怎么理解std::vector<cv::Mat> inputs{matRGBScaled}
时间: 2024-01-21 19:03:48 浏览: 30
这段代码是使用C++中的标准库std::vector来创建一个向量(vector)对象,并初始化它的元素为一个cv::Mat对象。
具体地说,std::vector<cv::Mat> inputs表示创建了一个名为inputs的向量,其中的元素类型为cv::Mat,即OpenCV库中的图像矩阵类型。
初始化部分{matRGBScaled}表示向inputs中添加了一个元素,该元素的值为matRGBScaled。在这里,matRGBScaled是一个cv::Mat对象,可能是一个已经加载或创建的图像矩阵。
这样的初始化方式允许你在创建vector对象时直接指定初始元素,而不需要单独调用push_back()等函数添加元素。
需要注意的是,std::vector是一个动态数组,可以存储多个元素,并且具有自动调整大小的功能。因此,你可以在inputs中添加更多的cv::Mat对象,以便处理多个图像矩阵。
相关问题
怎么把这段c#转换为在c++中的dll函数实现,并在最后把float[] c返回给到c#,注意c++中的session和和c#的inferencesession不同 InferenceSession session = new InferenceSession(modelPath); Mat src_f = copy_from_mat(img); var wl = m_width * m_height; VectorOfMat temp = new VectorOfMat(); CvInvoke.Split(src_f, temp); float[] typedArr = new float[3 * m_width * m_height]; unsafe { fixed (float* target = typedArr) { for (int i = 0; i < temp.Size; i++) { var rawDataPointer = temp[i].DataPointer; Buffer.MemoryCopy((byte*)rawDataPointer, (byte*)target + (i * wl * sizeof(float)), wl * sizeof(float), wl * sizeof(float)); } } } var input = new DenseTensor<float>(typedArr, new[] { 1, 3, m_height, m_width }); var inputs = new List<NamedOnnxValue> { NamedOnnxValue.CreateFromTensor("images", input) }; var results = session.Run(inputs).ToArray(); //var ooo = results[0].AsTensor<float>(); float[] c = results[0].AsTensor<float>().ToArray();
你想要将上述C#代码转换为C++的DLL函数,以便在C#中使用。下面是一个可能的实现:
首先,你需要包含以下头文件:
```cpp
#include <vector>
#include <memory>
#include <string>
#include "onnxruntime_cxx_api.h"
#include "opencv2/opencv.hpp"
```
接下来,你可以编写一个函数,该函数将接收模型路径和OpenCV图像作为输入,并返回结果数组。请注意,为了将结果传递回C#,你需要使用指针并将其包装在一个结构体中。
```cpp
typedef struct {
float* data;
int size;
} FloatArray;
FloatArray run_inference(const char* model_path, cv::Mat img) {
// Load the model
Ort::SessionOptions session_options;
Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "onnx");
Ort::Session session(env, model_path, session_options);
// Convert the image to a float array
int m_width = img.cols;
int m_height = img.rows;
cv::Mat src_f;
img.convertTo(src_f, CV_32FC3);
std::vector<cv::Mat> temp;
cv::split(src_f, temp);
float* typedArr = new float[3 * m_width * m_height];
for (int i = 0; i < temp.size(); i++) {
std::memcpy(typedArr + (i * m_width * m_height), temp[i].data, m_width * m_height * sizeof(float));
}
// Create the input tensor
Ort::MemoryInfo memory_info = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault);
std::vector<int64_t> input_shape = { 1, 3, m_height, m_width };
Ort::Value input_tensor = Ort::Value::CreateTensor<float>(memory_info, typedArr, 3 * m_width * m_height, input_shape.data(), input_shape.size());
// Run the inference
const char* input_names[] = { "images" };
Ort::RunOptions run_options;
std::vector<Ort::Value> inputs = { input_tensor };
std::vector<const char*> output_names = { "output" };
std::vector<Ort::Value> output_tensors = session.Run(run_options, input_names, inputs.data(), inputs.size(), output_names.data(), output_names.size());
// Convert the output tensor to a float array
float* output_data = output_tensors[0].GetTensorMutableData<float>();
int output_size = output_tensors[0].GetTensorTypeAndShapeInfo().GetElementCount();
FloatArray result = { output_data, output_size };
// Clean up
delete[] typedArr;
return result;
}
```
最后,你需要将该函数导出到DLL。这可以通过以下方式完成:
```cpp
extern "C" __declspec(dllexport) FloatArray __cdecl run_inference(const char* model_path, cv::Mat img);
```
现在你可以在C#中调用此函数,并将结果转换为float数组。
c++ FaceNet 人脸识别 的程序
人脸识别技术在计算机视觉领域中是非常重要的一个分支,而FaceNet是一种非常流行的人脸识别算法。在C++中实现FaceNet人脸识别需要以下步骤:
1. 下载FaceNet模型
FaceNet模型是由Google开发的深度学习模型,可以通过TensorFlow Hub获取。可以使用以下代码下载模型:
```
#include <tensorflow/core/public/version.h>
#include <tensorflow/core/public/session.h>
#include <tensorflow/core/platform/env.h>
#include <tensorflow/core/graph/default_device.h>
#include <tensorflow/core/framework/tensor.h>
#include <tensorflow/core/framework/tensor_shape.h>
#include <tensorflow/core/framework/types.h>
#include <tensorflow/core/framework/graph.pb.h>
#include <tensorflow/cc/ops/standard_ops.h>
#include <tensorflow/cc/framework/ops.h>
#include <tensorflow/cc/saved_model/loader.h>
#include <iostream>
void downloadFacenetModel(std::string modelPath)
{
tensorflow::Session* session;
tensorflow::Status status = tensorflow::NewSession(tensorflow::SessionOptions(), &session);
if (!status.ok()) {
std::cout << status.ToString() << "\n";
return;
}
tensorflow::MetaGraphDef graph_def;
status = tensorflow::LoadSavedModel(tensorflow::SessionOptions(), tensorflow::RunOptions(), modelPath, {"serve"}, &graph_def);
if (!status.ok()) {
std::cout << status.ToString() << "\n";
return;
}
tensorflow::GraphDef graph;
graph.ToProto(graph_def.graph_def());
status = session->Create(graph_def.graph_def());
if (!status.ok()) {
std::cout << status.ToString() << "\n";
return;
}
std::cout << "Facenet model downloaded successfully!\n";
}
```
2. 加载图片
可以使用OpenCV库加载图片,以下是一个简单的加载图片的示例代码:
```
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
cv::Mat loadImage(std::string imagePath)
{
cv::Mat image = cv::imread(imagePath, cv::IMREAD_COLOR);
if (!image.data) {
std::cout << "Could not open or find the image!\n";
return cv::Mat();
}
cv::cvtColor(image, image, cv::COLOR_BGR2RGB);
return image;
}
```
3. 预处理图片
FaceNet需要输入固定大小的图片,而且需要进行归一化。以下是一个简单的预处理图片的示例代码:
```
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
cv::Mat preprocessImage(cv::Mat image, int image_size)
{
cv::Mat resized_image;
cv::resize(image, resized_image, cv::Size(image_size, image_size));
resized_image.convertTo(resized_image, CV_32FC3);
resized_image = (resized_image - 127.5) / 128.0;
return resized_image;
}
```
4. 运行FaceNet模型
以下是一个简单的运行FaceNet模型的示例代码:
```
#include <tensorflow/cc/ops/standard_ops.h>
#include <tensorflow/cc/framework/ops.h>
std::vector<float> runFacenetModel(cv::Mat image, tensorflow::Session* session, int image_size)
{
std::vector<tensorflow::Tensor> outputs;
tensorflow::Tensor input_tensor(tensorflow::DT_FLOAT, tensorflow::TensorShape({1, image_size, image_size, 3}));
float* tensor_data = input_tensor.flat<float>().data();
memcpy(tensor_data, image.data, image.total() * image.elemSize());
tensorflow::ops::Placeholder input_placeholder(tensorflow::ops::Placeholder::Shape({1, image_size, image_size, 3}));
tensorflow::ops::Identity identity("input", input_placeholder);
std::vector<std::pair<std::string, tensorflow::Tensor>> inputs = {{"input:0", input_tensor}};
tensorflow::Status status = session->Run(inputs, {"embeddings"}, {}, &outputs);
if (!status.ok()) {
std::cout << status.ToString() << "\n";
return std::vector<float>();
}
std::vector<float> embeddings;
float* embeddings_data = outputs[0].flat<float>().data();
for (int i = 0; i < outputs[0].shape().dim_size(1); i++) {
embeddings.push_back(embeddings_data[i]);
}
return embeddings;
}
```
完整的人脸识别程序需要将以上步骤结合起来,可以参考以下的示例代码:
```
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <tensorflow/core/public/version.h>
#include <tensorflow/core/public/session.h>
#include <tensorflow/core/platform/env.h>
#include <tensorflow/core/graph/default_device.h>
#include <tensorflow/core/framework/tensor.h>
#include <tensorflow/core/framework/tensor_shape.h>
#include <tensorflow/core/framework/types.h>
#include <tensorflow/core/framework/graph.pb.h>
#include <tensorflow/cc/ops/standard_ops.h>
#include <tensorflow/cc/framework/ops.h>
#include <tensorflow/cc/saved_model/loader.h>
#include <iostream>
void downloadFacenetModel(std::string modelPath)
{
tensorflow::Session* session;
tensorflow::Status status = tensorflow::NewSession(tensorflow::SessionOptions(), &session);
if (!status.ok()) {
std::cout << status.ToString() << "\n";
return;
}
tensorflow::MetaGraphDef graph_def;
status = tensorflow::LoadSavedModel(tensorflow::SessionOptions(), tensorflow::RunOptions(), modelPath, {"serve"}, &graph_def);
if (!status.ok()) {
std::cout << status.ToString() << "\n";
return;
}
tensorflow::GraphDef graph;
graph.ToProto(graph_def.graph_def());
status = session->Create(graph_def.graph_def());
if (!status.ok()) {
std::cout << status.ToString() << "\n";
return;
}
std::cout << "Facenet model downloaded successfully!\n";
}
cv::Mat loadImage(std::string imagePath)
{
cv::Mat image = cv::imread(imagePath, cv::IMREAD_COLOR);
if (!image.data) {
std::cout << "Could not open or find the image!\n";
return cv::Mat();
}
cv::cvtColor(image, image, cv::COLOR_BGR2RGB);
return image;
}
cv::Mat preprocessImage(cv::Mat image, int image_size)
{
cv::Mat resized_image;
cv::resize(image, resized_image, cv::Size(image_size, image_size));
resized_image.convertTo(resized_image, CV_32FC3);
resized_image = (resized_image - 127.5) / 128.0;
return resized_image;
}
std::vector<float> runFacenetModel(cv::Mat image, tensorflow::Session* session, int image_size)
{
std::vector<tensorflow::Tensor> outputs;
tensorflow::Tensor input_tensor(tensorflow::DT_FLOAT, tensorflow::TensorShape({1, image_size, image_size, 3}));
float* tensor_data = input_tensor.flat<float>().data();
memcpy(tensor_data, image.data, image.total() * image.elemSize());
tensorflow::ops::Placeholder input_placeholder(tensorflow::ops::Placeholder::Shape({1, image_size, image_size, 3}));
tensorflow::ops::Identity identity("input", input_placeholder);
std::vector<std::pair<std::string, tensorflow::Tensor>> inputs = {{"input:0", input_tensor}};
tensorflow::Status status = session->Run(inputs, {"embeddings"}, {}, &outputs);
if (!status.ok()) {
std::cout << status.ToString() << "\n";
return std::vector<float>();
}
std::vector<float> embeddings;
float* embeddings_data = outputs[0].flat<float>().data();
for (int i = 0; i < outputs[0].shape().dim_size(1); i++) {
embeddings.push_back(embeddings_data[i]);
}
return embeddings;
}
float calculateDistance(std::vector<float> embedding1, std::vector<float> embedding2)
{
float distance = 0;
for (int i = 0; i < embedding1.size(); i++) {
distance += pow((embedding1[i] - embedding2[i]), 2);
}
distance = sqrt(distance);
return distance;
}
int main()
{
std::string modelPath = "facenet_model";
downloadFacenetModel(modelPath);
tensorflow::Session* session;
tensorflow::Status status = tensorflow::NewSession(tensorflow::SessionOptions(), &session);
if (!status.ok()) {
std::cout << status.ToString() << "\n";
return 0;
}
tensorflow::MetaGraphDef graph_def;
status = tensorflow::LoadSavedModel(tensorflow::SessionOptions(), tensorflow::RunOptions(), modelPath, {"serve"}, &graph_def);
if (!status.ok()) {
std::cout << status.ToString() << "\n";
return 0;
}
tensorflow::GraphDef graph;
graph.ToProto(graph_def.graph_def());
status = session->Create(graph_def.graph_def());
if (!status.ok()) {
std::cout << status.ToString() << "\n";
return 0;
}
std::string image1Path = "image1.jpg";
std::string image2Path = "image2.jpg";
cv::Mat image1 = loadImage(image1Path);
cv::Mat image2 = loadImage(image2Path);
int image_size = 160;
cv::Mat resized_image1 = preprocessImage(image1, image_size);
cv::Mat resized_image2 = preprocessImage(image2, image_size);
std::vector<float> embedding1 = runFacenetModel(resized_image1, session, image_size);
std::vector<float> embedding2 = runFacenetModel(resized_image2, session, image_size);
float distance = calculateDistance(embedding1, embedding2);
std::cout << "Distance: " << distance << "\n";
return 0;
}
```
在运行这个程序之前,需要先下载FaceNet模型,并将模型保存到"facenet_model"目录下。完整的程序需要两张人脸图片作为输入,然后输出这两张人脸图片之间的距离。