----回顾之前-----
需要准备的东西:
- caffee 模型(已经训练好的官网):
网盘
password:dqvf - opencv 环境
主要的代码片段:
所需的头文件添加:
#include <opencv4/opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include<fstream>
#include <iostream>
开始读取模型:
其中 prototxt 为模型卷积层中的属性文档.可以打开看看
string model = "/home/sms/AI/pyopencv/ssd_caffe/MobileNetSSD_deploy.caffemodel";
string config = "/home/sms/AI/pyopencv/ssd_caffe/MobileNetSSD_deploy.prototxt";
//Net net = readNet(model,config,"caffe");
// 网络读取模型
Net net = readNetFromCaffe(config,model);
if (net.empty()) {
cout << "caffe date error" << endl;
return 0;
}else {
cout <<"finish" << endl;
}
设置 DNN 加载的模式(兴趣点) OpenCV 和 处理方式
net.setPreferableBackend(DNN_BACKEND_OPENCV);
net.setPreferableTarget(DNN_TARGET_CPU);
编写函数读取类的个数和种类:
vector<string> readLabel(string label_path_)
{
vector<string> className;
ifstream fp(label_path_);
string name;
while (!fp.eof())
{
getline(fp,name);
if (name.length())
{
className.push_back(name);
}
}
fp.close();
return className;
}
并且执行推理部分:
Mat result_img = net.forward("detection_out"); // 获取制定曾的输出(默认最后一层)
cout << "forwadimg:" << result_img.size[0] << " "<< result_img.size[1] << " " << result_img.size[2] << " "<< result_img.size[3] << endl;
Mat detetion(result_img.size[2],result_img.size[3],CV_32F,result_img.ptr<float>());
设置置信度的阈值和判断结果,并且打印到窗口上面:
因为读取的时候会检索自己的类文本,所有结果需要 index -1
float conf_threshod = 0.2;
for (int i = 0; i < detetion.rows; i++)
{
float confidents = detetion.at<float>(i,2);
if (conf_threshod < confidents) {
int index_ = detetion.at<float>(i,1);
float tl_x = detetion.at<float>(i,3) * src_img.cols;
float tl_y = detetion.at<float>(i,4) * src_img.rows;
float bt_x = detetion.at<float>(i,5) * src_img.cols;
float bt_y = detetion.at<float>(i,6) * src_img.rows;
Rect rect_ (tl_x, tl_y,(bt_x - tl_x),(bt_y - tl_y));
rectangle(src_img,rect_,Scalar(0,255,0),3,LINE_AA);
putText(src_img,format("conf:%f,class:%s",confidents,layname[index_-1].c_str()),rect_.tl(),FONT_HERSHEY_COMPLEX,0.7,Scalar(0,0,255),2,LINE_AA);
}
}
所有代码:
其中包含了视频读取和图像读取的部分,更改 USE_IMAGE 参数(1 图片读取,0 视频读取)即可得到不同的模式切换.
#include <opencv4/opencv2/opencv.hpp>
#include <opencv4/opencv2/dnn/dnn.hpp>
#include <opencv2/dnn.hpp>
#include<fstream>
#include <iostream>
using namespace std;
using namespace cv;
using namespace cv::dnn;
#ifndef USE_IAMGE
#define USE_IAMGE 0
#endif
vector<string> readLabel(string label_path_)
{
vector<string> className;
ifstream fp(label_path_);
string name;
while (!fp.eof())
{
getline(fp,name);
if (name.length())
{
className.push_back(name);
}
}
fp.close();
return className;
}
int main() {
// 加载模型
// string module_path = "./ssd_caffe/MobileNetSSD_deploy.caffemodel";
// string config_path = " ./ssd_caffe/MobileNetSSD_deploy.prototxt";
string model = "/home/sms/AI/pyopencv/ssd_caffe/MobileNetSSD_deploy.caffemodel";
string config = "/home/sms/AI/pyopencv/ssd_caffe/MobileNetSSD_deploy.prototxt";
//Net net = readNet(model,config,"caffe");
// 网络读取模型
Net net = readNetFromCaffe(config,model);
if (net.empty()) {
cout << "caffe date error" << endl;
return 0;
}else {
cout <<"finish" << endl;
}
net.setPreferableBackend(DNN_BACKEND_OPENCV);
net.setPreferableTarget(DNN_TARGET_CPU);
vector<string> lay_name = net.getLayerNames();
for (int i = 0; i < lay_name.size(); i++)
{
int id = net.getLayerId(lay_name[i]);
Ptr<Layer> layer = net.getLayer(id);
cout << "id = " << id << " " << "type:" << layer->type.c_str() << " " << "name:" << layer->name.c_str() << endl;
}
// 构建输入
#if USE_IAMGE == 0
VideoCapture capture("/home/sms/video/car.mp4");
#endif
while (true)
{
Mat src_img ;
// src_img = imread("/home/sms/tu/ball1.jpeg")
#if USE_IAMGE == 1
src_img = imread("/home/sms/tu/bycle.jpeg");
#else
capture >> src_img;
#endif
if (!src_img.empty())
{
Mat input_image = blobFromImage(src_img,0.0383, Size(300,300),Scalar(50,50,50),false,false);
net.setInput(input_image);
cout << "image input finish" << endl;
} else
{
return 0;
}
// 执行推理
Mat result_img = net.forward("detection_out"); // 获取制定曾的输出(默认最后一层)
cout << "forwadimg:" << result_img.size[0] << " "<< result_img.size[1] << " " << result_img.size[2] << " "<< result_img.size[3] << endl;
Mat detetion(result_img.size[2],result_img.size[3],CV_32F,result_img.ptr<float>());
vector<string> layname = readLabel("/home/sms/AI/pyopencv/ssd_caffe/object_detection_classes_pascal_voc.txt");
float conf_threshod = 0.2;
for (int i = 0; i < detetion.rows; i++)
{
float confidents = detetion.at<float>(i,2);
if (conf_threshod < confidents) {
int index_ = detetion.at<float>(i,1);
float tl_x = detetion.at<float>(i,3) * src_img.cols;
float tl_y = detetion.at<float>(i,4) * src_img.rows;
float bt_x = detetion.at<float>(i,5) * src_img.cols;
float bt_y = detetion.at<float>(i,6) * src_img.rows;
Rect rect_ (tl_x, tl_y,(bt_x - tl_x),(bt_y - tl_y));
rectangle(src_img,rect_,Scalar(0,255,0),3,LINE_AA);
putText(src_img,format("conf:%f,class:%s",confidents,layname[index_-1].c_str()),rect_.tl(),FONT_HERSHEY_COMPLEX,0.7,Scalar(0,0,255),2,LINE_AA);
}
}
imshow("src_out_img",src_img);
#if USE_IAMGE == 1
waitKey(0);
#else
waitKey(1);
#endif
}
return 0;
}
直接使用调整的参数不多:
需要调整的地方有:
输入进去的图片缩放因子-0.0383,值越小可是别的物体越多,准确率也会相对下降.
Mat input_image = blobFromImage(src_img,0.0383, Size(300,300),Scalar(50,50,50),false,false);
版权声明:本文为CSDN博主「splendid.rain生」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Msyusheng/article/details/122736066
暂无评论