OpenCV之YOLOv2-tiny目标检测( 二 )


预测的结果保存在的Mat类型矩阵中 。接下来就需要对这个预测结果进行后处理 。
四、解析输出
的输出包含:4个位置信息x、y、w、h,1个置信分数以及基于VOC数据集的20个目标类别 。注意这里的x,y是边框中心的坐标,所以要将目标边框绘制出来,需要根据这个四个参数推算出左顶点的坐标和高,宽 。
for (int i = 0; i < detectionMat.rows;i++){Mat scores = detectionMat.row(i).colRange(5, detectionMat.cols);Point classIdPoint;double confidence;minMaxLoc(scores, 0, &confidence, 0, &classIdPoint);int classid = classIdPoint.x;if (confidence > 0){printf("confide:%.2f\n", confidence);}if (confidence > confidenceThreshold){printf("confide2:%.2f\n", confidence);//x,y,w,h:中心坐标,边框w,hfloat x = detectionMat.at(i, 0) * image.cols;float y = detectionMat.at(i, 1) * image.rows;float width = detectionMat.at(i, 2) * image.cols;float height = detectionMat.at(i, 3) * image.rows;//左上角坐标int xLeftBottom = static_cast((x - width / 2));int yLeftBottom = static_cast((y - height / 2));//获取矩形框x,y,w,hRect object(xLeftBottom, yLeftBottom, static_cast(width), static_cast(height));//绘制矩形框rectangle(image, object, Scalar(0, 255, 0), 2);if (classid < classNames.size()){//获取类别名称及其置信度string conf = format("%.2f", confidence);String label = String(classNames[classid]) + ": " + conf;int baseLine = 0;//在图像上添加标签Size labelSize = getTextSize(label, FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);rectangle(image, Rect(Point(xLeftBottom, yLeftBottom), Size(labelSize.width, labelSize.height + baseLine)), Scalar(255, 255, 255), FILLED);putText(image, label, Point(xLeftBottom, yLeftBottom + labelSize.height), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 0));}}}
运行结果:
图片:
视频:
-tiny
源码:资源下载:
// yolov2-tiny.cpp : 此文件包含 "main" 函数 。程序执行将在此处开始并结束 。//#include #include #include #include #include #include #include #include using namespace std;using namespace cv;using namespace cv::dnn;//置信度阈值float confidenceThreshold = 0.25;//得到网络对应的标签vector getclasses(string classespath){ifstream ifs(classespath);//分类名vector classes;if (ifs.is_open()){string line;while (getline(ifs, line)){classes.push_back(line);}}return classes;}void detection(string config, string weights, string classespath, string video_path){//加载网络模型Net net = readNetFromDarknet(config, weights);if (net.empty()){printf("Could not load net...\n");return;}#if 0//cpu推理net.setPreferableBackend(DNN_BACKEND_OPENCV);net.setPreferableTarget(DNN_TARGET_CPU);#elif 1//使用cuda加速net.setPreferableBackend(cv::dnn::DNN_BACKEND_CUDA);net.setPreferableTarget(cv::dnn::DNN_TARGET_CUDA_FP16);#endif//获得分类名vector classNames = getclasses(classespath);//打开视频流VideoCapture capture;capture.open(video_path); //传入0:读取摄像头if (!capture.isOpened()){printf("could not open the video...\n");return;}//读取视频流Mat frame;while (capture.read(frame)){if (frame.channels() == 4){cvtColor(frame, frame, COLOR_BGRA2BGR);}//图像预处理Mat blob = blobFromImage(frame, 1 / 255.0, Size(416, 416), Scalar(), true, false);//设置输入net.setInput(blob,"data");//获得当前系统的计时间周期数,求FPSdouble t = (double)getTickCount();//推理预测Mat detectionMat = net.forward("detection_out");for (int i = 0; i < detectionMat.rows; i++){//获取每一行从第5列起的分类类别的概率const int probability_index = 5;//概率的总列数const int probability_size = detectionMat.cols - probability_index;//用于查找最大概率的类别float* prob_array_ptr = &detectionMat.at(i, probability_index);//查找概率数组中的最大值,并返回最大值的索引size_t objectClass = max_element(prob_array_ptr, prob_array_ptr + probability_size) - prob_array_ptr;//获取置信度值float confidence = detectionMat.at