深度学习目标识别之C语言调用

使用C语言对深度学习的模型进行调用,而可能是很多人目前需要的,因为使用C语言,更能满足日常开发需要,也更容易移植到到QT进行页面搭建。程序已经完成好久了,一直没有更新这个程序,但今天想使用这个程序时,提示调用DNN的一个函数未定义,绞尽脑汁,调试了整整一天,毫无结果,环境都重新配了一遍还是不行,最后终于还是解决了。
错误提示:
未定义标识符:DNN_BACKEND_OPENCV
问题所在环境问题
Opencv3.4.1无此函数
后面添加Opencv3.4.6之后,可以调用,相当于反反复复的配置了好几遍。
解决之后的我开心的不要不要的。
上图:
程序里改了一下,只检测人,用了yolov3-tiny,速度嗖嗖的哈哈。

在这里插入图片描述

具体的过程,我也是参考网上的大佬,放几个关键程序,带一些注释,以便帮助大家理解

首先是定义的变量名:

//用于存储coco类别名
vector<string> classes;
//低置信度移除
void postprocess(Mat& frame, const vector<Mat>& out);
//用于绘制预测框
void drawPred(int classId, float conf, int left, int top, int right, int bottom, Mat& frame);
//获得输出名
vector<String> getOutputsNames(const Net& net);
//用于存放相关数据的根目录 自行修改
string pro_dir = "C:\\Users\\14587\\source\\repos\\keras_yolos1\\keras_yolos1\\keras-yolo3-master\\"; //项目根目录

二是DNN网络加载,这里可以设置CPUorGPU:

//加载模型的配置和权重文件 自行修改路径
 String modelConfiguration = pro_dir + "yolov3-tiny.cfg";
 String modelWeights = pro_dir + "yolov3-tiny.weights";
 // 加载网络
 Net net = readNetFromDarknet(modelConfiguration, modelWeights);
 net.setPreferableBackend(DNN_BACKEND_OPENCV);
 //用gpu跑
 //DNN_TARGET_OPENCL 设置目标为GPU。
 //DNN_TARGET_CPU设置为cpu
 net.setPreferableTarget(DNN_TARGET_OPENCL);

这里是移除低置信度函数,并且只保留person这一索引

vector<int> indices;//保存没有重叠边框的索引
 NMSBoxes(boxes, confidences, confThreshold, nmsThreshold, indices);
 //用于抑制重叠边框
 for (size_t i = 0; i < indices.size(); ++i)
 { 
   int idx = indices[i];
   Rect box = boxes[idx]; 
   if (classIds[idx] != 0)
    continue;
   drawPred(classIds[idx], confidences[idx], box.x, box.y,
    box.x + box.width, box.y + box.height, frame);
 }

这里是获取索引名字:

//从输出层得到名字
vector<String> getOutputsNames(const Net& net)
{
 static vector<String> names;
 if (names.empty())
 {
  //取得输出层指标
  vector<int> outLayers = net.getUnconnectedOutLayers();
  vector<String> layersNames = net.getLayerNames();
  // 取得输出层名字
  names.resize(outLayers.size());
  for (size_t i = 0; i < outLayers.size(); ++i)
   names[i] = layersNames[outLayers[i] - 1];
 }
 return names;
}