OpenCV4.4 + YOLOv4 真的可以运行了…..

Stella981
• 阅读 383

点击上方“AI算法与图像处理”,选择加"星标"或“置顶”

重磅干货,第一时间送达OpenCV4.4 + YOLOv4 真的可以运行了…..

来源:OpenCV学堂

==========================================================================================================

前一阵子YOLOv4发布了,后面就是YOLOv5,估计再过几天就要YOLOv10086了,这个时代技术进步太魔幻,改几个参数就可以继续升级版本。2020.718 OpenCV4.4发布了,支持YOLOv4推理,于是我立刻测试了一波。

模型下载

YOLOv4的相关模型合集在这里

https://github.com/AlexeyAB/darknet/wiki/YOLOv4-model-zoo

我使用的是基于COCO预训练模型:

YOLOv4-Leaky

OpenCV4.4 DNN

OpenCV4.4 支持YOLOv4,这个是它的官方release里面说的,其实我早就发现了YOLOv4可以通过OpenCV4.2直接跑,怎么OpenCV4.4才官宣。也许不发布新版本不好官宣,只有发布了新版本才可以顺便说一下。此外OpenCV4.4 DNN还有很多新添加的演示程序,支持了深度学习的光流、支持tensorflow object detection API的EfficientDet对象检测模型,但是前提是tensorflow2.x才可以。多了一个tf_text_graph_efficientdet.py文件,用来生成对应的pbtxt文件。

OpenCV4.4 DNN + YOLOv4对象检测演示

跟YOLOv3一样,YOLOv4也有三个输出层,完成推理之后,需要在进一步通过NMS实现对重叠框的去除,什么是NMS(非最大抑制),看下图就懂啦:

OpenCV4.4 + YOLOv4 真的可以运行了…..

然后说一下模型输入格式与输出格式

输入:NCHW=1x3x416x416
输出:NXC 其中N表示多少个对象,C的前四个数矩形框的[center_x, center_y, width, height],从第五个数值开始分别是每个类别的得分,求的最大得分,如果高于阈值0.5,则认为检测到了对象,每个score对应的index即是COCO类别文本。

根据上面的描述,对一个视频文件实现YOLOv4的对象检测代码如下:

 1Net net = readNetFromDarknet(yolov4_config, yolov4_model); 2net.setPreferableBackend(DNN_BACKEND_INFERENCE_ENGINE); 3net.setPreferableTarget(DNN_TARGET_CPU); 4std::vector<String> outNames = net.getUnconnectedOutLayersNames(); 5for (int i = 0; i < outNames.size(); i++) { 6    printf("output layer name : %s\n", outNames[i].c_str()); 7} 8 9vector<string> classNamesVec;10ifstream classNamesFile("D:/projects/opencv_tutorial/data/models/object_detection_classes_yolov3.txt");11if (classNamesFile.is_open())12{13    string className = "";14    while (std::getline(classNamesFile, className))15        classNamesVec.push_back(className);16}1718VideoCapture capture;19capture.open("D:/images/video/f35_02.mp4");20Mat frame;21// 加载图像 22while (true) {23    int64 start = getTickCount();24    capture.read(frame);25    Mat inputBlob = blobFromImage(frame, 1 / 255.F, Size(416, 416), Scalar(), true, false);26    net.setInput(inputBlob);2728    // 检测29    std::vector<Mat> outs;30    net.forward(outs, outNames);3132    vector<Rect> boxes;33    vector<int> classIds;34    vector<float> confidences;35    for (size_t i = 0; i<outs.size(); ++i)36    {37        // detected objects and C is a number of classes + 4 where the first 438        float* data = (float*)outs[i].data;39        for (int j = 0; j < outs[i].rows; ++j, data += outs[i].cols)40        {41            Mat scores = outs[i].row(j).colRange(5, outs[i].cols);42            Point classIdPoint;43            double confidence;44            minMaxLoc(scores, 0, &confidence, 0, &classIdPoint);45            if (confidence > 0.5)46            {47                int centerX = (int)(data[0] * frame.cols);48                int centerY = (int)(data[1] * frame.rows);49                int width = (int)(data[2] * frame.cols);50                int height = (int)(data[3] * frame.rows);51                int left = centerX - width / 2;52                int top = centerY - height / 2;5354                classIds.push_back(classIdPoint.x);55                confidences.push_back((float)confidence);56                boxes.push_back(Rect(left, top, width, height));57            }58        }59    }6061    vector<int> indices;62    NMSBoxes(boxes, confidences, 0.5, 0.2, indices);63    for (size_t i = 0; i < indices.size(); ++i)64    {65        int idx = indices[i];66        Rect box = boxes[idx];67        String className = classNamesVec[classIds[idx]];68        putText(frame, className.c_str(), box.tl(), FONT_HERSHEY_SIMPLEX, 1.0, Scalar(255, 0, 0), 2, 8);69        rectangle(frame, box, Scalar(0, 0, 255), 2, 8, 0);70    }71    float fps = getTickFrequency() / (getTickCount() - start);72    float time = (getTickCount() - start) / getTickFrequency();73    ostringstream ss;74    ss << "FPS : "<< fps <<" detection time: " << time*1000 << " ms";75    putText(frame, ss.str(), Point(20, 20), 0, 0.5, Scalar(0, 0, 255));76    imshow("YOLOv4-Detections", frame);77    char c = waitKey(1);78    if (c == 27) {79        break;80    }81}82waitKey(0);83return;

代码运行结果如下:

OpenCV4.4 + YOLOv4 真的可以运行了…..

OpenCV4.4 + YOLOv4 真的可以运行了…..

我只能说速度有点感人,我有点怕啦,当然我是在i7CPU上运行的。

最后的最后求一波分享!YOLOv4 trick相关论文已经下载并放在公众号后台关注“AI算法与图像处理”,回复 “200714”获取
      
        
 
       
       
       
       
         
  
        
        
        
        
          
   
         
         
         
         
           
    
          
          
          
          
            
     
           
           
           
           
             
      
            
            
             
              
               
                
                 
                  
                   
                    
                   
                   
                    
                   
                  
                 
                
               
              
            
          
            
     
           
           
           
         
           
    
          
          
          
        
          
   
         
         
         
       
         
  
        
        
        
      
        
 
       
       
       
      
        
 
       
       
       
       
         
  
        
        
        个人微信
      
        
 
       
       
       
      
        
 
       
       
       
       
         
  
        
        
        请注明:
       
         
  
        
        
        地区+学校/企业+研究方向+昵称
      
        
 
       
       
       
      
        
 
       
       
       
       
         
  
        
        
        如果没有备注不拉群!
      
        
 
       
       
       
      
        
 
       
       
       
       
         
  
        
        
        
        
          
   
         
         
         
         
           
    
          
          
          
        
          
   
         
         
         
       
         
  
        
        
        
      
        
 
       
       
       

本文分享自微信公众号 - AI算法与图像处理(AI_study)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
光头强的博客 光头强的博客
2个月前
Java面向对象试题
1、请创建一个Animal动物类,要求有方法eat()方法,方法输出一条语句“吃东西”。创建一个接口A,接口里有一个抽象方法fly()。创建一个Bird类继承Animal类并实现接口A里的方法输出一条有语句“鸟儿飞翔”,重写eat()方法输出一条语句“鸟儿吃虫”。在Test类中向上转型创建b对象,调用eat方法。然后向下转型调用eat()方
刚刚好 刚刚好
2个月前
css问题
1、在IOS中图片不显示(给图片加了圆角或者img没有父级)<div<imgsrc""/</divdiv{width:20px;height:20px;borderradius:20px;overflow:h
blmius blmius
1年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
小森森 小森森
2个月前
校园表白墙微信小程序V1.0 SayLove -基于微信云开发-一键快速搭建,开箱即用
后续会继续更新,敬请期待2.0全新版本欢迎添加左边的微信一起探讨!项目地址:(https://www.aliyun.com/activity/daily/bestoffer?userCodesskuuw5n)\2.Bug修复更新日历2.情侣脸功能大家不要使用了,现在阿里云的接口已经要收费了(土豪请随意),\\和注意
晴空闲云 晴空闲云
2个月前
css中box-sizing解放盒子实际宽高计算
我们知道传统的盒子模型,如果增加内边距padding和边框border,那么会撑大整个盒子,造成盒子的宽度不好计算,在实务中特别不方便。boxsizing可以设置盒模型的方式,可以很好的设置固定宽高的盒模型。盒子宽高计算假如我们设置如下盒子:宽度和高度均为200px,那么这会这个盒子实际的宽高就都是200px。但是当我们设置这个盒子的边框和内间距的时候,那
艾木酱 艾木酱
1个月前
快速入门|使用MemFire Cloud构建React Native应用程序
MemFireCloud是一款提供云数据库,用户可以创建云数据库,并对数据库进行管理,还可以对数据库进行备份操作。它还提供后端即服务,用户可以在1分钟内新建一个应用,使用自动生成的API和SDK,访问云数据库、对象存储、用户认证与授权等功能,可专
Stella981 Stella981
1年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Stella981 Stella981
1年前
Docker 架构原理、功能及使用
点击上方“杰哥的IT之旅”,选择“星标”公众号重磅干货,第一时间送达!(https://oscimg.oschina.net/oscnet/55595944998b405e9f939d9f9aa947d3.jpg)!(https://oscimg.oschina.net/oscnet/7f35f7e51704
Stella981 Stella981
1年前
Docker 部署SpringBoot项目不香吗?
  公众号改版后文章乱序推荐,希望你可以点击上方“Java进阶架构师”,点击右上角,将我们设为★“星标”!这样才不会错过每日进阶架构文章呀。  !(http://dingyue.ws.126.net/2020/0920/b00fbfc7j00qgy5xy002kd200qo00hsg00it00cj.jpg)  2
helloworld_28799839 helloworld_28799839
2个月前
常用知识整理
Javascript判断对象是否为空jsObject.keys(myObject).length0经常使用的三元运算我们经常遇到处理表格列状态字段如status的时候可以用到vue