Opencv C++ implementa YOLOv3v4

1. Razonamiento sobre el código fuente de C++

0.Enlace del código fuente

https://learnopencv.com/deep-learning-based-object-detection-using-yolov3-with-opencv-python-c/

1.Parámetros de inicialización

//初始化参数
float confThreshold = 0.5; // 置信度阈值
float nmsThreshold = 0.4;  // 非极大值抑制阈值
int inpWidth = 416;        //网络输入尺寸宽度
int inpHeight = 416;       //网络输入尺寸高度

2. Cargar etiquetas de modelo y categoría.

//加载类别名称
string classesFile = "coco.names";
ifstream ifs(classesFile.c_str());
string line;
while (getline(ifs, line)) classes.push_back(line);

//给模型喂养配置文件与权重文件
String modelConfiguration = "yolov3.cfg";
String modelWeights = "yolov3.weights";

//加载网络模型
Net net = readNetFromDarknet(modelConfiguration, modelWeights);
net.setPreferableBackend(DNN_BACKEND_OPENCV);
net.setPreferableTarget(DNN_TARGET_CPU);

3. Lea la imagen de entrada

outputFile = "yolo_out_cpp.avi";
if (parser.has("image"))
    {
        //打开图片文件
        str = parser.get<String>("image");
        ifstream ifile(str);
        if (!ifile) throw("error");
        cap.open(str);
        str.replace(str.end()-4, str.end(), "_yolo_out_cpp.jpg");
        outputFile = str;
    }
    else if (parser.has("video"))
    {
        //打开视频文件
        str = parser.get<String>("video");
        ifstream ifile(str);
        if (!ifile) throw("error");
        cap.open(str);
        str.replace(str.end()-4, str.end(), "_yolo_out_cpp.avi");
        outputFile = str;
    }
    //打开网络摄像机
    else cap.open(parser.get<int>("device"));

    catch(...) {
        cout << "Could not open the input image/video stream" << endl;
        return 0;
    }
    
    //初始化视频存储器,存储输出视频
    if (!parser.has("image")) {
        video.open(outputFile, VideoWriter::fourcc('M','J','P','G'), 28, Size(cap.get(CAP_PROP_FRAME_WIDTH), cap.get(CAP_PROP_FRAME_HEIGHT)));
    }

4. Procese cada fotograma

//处理每一帧
while (waitKey(1) < 0)
{
    //从视频获取图像
    cap >> frame;

    // Stop the program if reached end of video
    if (frame.empty()) {
        cout << "Done processing !!!" << endl;
        cout << "Output file is stored as " << outputFile << endl;
        waitKey(3000);
        break;
    }
    //从原图像创建一个4D的blob
    blobFromImage(frame, blob, 1/255.0, cv::Size(inpWidth, inpHeight), Scalar(0,0,0), true, false);
        
    //为网络设置输入
    net.setInput(blob);
    
    //运行前向推理的过程,得到输出层的输出
    vector<Mat> outs;
    net.forward(outs, getOutputsNames(net));
        
    //移除低置信度的输出框
    postprocess(frame, outs);
        
    //展示效率信息。函数getPerfProfile返回每一层的推理时间
    vector<double> layersTimes;
    double freq = getTickFrequency() / 1000;
    double t = net.getPerfProfile(layersTimes) / freq;
    string label = format("Inference time for a frame : %.2f ms", t);
    putText(frame, label, Point(0, 15), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 255));
        
    //保存带有检测框的一帧图像
    Mat detectedFrame;
    frame.convertTo(detectedFrame, CV_8U);
    if (parser.has("image")) imwrite(outputFile, detectedFrame);
    else video.write(detectedFrame);
        
    imshow(kWinName, frame);        
}

2. función de avance

//运行前向推理的过程,得到输出层的输出
vector<Mat> outs;
net.forward(outs, getOutputsNames(net));

La salida de la función getOutputsNames()es el nombre de la capa de salida de tres escalas diferentes en la red (que predicen objetos grandes, medianos y pequeños respectivamente).

net.forward()La función obtiene el resultado de salida según el nombre de la capa de salida. El contenido de salida outses una Matmatriz, cada una de las cuales Mates un grupo de vectores de dimensión 5+nc (n filas y matriz de columnas 5+nc, nc es el número de categorías). outsCada elemento de la matriz es un vector de dimensión 5 + nc (hay tres elementos en total, todos son Mat) El vector de dimensión 5 + nc es la salida de cada capa de salida en forma de un objeto binario blob.

La salida de la red YOLOv4 es un cuadro rectangular, cada cuadro rectangular está representado por un vector y todos los cuadros rectangulares forman un grupo de vectores. La longitud de cada vector es el número de categorías + 5 parámetros . Los primeros cuatro de estos cinco parámetros son la posición del marco rectangular en la imagen, center_x, center_y, ancho, alto (todos son proporciones, que van de 0 a 1). , el quinto parámetro es la confianza de que la caja rectangular puede contener objetos . A partir del sexto parámetro del vector, representa la confianza de cada categoría del objeto en el cuadro rectangular .

Enlace de referencia: https://www.freesion.com/article/72531365556/

3.net.setPreferableBackend y net.setPreferableTarget

1.Parámetros de la función setPreferableBackend()

DNN_BACKEND_INFERENCE_ENGINE;
DNN_BACKEND_OPENCV;
DNN_BACKEND_HALIDE;
DNN_BACKEND_CUDA;
DNN_BACKEND_DEFAULT;

Entre ellos, si OpenCV se compila con la biblioteca Inference Engine de Intel, entonces DNN_BACKEND_DEFAULT es DNN_BACKEND_INFERENCE_ENGINE; de lo contrario, es DNN_BACKEND_OPENCV.

2.Parámetros de la función setPreferableTarget()

List of supported combinations backend / target:
|                        | DNN_BACKEND_OPENCV | DNN_BACKEND_INFERENCE_ENGINE | DNN_BACKEND_HALIDE |  DNN_BACKEND_CUDA |
|------------------------|--------------------|------------------------------|--------------------|-------------------|
| DNN_TARGET_CPU         |                  + |                            + |                  + |                   |
| DNN_TARGET_OPENCL      |                  + |                            + |                  + |                   |
| DNN_TARGET_OPENCL_FP16 |                  + |                            + |                    |                   |
| DNN_TARGET_MYRIAD      |                    |                            + |                    |                   |
| DNN_TARGET_FPGA        |                    |                            + |                    |                   |
| DNN_TARGET_CUDA        |                    |                              |                    |                 + |
| DNN_TARGET_CUDA_FP16   |                    |                              |                    |                 + |

Enlace de referencia: https://blog.csdn.net/weixin_43996161/article/details/113994433

Supongo que te gusta

Origin blog.csdn.net/m0_46749624/article/details/122401474
Recomendado
Clasificación