Ascend训练营:yolov5目标检测代码C++版初探(310开发板运行)
一、交叉编译环境安装
以下都是在已经安装好CANN的情况下进行下一步的操作:
(CANN安装参考:Ascend训练营请参考CANN安装指南)
可以从https://gitee.com/ascend/samples下载华为昇腾的代码样例
下载好后,可参考cplus文件夹下的分设环境安装教程(编译环境为虚拟机,运行环境为昇腾310)samples-master/cplusplus/environment/separate_environmental_guidance_CN.md
其中安装opencv的库时,从开发板拷回so等库时,编译如果还是出现了找不到opencv相关库头文件的情况,可以修改src/cmakelist.txt中的include_directories选项,并将上述opencv的动态库和头文件分别拷贝到非usr/lib下的别的文件夹,像如下这样:
修改后,进入scripts文件夹输入:
开始编译,因为是交叉编译,实际代码运行位置为310板卡为arm板卡,因此编译也应该选择arm,如是x86环境也可以选择x86
编译完成后显示:
则为编译成功
二、代码初探
1.警告消除:
代码中有几个警告可以消除:
(1).
可以删除在main.c下的此变量!
(2).
这个警告是因为此版本的getsize函数有更新的V2版本,使用新的api即可
(3).
此警告是类型不同导致的,可以统一为int类型就可以了。
至此代码warning修改完成。
2.代码简单解析
main.c的主函数代码:
if((argc < 3) || (argv[1] == nullptr)){
ERROR_LOG("Please input: https://www.bilibili.com/read/cv/main <image_path>`<saveImg>`(0/1)");
return FAILED;
}
char image_names[5000][100];
string image_dir = string(argv[1]);
int fnum = readFileList(argv[1],image_names);
string image_path;
// string imgFormat = image_path.substr(image_path.size()-3,image_path.size());
// if ((imgFormat !="jpg") && (imgFormat !="png")){
// ERROR_LOG("Only support JPG or PNG img!!");
// return FAILED;
// }
string imgFormat = string("jpg");
ObjectDetect detect(modelPath,modelWidth,modelHeight);
aclError ret = detect.Init();
if (ret != ACL_SUCCESS) {
ERROR_LOG("Init resource failed %d", ret);
return FAILED;
}
struct timeval tstart,tend;
double timeuse;
gettimeofday(&tstart,NULL);
aclmdlDataset* inferenceOutput;
for(int i =0;i<fnum;i++)
{
// printf("run %d times ",i);
image_path = image_dir+image_names[i];
Image image;
image.imgFormat = imgFormat;
image.modelWidth = modelWidth;
image.modelHeight = modelHeight;
ret = detect.Preprocess(image_path, image);
if (ret != ACL_SUCCESS) {
ERROR_LOG("Preprocess failed %d", ret);
return FAILED;
}
ret = detect.Inference(inferenceOutput, image);
if (ret != ACL_SUCCESS) {
ERROR_LOG("Inference model inference output data failed");
return FAILED;
}
ret = detect.Postprocess(image, inferenceOutput, image_path);
if (ret != ACL_SUCCESS) {
ERROR_LOG("Process model inference output data failed");
return FAILED;
}
}
gettimeofday(&tend,NULL);
timeuse = *(tend.tv_sec - tstart.tv_sec) +
(tend.tv_usec - tstart.tv_usec);
INFO_LOG("whole time: %f ms",timeuse/1000);
detect.DestroyResource();
return SUCCESS;
从上述代码中可得出,该例程的设计分为
1. 初始化部分
2. 预处理部分
3. 推理部分
4. 后处理部分
1.初始化部分
具体操作流程为申请一段空间,然后调用 按照名称加载模型,并获取该加载模型的ID,其中模型的名称是由main.c下的命名空间里去指定的,这里我们可以做一下简单优化,如果我们有多个模型加载,参照昇腾的C++版本API手册,我们可知多模型加载只是需要反复调用加载函数即可,我们可以以.为界限提取om的名称,然后加载该模型,最终会获得一个模型ID,我们可以用容器或者结构体去存储这些信息,这样方便随时使用任意模型进行推理
参考华为文档准备信息
2.预处理部分
预处理部分的主要思想是运用dvpp部件的接口,高速的将相关格式的图片转换为YUV420SP格式的图片
这里使用的是JPG和PNG的图片,输出图像在 在此函数中设置为 模式,并且通过dvpp接口都回来jpg图片的大小按照需要resize成需要的大小
如果只是普通的灰度图怎么处理呢?
这里在实际应用中,可能我的图片就只是一张普通的灰度图(仅含Y分量),因此我们可以直接在Y分量的数据后面直接添加大小为Y分量图片大小的1/2的0x80填充UV分量,就不需要解码等操作了,可以直接用来推理
3.推理部分
参照应用手册中的流程,只需要准备好输入输出的数据结构,在调用 执行推理并获得结果即可
4.后处理部分
后处理部分主要是运用 将模型的结果读取出来并按照模型设定的内容获取并存储需要的信息
注意!!!!
所有申请的通道、设备一定要记得!销毁!!!!否则内存泄漏会造成严重的问题
ps:该文仅是为了记录CANN训练营的学习过程所用,不参与任何商业用途
到此这篇yolov3教程(yolov3map)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/do-yfwjc/20129.html