【基于opencv3.4.1的Mobilenet_SSD深度学习模型的调用与目标识别】
目前,常见的目标检测算法,如Faster R-CNN,存在着速度慢的缺点。该论文提出的SSD方法,不仅提高了速度,而且提高了准确度。SSD:
该论文的核心思想:
本文中我们主要总结前人工作,通过opencv调用ssd生成模型,实现对图像或视频流中目标的识别。
其中mobile_net的模型文件与描述文件位于opencv安装路径的C:\opencv\opencv\sources\samples\data\dnn\...中。
主要代码如下:
#include<opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <iostream>
using namespace cv;
using namespace cv::dnn;
using namespace std;
int main() {
Net net = readNetFromCaffe("MobileNetSSD_deploy.prototxt", "MobileNetSSD_deploy.caffemodel");
const char* classNames[] = { "background", "aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair","cow", "diningtable", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor" };
float detect_thresh = 0.24;
VideoCapture cap("vtest.avi");
if (!cap.isOpened()) return -1;
while (true) {
Mat frame;
cap >> frame;
if (frame.empty()) break;
clock_t start_t = clock();
//预测
Mat inputblob = blobFromImage(frame, 1.0 / 127.5, Size(300, 300), Scalar(127.5, 127.5, 127.5), true, false);
net.setInput(inputblob, "data");
Mat detetmat = net.forward("detection_out");
cout << "Cost time: " << clock() - start_t << endl;
//绘制
Mat detectionMat(detetmat.size[2], detetmat.size[3], CV_32F, detetmat.ptr<float>());
float confidence_th = 0.2;
for (int i = 0; i < detectionMat.rows; i++) {
//int obj_class = detectionMat.at<float>(i, 1);
float confidence = detectionMat.at<float>(i, 2);
if (confidence > confidence_th) {
size_t objectClass = (size_t)(detectionMat.at<float>(i, 1));
int xLeftBottom = static_cast<int>(detectionMat.at<float>(i, 3) * frame.cols);
int yLeftBottom = static_cast<int>(detectionMat.at<float>(i, 4) * frame.rows);
int xRightTop = static_cast<int>(detectionMat.at<float>(i, 5) * frame.cols);
int yRightTop = static_cast<int>(detectionMat.at<float>(i, 6) * frame.rows);
Rect object((int)xLeftBottom, (int)yLeftBottom, (int)(xRightTop - xLeftBottom), (int)(yRightTop - yLeftBottom));
rectangle(frame, object, Scalar(0, 0, 255), 2);
putText(frame, classNames[objectClass], Point(xLeftBottom, yLeftBottom - 10), 3, 0.5, Scalar(0, 0, 255), 2);
}
}
imshow("test", frame);
waitKey(50);
}
return 0;
}
detectionMat输入图像后经过网络前向传播后的输出7*10的结果矩阵,其定义盗用别人一张图来说明前向运行输出的图像结果矩阵,prob层的输出:实际意义为测试图片所对应与标签的概率值。resize成一个列向量,然后排序,输出最大值和最大值所对应的位置。
上图中置信概率最高(0.999)的目标数组下标为2,对应的是bicycle自行车,只要大于设置的阈值(变量confidenceThreshold),就会在图像上标记出目标的位置(detectionMat行向量的3,4,5,6元素)。比如将阈值confidenceThreshold设置为0.5,则识别结果只有一个是大于0.5的,则只会在图像上标记出自行车,如下图:
参考博客:https://blog.****.net/KayChanGEEK/article/details/79978851
https://blog.****.net/samylee/article/details/80548323
https://blog.****.net/qq_15947787/article/details/78436995