当前位置:   article > 正文

Ubuntu环境下C++使用onnxruntime和Opencv进行YOLOv8模型部署_ubuntu 安装onnx c++

ubuntu 安装onnx c++

目录

环境配置

系统环境

项目文件路径 

文件环境

 config.txt

 CMakeLists.txt

type.names

 读取config.txt配置文件

修改图片尺寸格式

读取缺陷标志文件

生成缺陷随机颜色标识

模型推理

推理结果获取

缺陷信息还原并显示

总代码


环境配置

系统环境

Ubuntu18.04

onnxruntime-linux-x64 1.12.1:https://github.com/microsoft/onnxruntime/releases

opencv 3.4.3

cmake 3.10.2

项目文件路径 

1.  bin:存放可执行程序和识别结果
2.  data:存放数据集
3.  src:存放源程序
4.  include:存放头文件
5.  config.txt:配置文件,内容分别是模型相对路径、图片相对路径、缺陷标识文件相对路径、缺陷识别阈值、缺陷重叠阈值
6.  type.names:缺陷标识文件,内容和模型识别的缺陷标识顺序需要一致

文件环境

 config.txt

分别表示模型相对路径、图片相对路径、缺陷标识文件相对路径、缺陷识别阈值、缺陷重叠阈值

../models/best.onnx
../data/2.bmp
../type.names
0.4
0.4

 CMakeLists.txt

需要更改的地方已经在里面标注好了

  1. # 项目名称,随便写
  2. PROJECT(image_onnx)
  3. # cmake版本,根据自己的写
  4. cmake_minimum_required(VERSION 3.10)
  5. # 编译好的可执行文件放置的位置
  6. set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${image_onnx_SOURCE_DIR}/bin)
  7. # find required opencv
  8. find_package(OpenCV REQUIRED)
  9. # directory of opencv headers
  10. include_directories(${OpenCV_INCLUDE_DIRS})
  11. # 根据自己的onnxruntime存放路径编写
  12. set(ONNXRUNTIME_ROOT_PATH /home/ebaina/onnxruntime-linux-x64-1.12.1/)
  13. set(ONNXRUNTIME_INCLUDE_DIRS ${ONNXRUNTIME_ROOT_PATH}/include/)
  14. set(ONNXRUNTIME_LIB ${ONNXRUNTIME_ROOT_PATH}lib/libonnxruntime.so)
  15. # 需要编译的cpp文件所在路径,前面是编译好的可执行文件名
  16. add_executable(image_onnx src/main_image.cpp
  17. src/change_image.cpp
  18. src/adjust_result.cpp)
  19. # directory of opencv library
  20. link_directories(${OpenCV_LIBRARY_DIRS})
  21. # opencv libraries
  22. target_link_libraries(image_onnx ${OpenCV_LIBS})
  23. include_directories(${ONNXRUNTIME_INCLUDE_DIRS})
  24. target_link_libraries(image_onnx ${ONNXRUNTIME_LIB})
  25. # include
  26. target_include_directories(image_onnx
  27. PRIVATE
  28. ${PROJECT_SOURCE_DIR}/include
  29. )

type.names

缺陷标志文件,内容和模型识别的缺陷标识顺序需要一致,模型识别网站:Netron

burr
cbreakage
inbreakage
bpulp
corrode

 读取config.txt配置文件

  1. // 自动读取模型路径,图片路径,缺陷阈值,重叠阈值
  2. std::string model_path_;
  3. std::string imgPath;
  4. std::string namesPath;
  5. float threshold;
  6. float nms_threshold;
  7. // 打开配置文件并读取配置
  8. std::ifstream configFile("../config.txt");
  9. if (configFile.is_open()) {
  10. configFile >> model_path_ >> imgPath >> namesPath >> threshold >> nms_threshold;
  11. configFile.close();
  12. std::cout << "Model Path: " << model_path_ << std::endl;
  13. std::cout << "Image Path: " << imgPath << std::endl;
  14. std::cout << "Names Path: " << namesPath << std::endl;
  15. std::cout << "Threshold: " << threshold << std::endl;
  16. std::cout << "NMS Threshold: " << nms_threshold << std::endl;
  17. } else
  18. std::cerr << "Failed to open config file." << std::endl;
  19. const char* model_path = model_path_.c_str();

修改图片尺寸格式

  1. // 图片变换
  2. cv::Mat inputImage = cv::imread(imgPath);
  3. if (inputImage.empty()) {
  4. std::cerr << "Failed to load image." << std::endl;
  5. return 1;
  6. }
  7. // 获取图片尺寸
  8. int y = inputImage.rows;
  9. int x = inputImage.cols;
  10. // 图片尺寸变换
  11. cv::Mat image0 = resizeImage(inputImage, y, x);
  12. // 图像归一化
  13. std::vector<float> input_image_ = nchwImage(image0);

读取缺陷标志文件

  1. // 读取缺陷标志文件
  2. std::ifstream inputFile(namesPath);
  3. if (!inputFile.is_open()) {
  4. std::cerr << "Failed to open the file." << std::endl;
  5. return 1;
  6. }
  7. std::vector<std::string> typeNames;
  8. std::string line;
  9. while (std::getline(inputFile, line))
  10. typeNames.push_back(line);
  11. inputFile.close();

生成缺陷随机颜色标识

  1. // 缺陷颜色标识随机
  2. int numColors = typeNames.size();
  3. std::vector<std::vector<int>> colors;
  4. for (int i = 0; i < numColors; ++i)
  5. colors.push_back(generateRandomColor());
  6. // // 打印颜色种类
  7. // for (const auto &color : colors)
  8. // std::cout << "R: " << color[0] << ", G: " << color[1] << ", B: " << color[2] << std::endl;

模型推理

  1. // 模型设置和推理结果
  2. Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "Default");
  3. // CPU
  4. Ort::Session session_{env, model_path, Ort::SessionOptions{nullptr}};
  5. // 模型输入尺寸
  6. static constexpr const int height_ = 640; //model input height
  7. static constexpr const int width_ = 640; //model input width
  8. Ort::Value input_tensor_{nullptr};
  9. std::array<int64_t, 4> input_shape_{1, 3, height_, width_}; //mode input shape NCHW = 1x3xHxW
  10. // 模型输出尺寸
  11. Ort::Value output_tensor_{nullptr};
  12. std::array<int64_t, 3> output_shape_{1, 9, 8400}; //model output shape,
  13. std::array<_Float32, 9*8400> results_{};
  14. // 模型输入输出张量设置
  15. auto memory_info = Ort::MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeDefault);
  16. input_tensor_ = Ort::Value::CreateTensor<float>(memory_info, input_image_.data(), input_image_.size(), input_shape_.data(), input_shape_.size());
  17. output_tensor_ = Ort::Value::CreateTensor<float>(memory_info, results_.data(), results_.size(), output_shape_.data(), output_shape_.size());
  18. // 查看模型输入输出的名称
  19. const char* input_names[] = {"images"};
  20. const char* output_names[] = {"output0"};
  21. // 推理
  22. session_.Run(Ort::RunOptions{nullptr}, input_names, &input_tensor_, 1, output_names, &output_tensor_, 1);
  23. float* out = output_tensor_.GetTensorMutableData<float>();

推理结果获取

  1. // 推理结果获取
  2. int rows = 9; // 第二维度大小,即行数
  3. int cols = 8400; // 第三维度大小,即列数
  4. std::vector<std::vector<float>> matrix(rows, std::vector<float>(cols));
  5. for (int row = 0; row < rows; ++row)
  6. for (int col = 0; col < cols; ++col)
  7. matrix[row][col] = out[row * cols + col];
  8. // 9,8400数组转置为8400,9
  9. std::vector<std::vector<float>> tran_matrix = transpose(matrix);
  10. // // 显示缺陷筛选结果
  11. // std::vector<std::vector<float>> num = tran_matrix;
  12. // for (size_t n = 0; n < num.size(); ++n) {
  13. // bool aboveThreshold = false;
  14. // for (size_t col = 4; col <= 8; ++col)
  15. // if (num[n][col] > threshold) {
  16. // aboveThreshold = true;
  17. // break;
  18. // }
  19. // if (aboveThreshold) {
  20. // std::cout << "Row " << n << ": ";
  21. // for (const auto& val : num[n])
  22. // std::cout << val << " ";
  23. // std::cout << std::endl;
  24. // }
  25. // }

缺陷信息还原并显示

  1. // 缺陷还原
  2. std::vector<std::vector<double>> select_matrix;
  3. select_matrix = select(tran_matrix, threshold, cols,rows);
  4. // 缺陷位置信息还原
  5. select_matrix = return_(select_matrix, y, x);
  6. // 缺陷位置信息筛选
  7. select_matrix = nms_(select_matrix, nms_threshold);
  8. // // 打印数组的内容
  9. // for (const auto& row : select_matrix){
  10. // for (const auto& value : row) {
  11. // std::cout << value << " ";
  12. // }
  13. // std::cout << std::endl;
  14. // }
  15. // 绘制识别框
  16. cv::Mat outputImage = draw_image(select_matrix, inputImage, typeNames, colors);
  17. // 自定义窗口大小
  18. int windowWidth = 1200;
  19. int windowHeight = 900;
  20. // 调整窗口大小
  21. cv::namedWindow("Image with Bounding Boxes", cv::WINDOW_NORMAL);
  22. cv::resizeWindow("Image with Bounding Boxes", windowWidth, windowHeight);
  23. cv::imshow("Image with Bounding Boxes", outputImage);
  24. cv::imwrite("marked_image.jpg", outputImage);
  25. cv::waitKey(0);

main代码(关注取源码!)

  1. #include <assert.h>
  2. #include <random>
  3. #include <onnxruntime_cxx_api.h>
  4. #include "cpu_provider_factory.h"
  5. #include <adjust_result.h>
  6. // 随机生成颜色
  7. std::vector<int> generateRandomColor() {
  8. std::random_device rd;
  9. std::mt19937 gen(rd());
  10. std::uniform_real_distribution<double> dis(0.0, 1.0);
  11. std::vector<int> color(3);
  12. for (int i = 0; i < 3; ++i) {
  13. color[i] = static_cast<int>(dis(gen) * 255);
  14. }
  15. return color;
  16. }
  17. int main(int argc, char* argv[]) {
  18. // // 模型路径,图片路径,缺陷阈值,重叠阈值
  19. // const char* model_path = "../models/best.onnx";
  20. // std::string imgPath = "../data/3.bmp";
  21. // std::string namesPath = "../type.names";
  22. // float threshold = 0.4;
  23. // float nms_threshold = 0.4;
  24. // 自动读取模型路径,图片路径,缺陷阈值,重叠阈值
  25. std::string model_path_;
  26. std::string imgPath;
  27. std::string namesPath;
  28. float threshold;
  29. float nms_threshold;
  30. // 打开配置文件并读取配置
  31. std::ifstream configFile("../config.txt");
  32. if (configFile.is_open()) {
  33. configFile >> model_path_ >> imgPath >> namesPath >> threshold >> nms_threshold;
  34. configFile.close();
  35. std::cout << "Model Path: " << model_path_ << std::endl;
  36. std::cout << "Image Path: " << imgPath << std::endl;
  37. std::cout << "Names Path: " << namesPath << std::endl;
  38. std::cout << "Threshold: " << threshold << std::endl;
  39. std::cout << "NMS Threshold: " << nms_threshold << std::endl;
  40. } else
  41. std::cerr << "Failed to open config file." << std::endl;
  42. const char* model_path = model_path_.c_str();
  43. // 图片变换
  44. cv::Mat inputImage = cv::imread(imgPath);
  45. if (inputImage.empty()) {
  46. std::cerr << "Failed to load image." << std::endl;
  47. return 1;
  48. }
  49. // 获取图片尺寸
  50. int y = inputImage.rows;
  51. int x = inputImage.cols;
  52. // 图片尺寸变换
  53. cv::Mat image0 = resizeImage(inputImage, y, x);
  54. // 图像归一化
  55. std::vector<float> input_image_ = nchwImage(image0);
  56. // 读取缺陷标志文件
  57. std::ifstream inputFile(namesPath);
  58. if (!inputFile.is_open()) {
  59. std::cerr << "Failed to open the file." << std::endl;
  60. return 1;
  61. }
  62. std::vector<std::string> typeNames;
  63. std::string line;
  64. while (std::getline(inputFile, line))
  65. typeNames.push_back(line);
  66. inputFile.close();
  67. // // 打印缺陷标志文件内容
  68. // std::cout << "Number of elements: " << typeNames.size() << std::endl;
  69. // for (const std::string &typeName : typeNames)
  70. // std::cout << typeName << std::endl;
  71. // 缺陷颜色标识随机
  72. int numColors = typeNames.size();
  73. std::vector<std::vector<int>> colors;
  74. for (int i = 0; i < numColors; ++i)
  75. colors.push_back(generateRandomColor());
  76. // // 打印颜色种类
  77. // for (const auto &color : colors)
  78. // std::cout << "R: " << color[0] << ", G: " << color[1] << ", B: " << color[2] << std::endl;
  79. // 模型设置和推理结果
  80. Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "Default");
  81. // CPU
  82. Ort::Session session_{env, model_path, Ort::SessionOptions{nullptr}};
  83. // 模型输入尺寸
  84. static constexpr const int height_ = 640; //model input height
  85. static constexpr const int width_ = 640; //model input width
  86. Ort::Value input_tensor_{nullptr};
  87. std::array<int64_t, 4> input_shape_{1, 3, height_, width_}; //mode input shape NCHW = 1x3xHxW
  88. // 模型输出尺寸
  89. Ort::Value output_tensor_{nullptr};
  90. std::array<int64_t, 3> output_shape_{1, 9, 8400}; //model output shape,
  91. std::array<_Float32, 9*8400> results_{};
  92. // 模型输入输出张量设置
  93. auto memory_info = Ort::MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeDefault);
  94. input_tensor_ = Ort::Value::CreateTensor<float>(memory_info, input_image_.data(), input_image_.size(), input_shape_.data(), input_shape_.size());
  95. output_tensor_ = Ort::Value::CreateTensor<float>(memory_info, results_.data(), results_.size(), output_shape_.data(), output_shape_.size());
  96. // 查看模型输入输出的名称
  97. const char* input_names[] = {"images"};
  98. const char* output_names[] = {"output0"};
  99. // 推理
  100. session_.Run(Ort::RunOptions{nullptr}, input_names, &input_tensor_, 1, output_names, &output_tensor_, 1);
  101. float* out = output_tensor_.GetTensorMutableData<float>();
  102. // 推理结果获取
  103. int rows = 9; // 第二维度大小,即行数
  104. int cols = 8400; // 第三维度大小,即列数
  105. std::vector<std::vector<float>> matrix(rows, std::vector<float>(cols));
  106. for (int row = 0; row < rows; ++row)
  107. for (int col = 0; col < cols; ++col)
  108. matrix[row][col] = out[row * cols + col];
  109. // 9,8400数组转置为8400,9
  110. std::vector<std::vector<float>> tran_matrix = transpose(matrix);
  111. // // 显示缺陷筛选结果
  112. // std::vector<std::vector<float>> num = tran_matrix;
  113. // for (size_t n = 0; n < num.size(); ++n) {
  114. // bool aboveThreshold = false;
  115. // for (size_t col = 4; col <= 8; ++col)
  116. // if (num[n][col] > threshold) {
  117. // aboveThreshold = true;
  118. // break;
  119. // }
  120. // if (aboveThreshold) {
  121. // std::cout << "Row " << n << ": ";
  122. // for (const auto& val : num[n])
  123. // std::cout << val << " ";
  124. // std::cout << std::endl;
  125. // }
  126. // }
  127. // 缺陷还原
  128. std::vector<std::vector<double>> select_matrix;
  129. select_matrix = select(tran_matrix, threshold, cols,rows);
  130. // 缺陷位置信息还原
  131. select_matrix = return_(select_matrix, y, x);
  132. // 缺陷位置信息筛选
  133. select_matrix = nms_(select_matrix, nms_threshold);
  134. // // 打印数组的内容
  135. // for (const auto& row : select_matrix){
  136. // for (const auto& value : row) {
  137. // std::cout << value << " ";
  138. // }
  139. // std::cout << std::endl;
  140. // }
  141. // 绘制识别框
  142. cv::Mat outputImage = draw_image(select_matrix, inputImage, typeNames, colors);
  143. // 自定义窗口大小
  144. int windowWidth = 1200;
  145. int windowHeight = 900;
  146. // 调整窗口大小
  147. cv::namedWindow("Image with Bounding Boxes", cv::WINDOW_NORMAL);
  148. cv::resizeWindow("Image with Bounding Boxes", windowWidth, windowHeight);
  149. cv::imshow("Image with Bounding Boxes", outputImage);
  150. cv::imwrite("marked_image.jpg", outputImage);
  151. cv::waitKey(0);
  152. return 0;
  153. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/583801
推荐阅读
相关标签
  

闽ICP备14008679号