2020年8月,有人推出了YOLO-Fastest,见https://github.com/dog-qiuqiu/Yolo-Fastest 。
在笔记本上,感觉速度和精度和YOLO_V3/V4_tiny差不多,可以达到实时(普通配置),但比着两者的30M+、20M+,YOLO-Fastest 的1.3M还是不错的。
用的opencv4.4,4.0以上的应该都可以。
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <opencv2/dnn.hpp>
#include <fstream>
#include <iostream>
#include <cstdlib>
#include <string>
#include <assert.h>
using namespace cv;
using namespace cv::dnn;
using namespace std;
int main(int argc, char** argv)
{
string _cfg = "D:/E/DL/Yolo-Fastest/Yolo-Fastest/COCO/yolo-fastest.cfg";
string _model = "D:/E/DL/Yolo-Fastest/Yolo-Fastest/COCO/yolo-fastest.weights";
string _labels = "D:/E/DL/Yolo-Fastest/data/coco.names";
Net net = readNetFromDarknet(_cfg, _model);
net.setPreferableBackend(DNN_BACKEND_CUDA);
net.setPreferableTarget(DNN_TARGET_CUDA);
vector<string>outputLayerName = net.getUnconnectedOutLayersNames();
for (int i = 0; i < outputLayerName.size(); i++)
{
cout << outputLayerName[i] << endl;
}
ifstream labels_file(_labels); //_labels labels_txt_file
if (!labels_file.is_open())
{
cout << "can't open labels file" << endl;
exit(-1);
}
string label;
vector<string>labels;
while (getline(labels_file, label))
{
labels.push_back(label);
}
VideoCapture capture;
capture.open(0, CAP_DSHOW); //capture.open("http://192.168.43.1:8081");
if (!capture.isOpened())
{
cout << "can't open camera" << endl;
exit(-1);
}
Mat frame;
while (capture.read(frame))
{
double start = getTickCount();
flip(frame, frame, 1);
Mat inputBlob = blobFromImage(frame, 1 / 255.F, Size(416, 416), Scalar(), true, false);
net.setInput(inputBlob);
vector<Mat> prob;
net.forward(prob, outputLayerName);
vector<Rect>boxes;
vector<int>classID;
vector<float>confidences;
for (int i = 0; i < prob.size(); i++)
{
for (int row = 0; row < prob[i].rows; row++)
{
Mat scores = prob[i].row(row).colRange(5, prob[i].cols);
double confidence;
Point maxloc;
minMaxLoc(scores, NULL, &confidence, NULL, &maxloc);
if (confidence > 0.5)
{
int center_x = prob[i].at<float>(row, 0) * frame.cols;
int center_y = prob[i].at<float>(row, 1) * frame.rows;
int width = prob[i].at<float>(row, 2) * frame.cols;
int height = prob[i].at<float>(row, 3) * frame.rows;
int x = center_x - width / 2;
int y = center_y - height / 2;
Rect box(x, y, width, height);
boxes.push_back(box);
classID.push_back(maxloc.x);
confidences.push_back(float(confidence));
}
}
}
vector<int>indices;
NMSBoxes(boxes, confidences, 0.5, 0.2, indices);
for (int i = 0; i < indices.size(); i++)
{
int index = indices[i];
Rect box = boxes[index];
string className = labels[classID[index]];
rectangle(frame, box, Scalar(0, 255, 0), 1, 8);
putText(frame, className, box.tl(), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 255), 1, 8);
}
double end = getTickCount();
double run_time = (end - start) / getTickFrequency();
double fps = 1 / run_time;
putText(frame, format("FPS: %0.2f", fps), Point(20, 20), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 255), 1, 8);
imshow("Yolo-Fastest", frame);
char ch = waitKey(1);
if (ch == 27)break;
}
}