点击上方“小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达

本文转自:opencv学堂

OpenCV在3.3.1的版本中开始正式支持Darknet网络框架并且支持YOLO1与YOLO2以及YOLO Tiny网络模型的导入与使用。YOLO是一种比SSD还要快的对象检测网络模型,算法作者在其论文中说FPS是Fast R-CNN的100倍,基于COCO数据集跟SSD网络的各项指标对比

在最新的OpenCV3.4上我也测试了YOLO3,发现不支持,因为YOLO3有个新层类型shortcut,OpenCV3.4的Darknet暂时还不支持。这里首先简单的介绍一下YOLO网络基本结构,然后在通过代码演示Darknet支持的YOLO在OpenCV使用。

一:YOLO网络

对象检测网络基本上可以分为两种,一种称为两步法、另外一种称为一步法,很显然基于图像分类加上滑动窗口的方式最早的R-CNN就是两步法的代表之一,两步法的前面基本上是一个卷积神经网络,可以是VGGNet或者Inception之类的,然后再加上一个滑动窗口,但是这种方法太慢,所以就有了区域推荐(RP),预先推荐一些感兴趣的区域,进行预言,这些方法普遍有一个缺点,计算量比较大,导致性能低下无法实时,而YOLO采样了一种完全不同的方法,达到对图像每个区域只计算一次(You Only Look Once - YOLO),YOLO把图像分为13x13的Cell(网格):

每个Cell预测5个BOX,同时YOLO也会生成一个置信分数,告诉每个BOX包含某个对象的可能性是多少,注意置信分数不会直接说明BOX内是检测到何种对象,最终那些得分高的BOX被加粗显示如下:

对于每个BOX来说,Cell会预测检测对象类别,这部分的工作就像是一个分类器一样,基于VOC数据集20中对象检测,YOLO结合分数与分类信息对每个BOX给出一个最终可能对象类型的可能性值,如下图,黄色区域85%可能性是狗:

因为总数是13x13的网格,每个网格预言5个BOX,所以最终有854个BOX,证据表明绝大多数的BOX得分会很低,我们只要保留30%BOX即可(取决于你自己的阈值设置),最终输出:

从上面可以看出整个图像只是被计算了一次,真正做到了降低计算量,提高了检测实时性。上述检测使用的YOLO的网络结构如下:

发现只有CNN层,没有FC层,是不是简单到爆,最后说一下为什么最后一层卷积层深度是125, 因为每个Cell检测5个BOX,对每个BOX来说,包含如下数据

  • BOX本身信息,x、y、w、h

  • 置信分数

  • 基于VOC数据集的20个对象类别

所以对每个BOX来说有25个参数,5个BOX= 5x25=125个参数。

上面是得到的网络模型就是tiny-YOLO网络模型,可以在移动端实时对象检测。这个跟作者在论文中提到的稍微有点差异,论文中作者是输入图像为448x448,分为7x7的网格(Cell),结构如下:

最终输出是每个Cell预测两个BOX,做20个分类,它得到最终是

  • BOX本身信息,x、y、w、h

  • 置信分数

深度 = SS(B5+20), 其中20个表示分类数目,S表示网络分割,B表示BOX个数。S=7、B=2,最终输出是77*30

二:在OpenCV中使用YOLO

OpenCV在3.3.1版本中开始支持Darknet,可能有人会问,Darknet是什么鬼,它是YOLO的作者自己搞出来的深度学习框架,支持C/C++/Python语言,支持YOLOv1、YOLOv2、YOLOv3等网络模型训练与使用。但是在OpenCV只是前馈网络,只支持预测,不能训练。OpenCV中基于YOLO模型我使用的是tiny-YOLO网络模型,支持20中对象检测。代码实现步骤如下:1.加载网络模型

String modelConfiguration = "D:/vcprojects/images/dnn/yolov2-tiny-voc/yolov2-tiny-voc.cfg";
String modelBinary = "D:/vcprojects/images/dnn/yolov2-tiny-voc/yolov2-tiny-voc.weights";
dnn::Net net = readNetFromDarknet(modelConfiguration, modelBinary);
if (net.empty())
{printf("Could not load net...\n");return;
}

2.加载分类信息

vector<string> classNamesVec;
ifstream classNamesFile("D:/vcprojects/images/dnn/yolov2-tiny-voc/voc.names");
if (classNamesFile.is_open())
{string className = "";while (std::getline(classNamesFile, className))classNamesVec.push_back(className);
}

3.加载测试图像

// 加载图像
Mat frame = imread("D:/vcprojects/images/fastrcnn.jpg");
Mat inputBlob = blobFromImage(frame, 1 / 255.F, Size(416, 416), Scalar(), true, false);
net.setInput(inputBlob, "data");

4.检测

// 检测
Mat detectionMat = net.forward("detection_out");
vector<double> layersTimings;
double freq = getTickFrequency() / 1000;
double time = net.getPerfProfile(layersTimings) / freq;
ostringstream ss;
ss << "detection time: " << time << " ms";
putText(frame, ss.str(), Point(20, 20), 0, 0.5, Scalar(0, 0, 255));

5.显示与运行效果

// 输出结果
for (int i = 0; i < detectionMat.rows; i++)
{const int probability_index = 5;const int probability_size = detectionMat.cols - probability_index;float *prob_array_ptr = &detectionMat.at<float>(i, probability_index);size_t objectClass = max_element(prob_array_ptr, prob_array_ptr + probability_size) - prob_array_ptr;float confidence = detectionMat.at<float>(i, (int)objectClass + probability_index);if (confidence > confidenceThreshold){float x = detectionMat.at<float>(i, 0);float y = detectionMat.at<float>(i, 1);float width = detectionMat.at<float>(i, 2);float height = detectionMat.at<float>(i, 3);int xLeftBottom = static_cast<int>((x - width / 2) * frame.cols);int yLeftBottom = static_cast<int>((y - height / 2) * frame.rows);int xRightTop = static_cast<int>((x + width / 2) * frame.cols);int yRightTop = static_cast<int>((y + height / 2) * frame.rows);Rect object(xLeftBottom, yLeftBottom,xRightTop - xLeftBottom,yRightTop - yLeftBottom);rectangle(frame, object, Scalar(0, 0, 255), 2, 8);if (objectClass < classNamesVec.size()){ss.str("");ss << confidence;String conf(ss.str());String label = String(classNamesVec[objectClass]) + ": " + conf;int baseLine = 0;Size labelSize = getTextSize(label, FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);rectangle(frame, Rect(Point(xLeftBottom, yLeftBottom),Size(labelSize.width, labelSize.height + baseLine)),Scalar(255, 255, 255), CV_FILLED);putText(frame, label, Point(xLeftBottom, yLeftBottom + labelSize.height),FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 0));}}
}
imshow("YOLO-Detections", frame);

运行结果如下:

文章中提到模型可以到本人的GITHUB上下载即可,地址如下

https://github.com/gloomyfish1998/opencv_tutorial

下载1:OpenCV-Contrib扩展模块中文版教程

在「小白学视觉」公众号后台回复:扩展模块中文教程即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。

下载2:Python视觉实战项目52讲

在「小白学视觉」公众号后台回复:Python视觉实战项目即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。

下载3:OpenCV实战项目20讲

在「小白学视觉」公众号后台回复:OpenCV实战项目20讲即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。

交流群

欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~

OpenCV中使用YOLO对象检测相关推荐

  1. YOLO 对象检测 OpenCV 源代码

    请直接查看原文章 YOLO 对象检测 OpenCV 源代码 https://hotdog29.com/?p=621 在 2019年7月8日 上张贴 由 hotdog发表回复 YOLO YOLO 在本教 ...

  2. OpenCV DNN支持的对象检测模型

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转自:opencv学堂 引言 OpenCV DNN不光支持图像 ...

  3. OpenCV中霍夫圆检测

    OpenCV中霍夫圆检测 在直线检测中,变换后在r−θr-\thetar−θ空间内曲线交点,然后根据阈值来得到直线.在圆中需要有三个变量圆心坐标和半径,因此变换后的空间在三维空间,根据三维空间中的曲线 ...

  4. 如何在OpenCV中使用YOLO

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 今天,我们将研究如何在OpenCV框架中使用YOLO.YOLO于2 ...

  5. OpenCV中的内存泄漏检测

    转自:http://chaishushan.blog.163.com/blog/static/130192897200911685559809/ 内存泄漏时程序开发中经常遇到的问题. 而且出现内存泄漏 ...

  6. jetson nano opencv 打开 CSI摄像头_Nvidia Jetson Nano:使用Tensorflow和OpenCV从头开始自定义对象检测...

    本文作者: 转载自: https://medium.com/swlh/nvidia-jetson-nano-custom-object-detection-from-scratch-using-ten ...

  7. 使用OpenCV和Python进行对象检测和跟踪

    在此功能中,我将介绍使用OpenCV和Python代码设置对象检测和跟踪所需的功能.使用随附的代码片段,您可以轻松设置Raspberry Pi和网络摄像头,以便制作用于物体检测的便携式图像传感器. 本 ...

  8. OpenCV中角点未检测到原因与FindChessboardCorners函数

    本博客参考两位前辈的实验记录角点检测与FindChessboardCorners函数 和 OpenCV学习笔记(33)棋盘格角点检测练习程序,总结整理而成. 实验历程: 我在前几天的实验中,总是检测不 ...

  9. 利用openCV中的cvCanny函数检测人脸的边缘

    前几天按照学校的要求做一个项目设计,指导老师让完成一个边缘检测的程序,用来提取出人脸的轮廓.于是将相关过程记录下来. 提取边缘,可以直接使用cvCanny函数. cvCanny是开放计算机视觉(Ope ...

最新文章

  1. 学习Angular前了解下TypeScript
  2. python方法和函数的格式是完全一样的_Python成为专业人士笔记-返回变量形式函数- str() 和 repr()...
  3. 高并发高流量网站架构详解--转载
  4. get pid and kill
  5. 腾讯云培训认证中心开放日
  6. 《王朔和海岩的文学选择》
  7. 这套网红试卷火了!数学老师您应该是文案出身吧?
  8. 20190830每日一句
  9. 西安电脑服务器维修电脑,西安苹果电脑维修
  10. wps怎么图片透明_wps中图片怎么样调透明度_word设置图片背景透明的图文教程-爱纯净...
  11. 动物实验,如何设置对照?
  12. 阿里云——云迁移中心
  13. 想天浏览器:推荐国内主流浏览器TOP10
  14. 安卓实现截图功能的两种方式
  15. 在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr() ,这种方法在大部分情况下都是有效的。但是在通过了Apache,Squi...
  16. Mybatis-plus批量插入
  17. k8s挂载目录_Kubernetes 挂载文件到pod里面
  18. Spring Cloud Alibaba 服务消费者调用 nacos 服务报错:java.net.UnknownHostException: xxx
  19. elementary os网易云音乐托盘图标不显示菜单解决方法
  20. 搞编程,你必知必会的复杂度分析

热门文章

  1. 一年参加一次就够,全新升级的AI开发者大会议程出炉!
  2. 百度燎原计划2018强势回归 开放深度学习工程师评价标准
  3. 我亲手调教的AI,竟然开始歧视我了!
  4. 老板说我最近飘了,都敢用 MySQL 实现分布式锁了
  5. 限量!Alibaba首发“Java成长笔记”,差距不止一点点
  6. G1调优很难?记住这些经验技巧~
  7. Spring Boot 打包不同环境配置与 Shell 脚本部署
  8. 浅谈 CAP 和 Paxos 共识算法
  9. SpringBoot缓存应用实践
  10. 机器学习博士在获得学位之前需要掌握的九种工具!