前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >利用OpenCV玩转YOLOv3

利用OpenCV玩转YOLOv3

作者头像
Amusi
修改2019-12-17 15:42:49
6K0
修改2019-12-17 15:42:49
举报
文章被收录于专栏:CVerCVer

前言

YOLOv3是You Only Look Once系列的最新目标检测算法,关于YOLOv3的介绍,网上一大堆,本文就不跟风描述。想要了解YOLOv3的同学,可以看一下YOLOv3:你一定不能错过

下面简单粗暴列出YOLOv3的结果和DarkNet-53结构:

YOLOv3实验结果

DarkNet-53结构

OpenCV-YOLOv3

前几个月跑过OpenCV-YOLOv2,因为时间问题,就没整理成推文。今天看到learnopencv的github上push了新代码,Amusi打开一看!哦哟,这不是OpenCV-YOLOv3么!

讲真,OpenCV开源社区的大神们太强大了,无时无刻不在更新OpenCV,里面DNN模块几乎每周都会更新。废话不多说,看看这次OpenCV-YOLOv3有哪些特点。

  1. 与OpenCV应用程序轻松集成:如果您的应用程序已经使用OpenCV而您只是想使用YOLOv3,则无需担心编译和构建额外的Darknet代码。
  2. OpenCV CPU版本快9倍:OpenCV的DNN模块CPU实现速度惊人。 例如,与OpenMP一起使用时,Darknet在CPU上花费大约2秒钟来对单个图像进行推理。 相比之下,OpenCV的实现只需0.22秒! 如下图所示:
  1. Python接口:Darknet是用C语言编写的,它并不官方支持Python。(其实这里不是不支持,而是没有Python源码,而是Python调用c编译的动态链接库来实现的)

CVer

Welcome to click AD

安装OpenCV3.4.2

注意:想要在OpenCV中玩转YOLOv3,必须安装OpenCV3.4.2版本及以上。

Python版安装方法

代码语言:javascript
复制
1# 推荐安装外挂版
2pip install opencv-contrib-python
3
4# 或者安装正常版
5pip install opencv-python

C++版安装方法

注意,安装OpenCV3.4.2时,如果使用官方提供的release包,需要VS2015或者VS2017才能使用。若利用源码进行安装,需要使用CMake工具,有点费时间,这里Amusi就不安装了。

这里推荐一个Windows下安装OpenCV的教程《OpenCV学习之路》OpenCV3.3安装教程(Windows版)

link: https://blog.csdn.net/amusi1994/article/details/76768775

下载预训练模型

  • yolov3.cfg
  • yolov3.weights
  • coco.names

上述三个文件是YOLOv3官网提供的预训练模型及网络文件,其中yolov3.cfg中定义了网络结构,yolov3.weights是预训练权重,而coco.names就是COCO数据集的类别文件。

如何下载呢,你既可以去YOLO官网下载,也可以阅读下面的CVer福利

代码

C++代码

object_detection_yolo.cpp

由于源码过长,而且Amusi并没有亲测C++版本的代码。所以这里po一段利用OpenCV-YOLOv3处理视频帧的代码,来吊吊大家胃口。

至于为什么Amusi没有亲测C代码,因为安装C++版本的OpenCV3.4.2有点花时间,这里就偷点懒。

代码语言:javascript
复制
 1 1// Process frames.
 2 2while (waitKey(1) < 0)
 3 3{
 4 4    // get frame from the video
 5 5    cap >> frame;
 6 6
 7 7    // Stop the program if reached end of video
 8 8    if (frame.empty()) {
 9 9        cout << "Done processing !!!" << endl;
1010        cout << "Output file is stored as " << outputFile << endl;
1111        waitKey(3000);
1212        break;
1313    }
1414    // Create a 4D blob from a frame.
1515    blobFromImage(frame, blob, 1/255.0, cvSize(inpWidth, inpHeight), Scalar(0,0,0), true, false);
1616
1717    //Sets the input to the network
1818    net.setInput(blob);
1919
2020    // Runs the forward pass to get output of the output layers
2121    vector<Mat> outs;
2222    net.forward(outs, getOutputsNames(net));
2323
2424    // Remove the bounding boxes with low confidence
2525    postprocess(frame, outs);
2626
2727    // Put efficiency information. The function getPerfProfile returns the 
2828    // overall time for inference(t) and the timings for each of the layers(in layersTimes)
2929    vector<double> layersTimes;
3030    double freq = getTickFrequency() / 1000;
3131    double t = net.getPerfProfile(layersTimes) / freq;
3232    string label = format("Inference time for a frame : %.2f ms", t);
3333    putText(frame, label, Point(0, 15), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 255));
3434
3535    // Write the frame with the detection boxes
3636    Mat detectedFrame;
3737    frame.convertTo(detectedFrame, CV_8U);
3838    if (parser.has("image")) imwrite(outputFile, detectedFrame);
3939    else video.write(detectedFrame);
4040
4141}

Python代码

object_detection_yolo.py

限于篇幅原因,这里只po一段利用OpenCV-YOLOv3处理视频帧的代码。详细代码,见文末CVer福利

代码语言:javascript
复制
 1while cv.waitKey(1) < 0:
 2
 3    # get frame from the video
 4    hasFrame, frame = cap.read()
 5
 6    # Stop the program if reached end of video
 7    if not hasFrame:
 8        print("Done processing !!!")
 9        print("Output file is stored as ", outputFile)
10        cv.waitKey(3000)
11        break
12
13    # Create a 4D blob from a frame.
14    blob = cv.dnn.blobFromImage(frame, 1/255, (inpWidth, inpHeight), [0,0,0], 1, crop=False)
15
16    # Sets the input to the network
17    net.setInput(blob)
18
19    # Runs the forward pass to get output of the output layers
20    outs = net.forward(getOutputsNames(net))
21
22    # Remove the bounding boxes with low confidence
23    postprocess(frame, outs)
24
25    # Put efficiency information. The function getPerfProfile returns the 
26    # overall time for inference(t) and the timings for each of the layers(in layersTimes)
27    t, _ = net.getPerfProfile()
28    label = 'Inference time: %.2f ms' % (t * 1000.0 / cv.getTickFrequency())
29    cv.putText(frame, label, (0, 15), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255))
30
31    # Write the frame with the detection boxes
32    if (args.image):
33        cv.imwrite(outputFile, frame.astype(np.uint8));
34    else:
35        vid_writer.write(frame.astype(np.uint8))

实验结果

对图像进行目标检测

bird.jpg

代码语言:javascript
复制
1python object_detection_yolo.py --image=bird.jpg

检测结果如下所示:

person.jpg

代码语言:javascript
复制
1python object_detection_yolo.py --image=person.jpg

注:在Amusi渣渣笔记本(CPU为Inter i5-5300 HQ)上,OpenCV-YOLOv3(Python版)的速度是800ms左右,由此估计C++版本应该在300~500ms左右。其实CPU模式下,速度已经杠杠的了,来看看这恐怖的accuracy。

对视频进行目标检测

此次没有视频演示!没有视频演示!

为什么没有?!

因为上传视频有点麻烦,哈哈,但这不影响我们使用OpenCV-YOLOv3。

代码语言:javascript
复制
1python object_detection_yolo.py --video=run.mp4

侃侃

OpenCV真的很强大,Amusi刚才看了一下其DNN模块,官网提供的示例,居然将Faster R-CNN、SSD和YOLO等算法统一利用一个函数接口来调用。

试想一下,自己训练好的model,然后跑在OpenCV代码中,真的很cool。

这里不得不说说OpenCV的缺点,不方便训练且一般不提供GPU加速。

但还要啥自行车!要啥自行车!

CVer福利

关注CVer微信公众号,后台回复:opencv-yolov3

即可获得OpenCV-YOLOv3示例代码、预训练模型以及测试图像/视频。

参考

[1] https://pjreddie.com/darknet/yolo/

[2] https://github.com/spmallick/learnopencv/tree/master/ObjectDetection-YOLO

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-08-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CVer 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档