论文地址:[YOLO] [YOLOv2/YOLO9000] [YOLOv3] [YOLOv4]
YOLO系列权重、配置文件下载地址:https://github.com/AlexeyAB/darknet
代码解读:[Deep Learning based Object Detection using YOLOv3 with OpenCV ( Python / C++ ) ][中文翻译]
代码下载:这边有一个可以运行YOLOv3、YOLOv4、YOLO-Fastest,YOLObile四种网络的[C++代码][参考博客],只需在主函数修改参数即可,强烈推荐.

运行平台:i7 9700+VS2017+opencv4.4.0(opencv版本不宜过低,之前使用opencv3.4.9,只能运行YOLOv3和YOLO-Fastest,运行剩下两个会在加载网络处报错,应该是不支持YOLOv4的激活函数)

链接:https://pan.baidu.com/s/1EJRMypMR0SSEGGjCpyYskg
提取码:560s

可能遇到的报错:找不到opencv440d.dll,直接去opencv安装目录下E:\opencv4.4.0\build\x64\vc15\bin将opencv440d.dll文件复制到C:\Windows\System32下即可

一、网络输出
YOLOv3输出3个特征图,从而实现检测小目标的功能。

this->net.forward(outs, this->net.getUnconnectedOutLayersNames());
1
outs是一个三维矩阵,每一个包围框都输出一个包含85个元素的行向量,以红色方框所在那一行为例
前4维:归一化后的目标尺寸,分别对应横坐标、纵坐标、宽度、高度(具体的横纵坐标、目标尺寸还需要用到原文公式进一步计算)
第5维:显示该包围框包含目标的概率(这个数值在我的片面理解应该是类似yolov1里面提到的,目标预测包围框与groundtruth之间的IOU)
后80维:代表80个类别对应的置信度/Score

二、代码注释笔记
main_yolo.cpp
#include "yolo.h"

YOLO::YOLO(Net_config config)
{
    cout << "Net use " << config.netname << endl;
    this->confThreshold = config.confThreshold; //置信度阈值,筛选可能包含目标的包围框
    this->nmsThreshold = config.nmsThreshold;   //非极大值抑制阈值,避免对同一个目标产生多个包围框
    this->inpWidth = config.inpWidth;
    this->inpHeight = config.inpHeight;
    strcpy_s(this->netname, config.netname.c_str());

//load names of classes 读取coco.names文件的类别名
    ifstream ifs(config.classesFile.c_str());
    string line;
    while (getline(ifs, line)) this->classes.push_back(line);

//load the network
    this->net = readNetFromDarknet(config.modelConfiguration, config.modelWeights);
    this->net.setPreferableBackend(DNN_BACKEND_OPENCV);  //Opencv
    this->net.setPreferableTarget(DNN_TARGET_CPU);     //CPU  或改成DNN_TARGET_OPENCL调用GPU,但因为我电脑没显卡,没试过
}

void YOLO::postprocess(Mat& frame, const vector<Mat>& outs)   // Remove the bounding boxes with low confidence using non-maxima suppression
{
    vector<int> classIds;
    vector<float> confidences;
    vector<Rect> boxes;

for (size_t i = 0; i < outs.size(); ++i)
    {
        // Scan through all the bounding boxes output from the network and keep only the
        // ones with high confidence scores. Assign the box's class label as the class
        // with the highest score for the box.
        // outs[i]每一行有85个元素,头四个元素代表center_x, center_y, width和height。第五个元素表示包含着目标的边界框的置信度。
        // 剩下80个元素是和每个类别(如目标种类coconame里面定义的)有关的置信度
        float* data = (float*)outs[i].data;
        for (int j = 0; j < outs[i].rows; ++j, data += outs[i].cols)
        {
            cv::Mat look = outs[i];
            Mat scores = outs[i].row(j).colRange(5, outs[i].cols);//取每一行后80个元素,即每一类对应的置信度
            Point classIdPoint;
            double confidence;
            // Get the value and location of the maximum score
            minMaxLoc(scores, 0, &confidence, 0, &classIdPoint);
            if (confidence > this->confThreshold)
            {
                int centerX = (int)(data[0] * frame.cols);
                int centerY = (int)(data[1] * frame.rows);
                int width = (int)(data[2] * frame.cols);
                int height = (int)(data[3] * frame.rows);
                int left = centerX - width / 2;
                int top = centerY - height / 2;

classIds.push_back(classIdPoint.x);  //记录对应的类
                confidences.push_back((float)confidence);  //记录对应类的置信度
                boxes.push_back(Rect(left, top, width, height)); //记录包围框
            }
        }
    }

// Perform non maximum suppression to eliminate redundant overlapping boxes with
    // lower confidences
    vector<int> indices;
    NMSBoxes(boxes, confidences, this->confThreshold, this->nmsThreshold, indices);
    for (size_t i = 0; i < indices.size(); ++i)
    {
        int idx = indices[i];
        Rect box = boxes[idx];
        this->drawPred(classIds[idx], confidences[idx], box.x, box.y,
            box.x + box.width, box.y + box.height, frame);
    }
}

void YOLO::drawPred(int classId, float conf, int left, int top, int right, int bottom, Mat& frame)   // Draw the predicted bounding box
{
    //Draw a rectangle displaying the bounding box
    rectangle(frame, Point(left, top), Point(right, bottom), Scalar(0, 0, 255), 3);

//Get the label for the class name and its confidence
    string label = format("%.2f", conf);
    if (!this->classes.empty())
    {
        CV_Assert(classId < (int)this->classes.size());
        label = this->classes[classId] + ":" + label;
    }

//Display the label at the top of the bounding box
    int baseLine;
    Size labelSize = getTextSize(label, FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);
    top = max(top, labelSize.height);
    //rectangle(frame, Point(left, top - int(1.5 * labelSize.height)), Point(left + int(1.5 * labelSize.width), top + baseLine), Scalar(0, 255, 0), FILLED);
    putText(frame, label, Point(left, top), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0, 255, 0), 1);
}

void YOLO::detect(Mat& frame)
{
    //将输入图像frame转为神经网络的输入类型bolb,图像像素值从0~255归一化到0~1,并调整尺寸为--Size(this->inpWidth, this->inpHeight)
    Mat blob;
    blobFromImage(frame, blob, 1 / 255.0, Size(this->inpWidth, this->inpHeight), Scalar(0, 0, 0), true, false);
    //设置网络输入
    this->net.setInput(blob);
    vector<Mat> outs;
    //Runs the forward pass to get output of the output layers  运行前向网络得到输出
    this->net.forward(outs, this->net.getUnconnectedOutLayersNames());
    //去掉置信度过低的包围框
    this->postprocess(frame, outs);

vector<double> layersTimes;
    double freq = getTickFrequency() / 1000;

//Put efficiency information. The function getPerfProfile returns the
    //overall time for inference(t) and the timings for each of the layers(in layersTimes)
    double t = net.getPerfProfile(layersTimes) / freq;
    string label = format("%s Inference time : %.2f ms", this->netname, t);
    putText(frame, label, Point(0, 30), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 255), 2);
    //imwrite(format("%s_out.jpg", this->netname), frame);
}

int main()
{
    YOLO yolo_model(yolo_nets[0]);
    string imgpath = "person.jpg"; 
    Mat srcimg = imread(imgpath);
    yolo_model.detect(srcimg);

static const string kWinName = "Deep learning object detection in OpenCV";
    namedWindow(kWinName, WINDOW_NORMAL);
    imshow(kWinName, srcimg);
    waitKey(10);
    destroyAllWindows();
}

三、跟踪结果

跟踪速度还算可以,用GPU可能会快点

————————————————
版权声明:本文为CSDN博主「百里工人」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_40199447/article/details/111473376

YoLov3目标检测代码C++版本运行相关推荐

  1. 深度篇——目标检测史(七) 细说 YOLO-V3目标检测 之 代码详解

    返回主目录 返回 目标检测史 目录 上一章:深度篇--目标检测史(六) 细说 YOLO-V3目标检测 下一章:深度篇--目标检测史(八) 细说 CornerNet-Lite 目标检测 论文地址:< ...

  2. 【yolov3目标检测】(3) opencv+yolov3 检测交通路况,附python完整代码

    各位同学好,今天和大家分享一下如何使用 opencv 调用 yolov3 模型,加载网络权重,很方便地实现 yolov3 目标检测.先放张图看效果. 使用的网上找的行车记录仪视频做测试,数据集采用CO ...

  3. 使用PyTorch从零开始实现YOLO-V3目标检测算法 (一)

    原文:https://blog.csdn.net/u011520516/article/details/80222743 点击查看博客原文 标检测是深度学习近期发展过程中受益最多的领域.随着技术的进步 ...

  4. 使用pytorch从零开始实现YOLO-V3目标检测算法 (二)

    原文:https://blog.csdn.net/u011520516/article/details/80212960 博客翻译 这是从零开始实现YOLO v3检测器的教程的第2部分.在上一节中,我 ...

  5. 使用PyTorch从零开始实现YOLO-V3目标检测算法 (四)

    原文:https://blog.csdn.net/u011520516/article/details/80228130 点击查看博客原文 这是从零开始实现YOLO v3检测器的教程的第4部分,在上一 ...

  6. 使用PyTorch从零开始实现YOLO-V3目标检测算法 (三)

    原文:https://blog.csdn.net/u011520516/article/details/80216009 点击查看博客原文 这是从零开始实现YOLO v3检测器的教程的第3部分.第二部 ...

  7. YOLOV3目标检测模型训练实例

    YOLOV3目标检测 从零开始学习使用keras-yolov3进行图片的目标检测,比较详细地记录了准备以及训练过程,提供一个信号灯的目标检测模型训练实例,并提供相关代码与训练集. DEMO测试 YOL ...

  8. Pyqt搭建YOLOV3目标检测界面(超详细+源代码)

    Pyqt搭建YOLOV3目标检测界面(超详细+源代码) 2022.5.25更新 2021.11.23 更新 2021.11.22 更新 实现效果如下所示,可以检测图片.视频以及摄像头实时检测. 0.准 ...

  9. 神经网络学习小记录50——Pytorch 利用efficientnet系列模型搭建yolov3目标检测平台

    神经网络学习小记录50--Pytorch 利用efficientnet系列模型搭建yolov3目标检测平台 学习前言 什么是EfficientNet模型 源码下载 EfficientNet模型的实现思 ...

最新文章

  1. python3.7安装-Linux安装python3.7
  2. python输入多个字符串、输入最长的一串_无重复字符的最长子串(Python之暴力求解)...
  3. 6、Flutter Error waiting for a debug connection: ProcessException: adb did not report f(转)
  4. 33个PPT下载丨2018年PostgreSQL中国技术大会PPT
  5. SharePoint2007安装图文详解三:安装SqlServer2005
  6. 黑客利用域前置技术攻击缅甸政府并隐藏恶意活动
  7. Linux中zip和tar处理软链接的差异与选择
  8. 取消IE“已限制此网页运行可以访问计算机的脚本
  9. Netty的并发编程实践3:CAS指令和原子类
  10. 《机器学习Python实践》第5章——数据导入
  11. 【2022最新罗技G502吃鸡宏】
  12. 02虚幻编辑器各部分功能详解
  13. 201819102040张辰飞
  14. 安徽大学电气工程及自动化学院本科实验报告(MATLAB)——六、七章
  15. C++ 测试CFile读写文本
  16. 启用Direct3D功能
  17. 卸载软件中找不到360安全卫士该如何卸载360?
  18. STM8L的USART1串口通信详解 含例程
  19. ibernate、EJB3和JPA简介
  20. 微信小程序获取头像地址

热门文章

  1. Studio 3T无法连接MongoDB异常错误 解决方法
  2. 全球知名浏览器盘点,跨境电商的你知道吗?
  3. php怎么求最小公倍数,用PHP实现最小公倍数
  4. 计算机组成原理MVRD,计算机组成原理实验
  5. css 的 calc() 方法
  6. 泛泰SKYA830黑砖QHSUSB_DLOAD救砖教程
  7. ad20生成二维码_AD20(AltiumDesigner)最全快捷键-资源下载人人文库网
  8. 计算机休眠后黑屏打不开,电脑待机后黑屏打不开怎么办
  9. 倒计时1天,六位专家周末带你解锁前端研发新姿势
  10. 数值分析复化求积matlab,MATLAB数值分析实验二(复合梯形、辛普森和龙贝格求积,以及二重积分计算等)...