0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

YOLOv8对象检测ONNXRUNTIME部署C++源码演示

OpenCV学堂 来源:英特尔物联网 2023-07-17 11:13 次阅读

ONNXRUNTIME1.13

ONNXRUNTIME是主流的深度学习部署框架之一,支持ONNX格式模型在CPUGPUARM等不同硬件平台上加速推理,支持C++PythonJavaC#、JS等不同语言SDK。C++版本安装包下载如下:

122ac47e-23a9-11ee-962d-dac502259ad0.png

不同版本的ONNXRUNTIME安装文件下载地址

 框架主页

推理流程与API接口

常用组件与推理流程支持:

12513b86-23a9-11ee-962d-dac502259ad0.png

Python SDK API支持:

1266c51e-23a9-11ee-962d-dac502259ad0.png

C++ SDK API支持:

1281eea2-23a9-11ee-962d-dac502259ad0.png

YOLOv8对象检测 + ONNXRUNTIME深度学习 C++源码如下:

#include
#include
#include

usingnamespacecv;
usingnamespacestd;

intmain(intargc,char**argv){
std::vectorlabels=readClassNames();
cv::Matframe=cv::imread("D:/python/my_yolov8_train_demo/zidane.jpg");
intih=frame.rows;
intiw=frame.cols;

//创建InferSession,查询支持硬件设备
//GPUMode,0-gpudeviceid
std::stringonnxpath="D:/python/my_yolov8_train_demo/yolov8n.onnx";
std::wstringmodelPath=std::wstring(onnxpath.begin(),onnxpath.end());
Ort::SessionOptionssession_options;
Ort::Envenv=Ort::Env(ORT_LOGGING_LEVEL_ERROR,"yolov8-onnx");

session_options.SetGraphOptimizationLevel(ORT_ENABLE_BASIC);
std::cout<< "onnxruntime inference try to use GPU Device" << std::endl;
    OrtSessionOptionsAppendExecutionProvider_CUDA(session_options, 0);
    Ort::Session session_(env, modelPath.c_str(), session_options);

    std::vectorinput_node_names;
std::vectoroutput_node_names;

size_tnumInputNodes=session_.GetInputCount();
size_tnumOutputNodes=session_.GetOutputCount();
Ort::AllocatorWithDefaultOptionsallocator;
input_node_names.reserve(numInputNodes);

//获取输入信息
intinput_w=0;
intinput_h=0;
for(inti=0;i< numInputNodes; i++) {
        auto input_name = session_.GetInputNameAllocated(i, allocator);
        input_node_names.push_back(input_name.get());
        Ort::TypeInfo input_type_info = session_.GetInputTypeInfo(i);
        auto input_tensor_info = input_type_info.GetTensorTypeAndShapeInfo();
        auto input_dims = input_tensor_info.GetShape();
        input_w = input_dims[3];
        input_h = input_dims[2];
        std::cout << "input format: NxCxHxW = " << input_dims[0] << "x" << input_dims[1] << "x" << input_dims[2] << "x" << input_dims[3] << std::endl;
    }

    // 获取输出信息
    int output_h = 0;
    int output_w = 0;
    Ort::TypeInfo output_type_info = session_.GetOutputTypeInfo(0);
    auto output_tensor_info = output_type_info.GetTensorTypeAndShapeInfo();
    auto output_dims = output_tensor_info.GetShape();
    output_h = output_dims[1]; // 84
    output_w = output_dims[2]; // 8400
    std::cout << "output format : HxW = " << output_dims[1] << "x" << output_dims[2] << std::endl;
    for (int i = 0; i < numOutputNodes; i++) {
        auto out_name = session_.GetOutputNameAllocated(i, allocator);
        output_node_names.push_back(out_name.get());
    }
    std::cout << "input: " << input_node_names[0] << " output: " << output_node_names[0] << std::endl;

    // format frame
    int64 start = cv::getTickCount();
    int w = frame.cols;
    int h = frame.rows;
    int _max = std::max(h, w);
    cv::Mat image = cv::Size(_max, _max), CV_8UC3);
    cv::Rect roi(0, 0, w, h);
    frame.copyTo(image(roi));

    // fix bug, boxes consistence!
    float x_factor = image.cols / static_cast(input_w);
floaty_factor=image.rows/static_cast(input_h);

cv::Matblob=cv::blobFromImage(image,1/255.0,cv::Size(input_w,input_h),cv::Scalar(0,0,0),true,false);
size_ttpixels=input_h*input_w*3;
std::arrayinput_shape_info{1,3,input_h,input_w};

//setinputdataandinference
autoallocator_info=Ort::CreateCpu(OrtDeviceAllocator,OrtMemTypeCPU);
Ort::Valueinput_tensor_=Ort::CreateTensor(allocator_info,blob.ptr(),tpixels,input_shape_info.data(),input_shape_info.size());
conststd::arrayinputNames={input_node_names[0].c_str()};
conststd::arrayoutNames={output_node_names[0].c_str()};
std::vectorort_outputs;
try{
ort_outputs=session_.Run(Ort::RunOptions{nullptr},inputNames.data(),&input_tensor_,1,outNames.data(),outNames.size());
}
catch(std::exceptione){
std::cout<< e.what() << std::endl;
    }

    // output data
    const float* pdata = ort_outputs[0].GetTensorMutableData();
cv::Matdout(output_h,output_w,CV_32F,(float*)pdata);
cv::Matdet_output=dout.t();//8400x84

//post-process
std::vectorboxes;
std::vectorclassIds;
std::vectorconfidences;

for(inti=0;i< det_output.rows; i++) {
        cv::Mat classes_scores = det_output.row(i).colRange(4, 84);
        cv::Point classIdPoint;
        double score;
        minMaxLoc(classes_scores, 0, &score, 0, &classIdPoint);

        // 置信度 0~1之间
        if (score >0.25)
{
floatcx=det_output.at(i,0);
floatcy=det_output.at(i,1);
floatow=det_output.at(i,2);
floatoh=det_output.at(i,3);
intx=static_cast((cx-0.5*ow)*x_factor);
inty=static_cast((cy-0.5*oh)*y_factor);
intwidth=static_cast(ow*x_factor);
intheight=static_cast(oh*y_factor);
cv::Rectbox;
box.x=x;
box.y=y;
box.width=width;
box.height=height;

boxes.push_back(box);
classIds.push_back(classIdPoint.x);
confidences.push_back(score);
}
}

//NMS
std::vectorindexes;
cv::NMSBoxes(boxes,confidences,0.25,0.45,indexes);
for(size_ti=0;i< indexes.size(); i++) {
        int index = indexes[i];
        int idx = classIds[index];
        cv::rectangle(frame, boxes[index], cv::Scalar(0, 0, 255), 2, 8);
        cv::rectangle(frame, cv::Point(boxes[index].tl().x, boxes[index].tl().y - 20),
            cv::Point(boxes[index].br().x, boxes[index].tl().y), cv::Scalar(0, 255, 255), -1);
        putText(frame, labels[idx], cv::Point(boxes[index].tl().x, boxes[index].tl().y), cv::FONT_HERSHEY_PLAIN, 2.0, cv::Scalar(255, 0, 0), 2, 8);
        cv::imshow("YOLOv8+ONNXRUNTIME 对象检测演示", frame);
    }

    // 计算FPS render it
    float t = (cv::getTickCount() - start) / static_cast(cv::getTickFrequency());
putText(frame,cv::format("FPS:%.2f",1.0/t),cv::Point(20,40),cv::FONT_HERSHEY_PLAIN,2.0,cv::Scalar(255,0,0),2,8);
cv::imshow("YOLOv8+ONNXRUNTIME对象检测演示",frame);
cv::waitKey(0);

session_options.release();
session_.release();
return0;
}

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • JAVA
    +关注

    关注

    19

    文章

    2904

    浏览量

    102994
  • 源码
    +关注

    关注

    8

    文章

    573

    浏览量

    28586
  • C++
    C++
    +关注

    关注

    21

    文章

    2066

    浏览量

    72900
  • python
    +关注

    关注

    51

    文章

    4675

    浏览量

    83467
  • 深度学习
    +关注

    关注

    73

    文章

    5237

    浏览量

    119910

原文标题:YOLOv8对象检测 + ONNXRUNTIME 部署 C++ 源码演示!

文章出处:【微信号:CVSCHOOL,微信公众号:OpenCV学堂】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    【爱芯派 Pro 开发板试用体验】yolov8模型转换

    尝试将最新的yolov8模型转换为爱芯派的模型。 环境准备 准备Docker环境 首先自己在任意机器上准备好docker环境,详细步骤见官网。 Docker 镜像文件 准备 yolo8 模型,并转
    发表于 11-20 12:19

    使用YOLOv8做目标检测和实例分割的演示

    YOLOv8是来自Ultralytics的最新的基于YOLO的对象检测模型系列,提供最先进的性能。
    的头像 发表于 02-06 10:11 5977次阅读

    TensorRT 8.6 C++开发环境配置与YOLOv8实例分割推理演示

    YOLOv8实例分割TensorRT 推理代码已经完成C++类封装,三行代码即可实现YOLOv8对象检测与实例分割模型推理,不需要改任何代
    的头像 发表于 04-25 10:49 3698次阅读
    TensorRT 8.6 <b class='flag-5'>C++</b>开发环境配置与<b class='flag-5'>YOLOv8</b>实例分割推理<b class='flag-5'>演示</b>

    在AI爱克斯开发板上用OpenVINO™加速YOLOv8分类模型

    本系列文章将在 AI 爱克斯开发板上使用 OpenVINO 开发套件依次部署并测评 YOLOv8 的分类模型、目标检测模型、实例分割模型和人体姿态估计模型。
    的头像 发表于 05-05 11:47 598次阅读
    在AI爱克斯开发板上用OpenVINO™加速<b class='flag-5'>YOLOv8</b>分类模型

    在AI爱克斯开发板上用OpenVINO™加速YOLOv8目标检测模型

    《在 AI 爱克斯开发板上用 OpenVINO 加速 YOLOv8 分类模型》介绍了在 AI 爱克斯开发板上使用 OpenVINO 开发套件部署并测评 YOLOv8 的分类模型,本文将介绍在 AI 爱克斯开发板上使用 OpenV
    的头像 发表于 05-12 09:08 845次阅读
    在AI爱克斯开发板上用OpenVINO™加速<b class='flag-5'>YOLOv8</b>目标<b class='flag-5'>检测</b>模型

    AI爱克斯开发板上使用OpenVINO加速YOLOv8目标检测模型

    《在AI爱克斯开发板上用OpenVINO加速YOLOv8分类模型》介绍了在AI爱克斯开发板上使用OpenVINO 开发套件部署并测评YOLOv8的分类模型,本文将介绍在AI爱克斯开发板上使用OpenVINO加速
    的头像 发表于 05-26 11:03 718次阅读
    AI爱克斯开发板上使用OpenVINO加速<b class='flag-5'>YOLOv8</b>目标<b class='flag-5'>检测</b>模型

    教你如何用两行代码搞定YOLOv8各种模型推理

    大家好,YOLOv8 框架本身提供的API函数是可以两行代码实现 YOLOv8 模型推理,这次我把这段代码封装成了一个类,只有40行代码左右,可以同时支持YOLOv8对象
    的头像 发表于 06-18 11:50 2078次阅读
    教你如何用两行代码搞定<b class='flag-5'>YOLOv8</b>各种模型推理

    三种主流模型部署框架YOLOv8推理演示

    部署。这里以YOLOv8为例,演示YOLOv8对象检测模型在OpenVINO、
    的头像 发表于 08-06 11:39 1839次阅读

    解锁YOLOv8修改+注意力模块训练与部署流程

    很多人也想跟修改YOLOv5源码一样的方式去修改YOLOv8源码,但是在github上面却发现找到的YOLOv8项目下面TAG分支是空的
    的头像 发表于 08-11 14:14 2670次阅读
    解锁<b class='flag-5'>YOLOv8</b>修改+注意力模块训练与<b class='flag-5'>部署</b>流程

    如何修改YOLOv8源码

    很多人也想跟修改YOLOv5源码一样的方式去修改YOLOv8源码,但是在github上面却发现找到的YOLOv8项目下面TAG分支是空的,
    的头像 发表于 09-04 10:02 1214次阅读
    如何修改<b class='flag-5'>YOLOv8</b>的<b class='flag-5'>源码</b>

    OpenCV4.8+YOLOv8对象检测C++推理演示

    自从YOLOv5更新成7.0版本,YOLOv8推出以后,OpenCV4.6以前的版本都无法再加载导出ONNX格式模型了,只有OpenCV4.7以上版本才可以支持最新版本YOLOv5与YOLOv
    的头像 发表于 09-27 11:07 701次阅读
    OpenCV4.8+<b class='flag-5'>YOLOv</b>8<b class='flag-5'>对象</b><b class='flag-5'>检测</b><b class='flag-5'>C++</b>推理<b class='flag-5'>演示</b>

    基于YOLOv8的自定义医学图像分割

    YOLOv8是一种令人惊叹的分割模型;它易于训练、测试和部署。在本教程中,我们将学习如何在自定义数据集上使用YOLOv8。但在此之前,我想告诉你为什么在存在其他优秀的分割模型时应该使用YOLO
    的头像 发表于 12-20 10:51 409次阅读
    基于<b class='flag-5'>YOLOv8</b>的自定义医学图像分割

    YOLOv8实现旋转对象检测

    YOLOv8框架在在支持分类、对象检测、实例分割、姿态评估的基础上更近一步,现已经支持旋转对象检测(OBB),基于DOTA数据集,支持航拍图
    的头像 发表于 01-11 10:43 569次阅读
    <b class='flag-5'>YOLOv8</b>实现旋转<b class='flag-5'>对象</b><b class='flag-5'>检测</b>

    OpenCV4.8 C++实现YOLOv8 OBB旋转对象检测

    YOLOv8框架在在支持分类、对象检测、实例分割、姿态评估的基础上更近一步,现已经支持旋转对象检测(OBB),基于DOTA数据集,支持航拍图
    的头像 发表于 02-22 10:15 410次阅读
    OpenCV4.8 <b class='flag-5'>C++</b>实现<b class='flag-5'>YOLOv8</b> OBB旋转<b class='flag-5'>对象</b><b class='flag-5'>检测</b>

    基于OpenCV DNN实现YOLOv8的模型部署与推理演示

    基于OpenCV DNN实现YOLOv8推理的好处就是一套代码就可以部署在Windows10系统、乌班图系统、Jetson的Jetpack系统
    的头像 发表于 03-01 15:52 441次阅读
    基于OpenCV DNN实现<b class='flag-5'>YOLOv8</b>的模型<b class='flag-5'>部署</b>与推理<b class='flag-5'>演示</b>