Opencv项目实战:05 物体检测

Posted 夏天是冰红茶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Opencv项目实战:05 物体检测相关的知识,希望对你有一定的参考价值。

1,效果展示

为此,我专门还去查了查,怎么将视频转化为gif图,不知不觉中,我又多学会了一项技能。

OK!cool,效果很不错,今天需要搭配一些文件,都是可以从官网里找到的,那么我为了方便,专门去学习怎么在GitHub上托管项目,还下载了VScode和Git,我太难受了,如果不是要写博客,我绝对懒得去找教程。谢谢自己!

那么在此gif图像中,我检测了水瓶(截图时间不够了),鼠标,剪刀,书,手机,牙刷,键盘,电脑等。


 2,项目准备

  • 文件搭建

我会在结尾处,提供相关的资源,我们先在项目下新建一个目录,其中包含的文件,如图所示:

 3,代码的讲解与展示

import cv2

thres = 0.45 # Threshold to detect object

cap = cv2.VideoCapture(1)
cap.set(3,640)
cap.set(4,480)
cap.set(10,70)

classNames= []
classFile = 'coco.names'
with open(classFile,'rt') as f:
    classNames = f.read().rstrip('\\n').split('\\n')
    #restrip返回删除尾随空白的字符串副本。如果给定了字符而不是无,则删除字符中的字符。

configPath = 'ssd_mobilenet_v3_large_coco_2020_01_14.pbtxt'
weightsPath = 'frozen_inference_graph.pb'

net = cv2.dnn_DetectionModel(weightsPath,configPath)
net.setInputSize(320,320)
net.setInputScale(1.0/ 127.5)
net.setInputMean((127.5, 127.5, 127.5))
net.setInputSwapRB(True)

while True:
    success,img = cap.read()
    classIds, confs, bbox = net.detect(img,confThreshold=thres)
    print(classIds,bbox)

    if len(classIds) != 0:
        for classId, confidence,box in zip(classIds.flatten(),confs.flatten(),bbox):
            cv2.rectangle(img,box,color=(0,255,0),thickness=2)
            cv2.putText(img,classNames[classId-1].upper(),(box[0]+10,box[1]+30),
                        cv2.FONT_HERSHEY_COMPLEX,1,(0,255,0),2)
            cv2.putText(img,str(round(confidence*100,2)),(box[0]+200,box[1]+30),
                        cv2.FONT_HERSHEY_COMPLEX,1,(0,255,0),2)

    cv2.imshow("Output", img)
    if cv2.waitKey(1) & 0xFF == 27:
        break
    #对于物体的检测

 今天的重点在于讲解代码的思路。

  • 首先,打开我们的外部摄像头,并且设置窗口的宽,长,亮度,注意不要将窗口的大小超出我们外部摄像头的大小,不然你得到的图像可能就是黑屏。
  • 其次,在我们的coco.names文件当中,它是每个名词单独一行,所以通过文件操作,将其内容放入一个空列表当中,我们用到了read(),rstrip(),split()函数,不清楚的地方,可以去W3school上查询。
  • 接着,我们看看在包含了net的代码,它用到了DNN算法,其余的函数都可以在dnn.py文件里面查找到。
(1)setInputSize(weight,height)weight新输入宽度,height新输入宽度。
(2)setInputScale(1.0/ 127.5)设置帧的缩放因子值,帧值的比例乘数。
(3)setInputMean((127.5, 127.5, 127.5))简要设置帧的平均值。
(4)setInputSwapRB(True)将帧的标志设置为True。
  •  然后,又要用到一个detect()函数,它是属于class DetectionModel(Model)下的函数,在这里confThreshold用于根据置信度筛选框的阈值,我们将其阈值放在了较前面的位置,方便更改,它会返回ClassID结果检测中的类索引,一组对应的置信度,一组边界框。
  • 除此之外,我们用len(classIds) != 0来代表检测到了物体,然而我们有三个需要遍历的变量或信息,所以我们用到了zip函数,避免了写三个循环,而flatten()函数可以将其中的信息展开,再然后画框,放置文本,在这里需要提两句,在coco.name文件里面,每个名词是从1开始的,而classNames列表是从0开始的,故要在索引处-1,使用round()函数是因为confidence是小数,会与之前的classNmaes的东西叠加在一起,故此将其看作是百分数,并保留了两位小数。
  • 最后就是,imshow的展示窗口,以及点击Esc键推出。

 4,项目优化 

我已经将注释写在了代码当中,如有不清楚的地方,可以将其打印出来,进行观察。

其优化效果——有效的优化了之前检测框闪烁和重叠的现象。

import cv2
import numpy as np

thres = 0.45 # Threshold to detect object
#使用nms,不会像先前那样检测框有重叠和闪烁
nms_threshold = 0.2  #0.2 已经是较大的抑制效果
#若设置成1,将没有效果
cap = cv2.VideoCapture(1)
cap.set(3,1280)
cap.set(4,720)
cap.set(10,150)

classNames= []
classFile = 'coco.names'
with open(classFile,'rt') as f:
    classNames = f.read().rstrip('\\n').split('\\n')

#print(classNames)
configPath = 'ssd_mobilenet_v3_large_coco_2020_01_14.pbtxt'
weightsPath = 'frozen_inference_graph.pb'

net = cv2.dnn_DetectionModel(weightsPath,configPath)
net.setInputSize(320,320)
net.setInputScale(1.0/ 127.5)
net.setInputMean((127.5, 127.5, 127.5))
net.setInputSwapRB(True)

while True:
    success,img = cap.read()
    classIds, confs, bbox = net.detect(img,confThreshold=thres)
    bbox = list(bbox)
    #bbox本身得到的是numpy的数组,将其改为list
    confs = list(np.array(confs).reshape(1,-1)[0])
    #将其内容转化为只有一个列表,使用np.array()是因为元组是不能reshape
    confs = list(map(float,confs))
    #原本的confs是float32的形式,使用map()函数将float映射在confs上
    #print(type(confs[0]))
    #print(confs)
    indices = cv2.dnn.NMSBoxes(bbox,confs,thres,nms_threshold)
    #print(indices)
    for i in indices:
        i = i[0]
        #打印(indices)的内容是[[0]]
        box = bbox[i]
        x,y,w,h = box[0],box[1],box[2],box[3]
        cv2.rectangle(img, (x,y),(x+w,h+y), color=(0, 255, 0), thickness=2)
        cv2.putText(img,classNames[classIds[i][0]-1].upper(),(box[0]+10,box[1]+30),
                    cv2.FONT_HERSHEY_COMPLEX,1,(0,255,0),2)
        #此处需要一个classIds的特殊索引,它就是i,而且已经有了一个[],所以是[i][0]

    cv2.imshow("Output",img)
    cv2.waitKey(1)

5,项目资源

GitHub:Auorui/Opencv-project-training: According to the project made by learning murtaza Hassan's videos every day, thank the up Master of station B: a graduate student who knows a little about everything. It is mainly used to learn opencv by myself. On my CSDN blog, I have a detailed picture and text introduction of each project. I will continue to study hard. Welcome to my CSDN blog, where I store my code and some information. CSDN link: https://blog.csdn.net/m0_62919535?type=blog 。 You can check it in my column - opencv project practice. (github.com)https://github.com/Auorui/Opencv-project-training

 免费转化为Gif图网站:踢踢零工具 - tt0.tophttps://tt0.top/

6,项目总结与评价

其中的很多算法我也不是很明白,只是使用的思路学会到了,后面将会有人脸检测的项目,应该会用到YOYO算法。希望有人能在这个项目中玩的开心,感谢您的关注与支持!!!

 

 

以上是关于Opencv项目实战:05 物体检测的主要内容,如果未能解决你的问题,请参考以下文章

物体检测实战:使用 OpenCV 进行 YOLO 对象检测

物体检测实战:使用OpenCV内置方法实现行人检测

OpenCV:如何检测视频中是不是有快速移动的物体?

如何检测物体边框 opencv

Opencv项目实战目标检测:自动检测出现的所有动态目标

opencv 如何检测特定形状的物体