Yolov5 ONNX Runtime 的 C++部署

一、onnxruntime C++的下载

不要相信某些博客,2022年居然还是写的:

我才疏学浅,试过好几次都没有成功。

不要克隆不要克隆,那么大的项目你克隆到啥时候,人家发布了压缩包版本的好不好。

 点击latest:

 看见没有,gpu版本的才几十M!!!!!

如果自己下载源码编译,很大可能会失败。用官方给的include、lib是很香的哦。

二、部署

一个大佬的项目:GitHub - iwanggp/yolov5_onnxruntime_deploy: 使用onnxruntime部署yolov5

这里就不贴代码了,写一写整体的流程:

1、输入图像预处理:

  • BRG2RBG
  • 信封处理(等比例缩放加padding),得到模型输入制定尺寸大小的图像
  • 像素0~255 ----> 0~1
  • HWC --->  CHW

2、onnxruntime推理得到输出

3、对输出进行后处理,每次都是一张图像的输出

  • box的置信度与置信度阈值作比较,通过后获得该图像的所有box的类别、类别概率、位置信息[xmin, ymin, width, height] ;   在yolov5中类别概率=类别概率*置信度
  • NMS处理,消除同类别重叠度大于iou阈值、类别概率小于置信度阈值的box
  • box位置信息映射到输入原图上

4、在输入原图上进行画预测框、打印类别名称和类别概率

三、总结

1、运行总结:

如果你把onnx格式模型路径、类别文件路径、图像路径写对后,可能还是跑不起来,代码中需要修改一下

如果运行出现下面这样的报错:

 那就直接把模型输入输出的名字写进去:

2、运行速度

我这次用的是yolov5-6.2版本的yolov5n模型,在C++上用onnxtime部署,用视频大概检测其推理速度,发现onnxruntime比opencv dnn快一些。不过还是没有pytorch python快。

3、项目通用性

另外如果你用的是其他模型,要套这个项目的话,你得知道输出信息,然后进行修改。比如你现在的类别是coco,yolov5的输出是【batch,  box_num, 85】。这里的85是【Xcenter, Ycenter, width, height, 置信度,类别1概率,类别2概率.......类别80概率】。

yolov5NMS处理时候,一个是box重叠度 < iou阈值,另一个是需要是   box的类别该概率*box的置信度   >  置信度阈值

欢迎留言、欢迎交流!!!

参考:

yolov5 onnxruntime部署_Kun Li的博客-优快云博客

C/C++下的ONNXRUNTIME推理 - 知乎
onnxruntime的c++使用_c++ onnxruntime_chencision的博客-优快云博客

### 使用 ONNX Runtime 实现图片分类 #### 准备工作 为了实现图像分类,需确保开发环境中已安装必要的依赖项。这包括 `opencv` 和 `onnxruntime-gpu` 或者带有 TensorRT 支持的版本[^1]。 #### 设置项目属性 配置 Visual Studio 项目的属性来包含 ONNX Runtime 和 OpenCV 的路径设置非常重要。具体操作如下: - 将 ONNX Runtime 和 OpenCV 头文件所在的目录添加至项目的包含目录; - 把 ONNX Runtime 和 OpenCV 库文件所在位置指定给库目录; - 在链接器输入中增加相应的 .lib 文件名称; - 对于动态链接库 (.dll),应将其放置在可执行程序能够访问的位置,通常是在应用程序的工作目录下即 Release 文件夹内[^2]。 #### 图像预处理 利用 OpenCV 来读取并调整待预测图片大小以匹配训练时所使用的尺寸规格。对于 EfficientNet V2 模型而言,默认情况下可能期望特定分辨率下的 RGB 彩色图作为输入数据形式。 ```cpp #include <opencv2/opencv.hpp> cv::Mat preprocessImage(const std::string& imagePath, int inputHeight, int inputWidth){ cv::Mat img = cv::imread(imagePath); // Resize image to match model's expected dimensions. cv::resize(img, img, cv::Size(inputWidth, inputHeight)); // Convert the color space from BGR (default in OpenCV) to RGB. cv::cvtColor(img, img, cv::COLOR_BGR2RGB); return img; } ``` #### 创建会话与加载模型 通过调用 ONNX Runtime 提供的接口创建一个新的推理会话实例,并加载预先转换好的 `.onnx` 格式的深度学习模型文件。 ```cpp Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "test"); Ort::SessionOptions session_options; // Enable GPU provider with CUDA or TensorRT backend support based on installation. session_options.AppendExecutionProvider_CUDA(0); std::vector<const char*> model_paths{"path/to/AlexNet.onnx"}; Ort::Session session(env, model_paths.data(), session_options); ``` #### 构建输入张量 根据目标框架的要求构建合适的输入张量格式,这里假设采用 NCHW 布局(批量数×通道数×高度×宽度),并将像素值归一化到 [-1,+1] 范围之间。 ```cpp float* inputDataPtr = new float[inputHeight * inputWidth * channels]; for(int i=0; i<inputHeight;i++){ for(int j=0;j<inputWidth;j++){ inputDataPtr[(i*inputWidth+j)*channels]=((float)(img.at<cv::Vec3b>(i,j)[0])/255.-meanB)/stdB; inputDataPtr[(i*inputWidth+j)*channels+1]=((float)(img.at<cv::Vec3b>(i,j)[1])/255.-meanG)/stdG; inputDataPtr[(i*inputWidth+j)*channels+2]=((float)(img.at<cv::Vec3b>(i,j)[2])/255.-meanR)/stdR; } } Ort::MemoryInfo memory_info = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault); Ort::Value tensor_input = Ort::Value::CreateTensor<float>( memory_info, inputDataPtr, batch_size * channels * inputHeight * inputWidth, tensor_shape.data(), tensor_shape.size()); ``` #### 执行推理过程 准备好所有必要参数之后就可以调用 Run 方法来进行实际推断计算了。注意要传递正确的输入节点名字列表以及对应的张量对象数组进去。 ```cpp auto output_tensors = session.Run( Ort::RunOptions{nullptr}, input_node_names.data(), &tensor_input, num_inputs, output_node_names.data(), num_outputs); ``` #### 解析输出结果 最后一步是从返回的结果集中提取类别概率分布向量,并找出最大可能性对应的那个标签索引号作为最终识别出来的物体种类标识符。 ```cpp const float* probabilities = output_tensors.front().GetTensorMutableData<float>(); int maxIndex = std::max_element(probabilities,probabilities+num_classes)-probabilities; std::cout << "Predicted class index is : "<< maxIndex<<'\n'; delete[] inputDataPtr; ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值