- 使用SIFT的物体检测
- 使用ORB进行对象检测
- 定向梯度直方图(HOG)
- 定向梯度直方图(HOG),分步进行:
- HAAR级联分类器
- 面部和眼睛检测
- 实时面部和眼睛检测
- 调整级联分类器
- 视频中的汽车和行人检测
我们从在Windows上安装python OpenCV开始,到目前为止,已经使用Python完成了一些基本的图像处理,图像分割和对象检测,以下教程对此进行了介绍:
- Python OpenCV入门:安装和基本图像处理
- Python OpenCV中的图像处理(第1部分)
- OpenCV中的图像处理(第2部分)
- 使用OpenCV进行图像分割-提取图像的特定区域
我们还了解了各种对象检测方法和算法,其中使用不同算法为每个对象确定了一些关键点。在本教程中,我们将使用这些算法来检测现实生活中的物体,这里我们将使用SIFT和ORB进行检测。
使用SIFT的物体检测
在这里,对象检测将使用实时网络摄像头流完成,因此,如果它识别出对象,则会提及找到的物体。在代码中,主要部分由称为SIFT检测器的功能扮演,大部分处理工作均由该功能完成。
在代码的另一半中,我们首先打开网络摄像头流,然后加载图像模板,即参考图像,即程序实际上正在浏览网络摄像头流。
接下来,我们将在无限 while 循环的帮助下连续从网络摄像头流中捕获图像,然后捕获网络摄像头框架的相应高度和宽度,然后在其中定义关注区域(ROI)框的参数,我们的对象可以通过采用相应的摄像头框架的高度和宽度来放入。然后我们从上面定义的ROI参数中绘制矩形。然后,最终将矩形裁剪出来,并将其输入代码的SWIFT检测器部分。
现在,SIFT检测器基本上有两个输入,一个是裁剪的图像,另一个是我们先前定义的图像模板,然后它给我们一些匹配项,因此匹配项基本上是裁剪后的图像中相似的对象或关键点的数量和目标图片。然后,为匹配项定义一个阈值,如果匹配项值大于阈值,则将在屏幕上找到的图像以ROI矩形的绿色放置。
现在让我们回到代码的主要部分,该函数称为SIFT检测器,它将输入作为两个图像,一个是它正在寻找对象的图像,另一个是我们试图匹配的对象到(图像模板)。然后对第一张图像进行灰度处理,并将图像模板定义为第二张图像。然后我们创建一个SIFT检测器对象并运行OpenCV SIFT检测和计算功能,以便检测关键点并计算描述符,描述符基本上是存储有关关键点信息的向量,并且在进行匹配时,这一点非常重要在图像的描述符之间。
然后定义基于FLANN的匹配器,我们将不在后面讨论匹配的数学理论,但是您可以轻松地对其进行Google搜索。首先,将索引 kdtree 定义为零,然后以字典格式设置索引和搜索参数,我们只定义要使用的算法KDTREE,并且要使用的树数越多我们使用的越复杂越慢。在搜索参数中定义检查次数,这基本上是要完成的匹配数。
然后,通过加载先前定义的参数(即索引参数和搜索参数)来创建基于FLANN的匹配器对象,并以此为基础创建基于FLANN的匹配器,该匹配器是KNN匹配器,其中KNN是K近邻,基本上,这是一种我们寻找最接近的匹配器和描述符,并使用初始化常数k进行匹配。现在,此基于FLANN的匹配器将返回我们获得的匹配数。
基于FLANN的匹配只是一个近似值,为了提高基于FLANN的匹配器的准确性,我们执行了Lowe比率测试,它所做的是它从基于knn flann的匹配器中寻找匹配项,并在此处定义了一些距离的矩阵参数,距离是一个numpy函数,一旦满足条件,就将匹配项追加到匹配项中并返回找到的匹配项,因此实时视频流会告诉您在屏幕一角找到的匹配项数。
现在,让我们看一下上面描述的代码:
import cv2 import numpy as np def sift_detector(new_image,image_template): #将输入图像与模板进行比较的函数 #然后返回它们之间SIFT匹配的数量 image1 = cv2.cvtColor(new_image,cv2.COLOR_BGR2GRAY) image2 = image_template #创建SIFT检测器对象 #sift = cv2.SIFT() sift = cv2.xfeatures2d.SIFT_create() #使用SIFT 关键点_1,描述符_1 = sift.detectAndCompute(image1,None) 关键点_2,描述符_2 = sift.detectAndCompute(image2,无) #为Flann Matcher定义参数 FLANN_INDEX_KDTREE = 0 index_params = dict(算法= FLANN_INDEX_KDTREE,树= 3) search_params = dict(checks = 100) #创建Flann Matcher对象 flann = cv2.FlannBasedMatcher(index_params,search_params) #使用K最近邻方法获取匹配项 #结果'matches'是在两个图像 匹配 中找到的相似匹配项的数量= flann.knnMatch(descriptors_1,描述符_2,k = 2)#使用Lowe比率存储良好匹配 ,在匹配中对m,n进行测试good_matches = for m,n: 如果m.distance <0.7 * n.distance: good_matches.append(m) 返回len( good_matches) cap = cv2.VideoCapture(0) #加载我们的图像模板,这是我们的参考图像 image_template = cv2.imread('phone.jpg',0) 而True: #获取摄像头图像 ret,frame = cap.read() #获取摄像头框架的高度和宽度 ,width = frame.shape #定义ROI框的尺寸 top_left_x = int(width / 3) top_left_y = int((height / 2)+(height / 4)) bottom_right_x = int((宽度/ 3)* 2) bottom_right_y = int((高度/ 2)-(高度/ 4)) #为我们感兴趣的区域绘制矩形窗口 cv2.rectangle(frame,(top_left_x,top_left_y ),(bottom_right_x,bottom_right_y),255,3) #我们在上 方定义的裁剪 观察窗口裁剪=帧#水平翻转帧方向 frame = cv2.flip(frame,1) #获取SIFT匹配项的数量 matchs = sift_detector(cropped, image_template) #显示状态字符串,显示当前编号。的匹配项 cv2.putText(frame,str(matches),(450,450),cv2.FONT_HERSHEY_COMPLEX,2,(0,255,0),1) #指示对象检测的阈值 #由于SIFT检测器返回的误差很小,因此我们使用10 threshold = 10 #如果匹配项超过我们的阈值,则 如果匹配项>阈值, 则已检测到对象:cv2.rectangle(frame,(top_left_x,top_left_y),(bottom_right_x,bottom_right_y),(0,255,0),3) cv2.putText(frame) ,'找到对象',(50,50),cv2.FONT_HERSHEY_COMPLEX,2,(0,255,0),2) cv2.imshow('使用SIFT的对象检测器',frame) 如果cv2.waitKey(1)== 13: #13是Enter键 中断 cap.release() cv2.destroyAllWindows()
使用ORB进行对象检测
使用SIFT的对象检测非常酷且准确,因为它可以根据关键点生成准确的匹配数目,但是它已获得专利,这使其难以用于商业应用,而另一种解决方法是ORB算法用于物体检测。
类似于将SIFT分为两部分的SIFT对象检测方法,此处将遵循相同的步骤。
首先,我们定义函数ORB_detector,它接受两个输入,一个是来自网络摄像头的实时流图像,另一个是图像模板,在此基础上我们将匹配图像。然后,我们对网络摄像头图像进行灰度处理,然后初始化ORB检测器,并在此处将其设置为1000个关键点和1.2的缩放参数。您可以轻松地使用这些参数,然后检测图像的关键点(kp)和描述符(des),而我们在 detectANDCompute 函数中定义的第二个参数为NONE,它要求是否使用图像遮罩,并且我们在这里否认。
然后移到检测器,之前我们一直在使用基于FLANN的匹配器,但是这里我们将使用BFMatcher,在BFMatcher内部,我们定义两个参数,一个是NORM_HAMMING,另一个是crossCheck,其值为TRUE。
然后使用上面定义的描述符计算这两个图像之间的匹配,由于这些匹配不是近似值,因此它们全部返回匹配的数量,因此不需要进行Lowe比率测试,而是根据距离对匹配进行排序,至少距离越长,匹配越好(此处的距离表示点之间的距离),最后,我们使用长度函数返回匹配的次数。
并且在主要功能中,我们将阈值设置为更高的值,因为球检测器会产生大量噪声。
现在让我们看一下基于ORB的检测代码
import cv2 import numpy as np def ORB_detector(new_image,image_template): #将输入图像与模板进行比较的函数 #然后返回它们之间的ORB匹配数 image1 = cv2.cvtColor(new_image,cv2.COLOR_BGR2GRAY) #使用以下命令创建ORB检测器1000个缩放金字塔因子为1.2的关键点 orb = cv2.ORB_create(1000,1.2) #检测原始图像的关键点 (kp1,des1)= orb.detectAndCompute(image1,None) #检测旋转图像的关键点 (kp2,des2) = orb.detectAndCompute(image_template,None) #创建匹配器 #请注意,我们不再使用基于Flann的匹配 bf = cv2.BFMatcher(cv2.NORM_HAMMING,crossCheck = True) #做匹配的 比赛= bf.match(des1,des2) #根据距离对比赛进行排序。最小距离 #更好地 匹配=排序(matches,key = lambda val:val.distance) return len(matches) cap = cv2.VideoCapture(0) #加载图像模板,这是我们的参考图像 image_template = cv2.imread( 'phone.jpg',0) #image_template = cv2.imread('images / kitkat.jpg',0) 而True: #获取摄像头图像 ret,frame = cap.read() #获取摄像头框架 高度 和宽度,width = frame.shape #定义ROI框的尺寸(注意其中一些内容应该在循环之外) top_left_x = int(width / 3) top_left_y = int((高度/ 2)+(高度/ 4)) bottom_right_x = int((宽度/ 3)* 2) bottom_right_y = int((高度/ 2)-(高度/ 4)) #为我们绘制矩形窗口感兴趣区域 cv2.rectangle(frame,(top_left_x,top_left_y),(bottom_right_x,bottom_right_y),255,3) #我们在上面定义的 裁剪 观察窗口裁剪= frame #水平翻转框架方向 frame = cv2.flip(frame,1 ) #获取ORB匹配项的数目 matchs = ORB_detector(cropped,image_template) #显示状态字符串,显示当前编号。匹配项 output_string =“ Matches =” + str(matches) cv2.putText(frame,output_string,(50,450),cv2.FONT_HERSHEY_COMPLEX,2,(250,0,150),2) #用于指示物体检测的阈值 #对于新图像或 明亮的条件,您可能需要进行一些实验#注意:ORB检测器可以获取前1000个匹配项,而350本质上是最小35%匹配 阈值= 250 #如果匹配项超过了阈值,然后 如果匹配>阈 值则检测到对象:cv2.rectangle(frame,(top_left_x,top_left_y),(bottom_right_x,bottom_right_y),(0,255,0),3) cv2.putText(frame,'找到对象',(50 ,50),cv2.FONT_HERSHEY_COMPLEX,2,((0,255,0),2) cv2.imshow('使用ORB的对象检测器,帧), 如果cv2.waitKey(1)== 13:#13是Enter键的 中断 上限.release() cv2.destroyAllWindows()
定向梯度直方图(HOG)
现在,让我们讨论一个不同的描述符,即定向梯度直方图(HOG)。
HOG是非常酷和有用的描述符,它们已广泛且成功地用于对象检测,如先前所见,像图像描述符(如SIFT和ORB)我们必须计算关键点,然后必须从这些关键点中计算描述符,HOG会执行此过程不一样。它将对象表示为单个特征向量,而不是一组特征向量(每个特征向量代表图像的一部分)。这意味着我们对整个图像具有单一矢量特征。
它由图像上的滑动窗口检测器计算得出,其中HOG描述符针对每个位置进行计算。然后将每个位置合并为一个特征向量。
像SIFT一样,图像的比例通过金字塔进行调整。
以前我们曾经使用过FLANN和BFMatcher之类的匹配器,但是HOG在SVM(支持向量机)分类器的帮助下做的不同,其中将计算出的每个HOG描述符馈送到SVM分类器,以确定是否找到了对象。
这是Dalal&Triggs撰写的有关使用HOG进行人类检测的好论文的链接:
https ://lear.inrialpes.fr/people/triggs/pubs/Dalal-cvpr05.pdf
定向梯度直方图(HOG),分步进行:
了解HOG可能非常复杂,但是在这里,我们将只涉及HOG的理论,而不会更深入地研究与之相关的数学。
因此,让我们拍一下这张照片,它有点像素化,并且在这里的右上角是8x8像素框,因此在此框中,我们计算每个像素处的梯度矢量或边缘方向。因此,这意味着在此框内,我们计算框内像素的图像梯度矢量(它们是图像强度本身的方向或流向),然后生成64(8 x 8)个梯度矢量,然后将其表示为直方图。因此,想象一个代表每个梯度向量的直方图。因此,如果所有点或强度都在一个方向上说谎,则该方向的直方图可以说是45度,则直方图将在45度处达到峰值。
因此,我们现在要做的是将每个像元划分为多个角形单元,其中每个单元格对应一个梯度方向(例如x,y)。在Dalal和Triggs的论文中,他们使用了9个bin0-180°(每个20°)。这有效地将64个向量减少到9个值。因此,我们要做的是减小大小,但保留所有需要的关键信息。
计算猪的下一步是归一化,我们将梯度归一化以确保对照明变化的不变性,即亮度和对比度。
在此图像中,强度值根据相应的方向显示为正方形,并且彼此之间的差值均为50
Δ ħ = 50,Δ v = 50; │Δ│=√50 2 50 = 70.72,70.72 / 100 = 0.707
我们将矢量除以所有梯度均值0.707,这就是归一化。
同样,如果我们改变强度或改变对比度,我们将得到以下数值。
Δ ħ = 50,Δ v = 50; │Δ│=√50 2 50 = 70.72,70.72 / 100 = 0.707; Δ ħ = 100,Δ v = 100; │Δ│=√100 2 100 = 141.42,141.42 / 100 = 1.41
归一化不是在像元级上进行的,而是在块级上进行的,因此这里的块基本上是一组4个像元,这考虑到了相邻块,因此在考虑较大图像段的同时进行了归一化。
现在让我们看一下代码
导入numpy作为np 导入cv2 导入matplotlib.pyplot作为plt #加载图像然后灰度 图像= cv2.imread('elephant.jpg') 灰色= cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) #显示原始图像 cv2.imshow('输入图像',图像) cv2.waitKey(0)# 定义参数,像元大小和块大小 #以像素为单位的 hxw cell_size =(8,8) #以像 元为单位的hxw block_size =(2,2) #定向仓的 数量= 9 #使用OpenCV的HOG描述符 #winSize是裁剪为单元格大小倍数的图像大小 hog = cv2.HOGDescriptor(_winSize =(gray.shape // cell_size * cell_size, gray.shape // cell_size * cell_size), _blockSize =(block_size * cell_size, block_size * cell_size), _blockStride =(cell_size,cell_size), _cellSize =(cell_size,cell_size), _nbins = nbins) #创建我们使用的numpy数组形状创建hog_features n_cells =(gray.shape // cell_size,gray.shape // cell_size) #我们首先按行索引块。 #hog_feats现在包含每个方向的梯度幅度, #包含其组中每个单元的每个组的#值。索引是按行然后按列。 hog_feats = hog.compute(gray).reshape(n_cells-block_size + 1, n_cells-block_size + 1, block_size,block_size,nbins).transpose((1,0,2,3,4)) #创建具有nbin尺寸的渐变数组以存储渐变方向 gradients = np.zeros(((n_cells,n_cells,nbins))) #创建尺寸为 cell_count = np.full(((n_cells,n_cells,1),0,dtype = int的 数组)# 范围内off_y的 块归一化(block_size):范围内off_x的块归一化(block_size): 渐变-block_size + off_y + 1, off_x:n_cells-block_size + off_x + 1] + = \ hog_feats cell_count-block_size + off_y + 1, off_x:n_cells-block_size + off_x + 1] + = 1 #平均渐变 梯度/ = cell_count #使用Matplotlib绘制HOGs #角度为360 / nbins *方向 color_bins = 5 plt.pcolor(gradients) plt.gca()。invert_yaxis() plt.gca()。set_aspect('equal', Adjustable ='box')plt.colorbar()plt.show() cv2.destroyAllWindows()
该图像显示了如何将输入图像表示为HOG表示。
HAAR级联分类器
如前所述,我们可以从图像中提取特征,然后使用这些特征对对象进行分类或检测。
什么是HAAR级联分类器?
一种将Haar特征输入到一系列分类器(级联)中以识别图像中的对象的对象检测方法。他们经过训练可以识别一种类型的物体,但是,我们可以并行使用其中的几种物体,例如一起检测眼睛和面部。
HAAR分类器说明:
HAAR分类器使用大量正图像(即存在对象的
图像)和负图像(即不存在对象的图像)进行训练。
有了这些图像后,我们便可以使用矩形块的滑动窗口提取特征。这些特征(HAAR特征)是单值的,是通过从黑色矩形中减去白色矩形下的像素强度总和来计算的。
但是,即使对于24 x 24像素的基本窗口(生成了180,000个特征),这也是可笑的数目。
因此,研究人员设计了一种称为“积分图像”的方法,该方法使用四个数组引用对其进行计算。但是,它们仍然具有180,000个功能,并且大多数功能没有增加任何实际价值。
然后,借助Freund&Schapire的AdaBoost,使用Boosting来确定最有用的功能,并在图像中找到最有用的功能。提升是我们使用弱分类器构建强分类器的过程,只需对不正确的分类分配较重的加权惩罚即可。将180,000个功能减少到6000个,这仍然是一个很大的功能。
在这6000个功能中,某些功能会比其他功能提供更多信息。因此,如果我们使用信息量最大的功能来首先检查该区域是否可能有面孔(误报就没什么大不了了)。这样做消除了一次计算所有6000个特征的需要。这个概念称为“分类器级联” -对于人脸检测,Viola Jones方法使用了38个阶段。
面部和眼睛检测
因此,在获得了有关HAAR级联的一些理论知识之后,我们将最终实现它,以便使事情变得更加清晰,我们将分部分课,首先,我们将检测正面,然后再使用以下方法检测正面眼睛,最后我们将通过网络摄像头实时检测面部和眼睛。
因此,为此,我们将使用OpenCV提供的经过预训练的分类器作为.xml文件,xml表示可扩展标记语言,该语言用于存储大量数据,甚至可以在其上建立数据库。
您可以在此链接上访问这些分类器。
人脸检测
让我们尝试进行正面人脸检测,您可以在此处访问层叠的正面人脸检测器。只需解压缩zip文件即可获取xml文件。
import numpy as np import cv2 #我们将OpenCV的CascadeClassifier函数指向 #分类器(XML文件格式)的存储位置,请记住将代码和分类器保存在同一文件夹中 face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') #加载我们的图像然后将其转换为灰度 图像= cv2.imread('Trump.jpg') 灰色= cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) #我们的分类器将检测到的脸部的ROI作为元组返回 #存储左上角坐标和右下角的坐标 #返回列表列表,这些列表是检测到的不同脸部的位置。 faces = face_cascade.detectMultiScale(gray,1.3,5) #如果未检测到脸部,则face_classifier返回, 如果faces为() ,则返回空元组:print(“找不到脸部”) #我们遍历faces数组,并 在 (x,y,w, h)在人脸中: cv2.rectangle(image,(x,y),(x + w,y + h),(127,0,255),2) cv2.imshow('人脸检测',图像) cv2.waitKey( 0) cv2.destroyAllWindows()
现在,将面部和眼睛检测结合在一起,您可以在同一zip文件中访问眼睛检测器的级联。
导入numpy作为np 导入cv2 face_classifier = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier('haarcascade_eye.xml') img = cv2.imread('Trump.jpg') 灰色= cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = face_classifier.detectMultiScale(gray,1.3,5) #如果未检测到面孔,则face_classifier返回, 如果面孔为()则为 空元组:print(“ No Face Found”) for(x,y,w,h ): cv2.rectangle(img,(x,y),(x + w,y + h),(127,0,255),2) cv2.imshow('img',img) roi_gray =灰色 roi_color = img 眼睛= eye_classifier.detectMultiScale(roi_gray) cv2.waitKey(0) for(ex,ey,ew,eh)在眼睛中: cv2.rectangle(roi_color,(ex,ey),(ex + ew,ey + eh),(255,255,0),2) cv2.imshow('img',img) cv2.waitKey(0) cv2.destroyAllWindows( ) cv2.waitKey(0)
所以这个代码是一样多的,对于人脸检测的代码,但在这里,我们增加了眼瀑布和方法检测到它们,你可以看到我们选择了灰色缩放脸的版本作为参数 detectMultiScale 为眼睛,这使我们减少了计算量,因为我们仅在该区域仅检测眼睛。
实时面部和眼睛检测
因此,到目前为止,我们已经完成了面部和眼睛检测,现在让我们使用来自网络摄像头的实时视频流实现相同的功能。在此,我们将对面部和眼睛进行相同的检测,但是这次我们将对网络摄像头的实时流进行检测。在大多数应用程序中,您会发现自己的脸部周围有一个高亮显示的方框,但是在这里我们做了一些不同的事情,您会发现自己的脸部被裁剪掉了,而眼睛只能在其中识别出来。
因此,在这里,我们同时导入了面部和眼睛分类器,并定义了用于进行面部和眼睛检测的所有处理的函数。之后,开始网络摄像头流,并调用了面部检测器功能以检测面部和眼睛。我们在人脸检测器功能中定义的参数是实时网络摄像头流中的连续图像
import cv2 import numpy as np face_classifier = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier('haarcascade_eye.xml') def face_detector(img,size = 0.5): #将图像转换为灰度 灰度= cv2.cvtColor (img,cv2.COLOR_BGR2GRAY)人 脸= face_classifier.detectMultiScale(gray,1.3,5) 如果人脸是(): 返回人 脸中(x,y,w,h)的 img :x = x-50 w = w + 50 y = y-50 h = h + 50 cv2.rectangle(img,(x,y),(x + w,y + h),(255,0,0),2) roi_gray =灰色 roi_color = img 眼睛= eye_classifier.detectMultiScale(roi_gray) 用于(ex,ey,ew,eh)的眼睛: cv2.rectangle(roi_color,(ex,ey),(ex + ew,ey + eh),(0,0,255),2)roi_color = cv2.flip(roi_color,1)return roi_color cap = cv2.VideoCapture(0)而True:ret,frame = cap.read()cv2.imshow('Our Face Extractor',face_detector(frame))如果cv2.waitKey(1)== 13:#13是Enter键中断cap.release()cv2.destroyAllWindows()
调整级联分类器
在detectMultiScale内部定义的除输入图像之外的参数具有以下含义
ourClassifier。detectMultiScale(输入图像,比例因子,最小邻域)
- 比例因子 指定每次缩放时减少多少图像尺寸。例如在人脸检测中,我们通常使用1.3。这意味着我们在每次缩放图像时都会将其减少30%。较小的值(例如1.05)将需要更长的时间来计算,但会提高检测率。
- 最小邻居 数指定每个潜在窗口应具有的邻居数,以将其视为肯定检测。通常设置在3-6之间。它用作灵敏度设置,低值有时会检测到单个面部上的多个面部。高值将确保较少的误报,但您可能会错过一些面孔。
视频中的汽车和行人检测
现在,我们将使用HAAR级联来检测视频中的行人和汽车,但是在没有视频正在加载且代码编译没有错误的情况下,您需要执行以下步骤:
如果运行代码后没有视频加载,则可能需要 从 以下位置复制我们的 opencv_ffmpeg.dl : opencv \ sources \ 3rdparty \ ffmpeg,将其粘贴到 安装了python的位置,例如 C:\ Anaconda2
复制后,您需要根据使用的OpenCV版本重命名文件。例如,如果您使用的是OpenCV 2.4.13,则将文件重命名为:opencv_ffmpeg2413_64.dll 或opencv_ffmpeg2413.dll(如果您使用的是使用X86机器)opencv_ffmpeg310_64.dll 或opencv_ffmpeg310.dll(如果您使用的是X86机器)
要查找python.exe的安装位置,只需运行这两行代码,它将打印python的安装位置。
导入sys 打印(sys.executable)
现在,如果您已成功完成这些步骤,那么让我们转到用于行人检测的代码,
您可以从此处附加的zip文件中获取用于行人检测的级联。
import cv2 import numpy as np #创建我们的身体分类器 body_classifier = cv2.CascadeClassifier('haarcascade_fullbody.xml') #启动视频文件的视频捕获,这里我们使用的视频文件中将检测到行人 cap = cv2.VideoCapture( 'walking.avi') # 在cap.isOpened() 成功加载视频后循环播放:#读取视频 ret 的每一帧,frame = cap.read()#在这里,我们将帧调整为其大小的一半,我们正在努力加快分类速度, 因为较大的图像具有更多可滑动的窗口,因此总的来说,我们降低了分辨率 视频数量减半(即0.5表示的一半),我们还使用了更快的插值方法,即#interlinear frame = cv2.resize(frame,None,fx = 0.5,fy = 0.5,插值= cv2.INTER_LINEAR) 灰色= cv2。 cvtColor(frame,cv2.COLOR_BGR2GRAY) #将帧传递到我们的身体分类器 bodys = body_classifier.detectMultiScale(gray ,1.2,3)#提取 在 cv2中 为(x,y,w,h)标识的任何物体的边界框。矩形(frame,(x,y),(x + w,y + h),(0,255,255 ),2)cv2.imshow('Pedestrians',frame)如果cv2.waitKey(1)== 13 :#13是Enter键 中断 cap.release() cv2.destroyAllWindows()
成功检测视频中的行人之后,让我们转到用于汽车检测的代码,您可以从此处获取用于行人检测的级联。
import cv2 import time import numpy as np #创建我们的身体分类器 car_classifier = cv2.CascadeClassifier('haarcascade_car.xml') #启动视频文件 cap = cv2.VideoCapture('cars.avi')的 视频捕获#视频成功后循环加载 而cap.isOpened(): time.sleep(0.05)# 读取第一帧 RET,帧= cap.read() 灰色= cv2.cvtColor(帧,cv2.COLOR_BGR2GRAY) #通帧我们的车分类 车= car_classifier.detectMultiScale(gray,1.4,2) #为汽车中确定 为(x,y,w,h)的 任何物体提取边界框:cv2.rectangle(frame,(x,y),(x + w,y + h ),(0、255、255),2) cv2.imshow('Cars',frame) 如果cv2.waitKey(1)== 13:#13是Enter键 中断 cap.release() cv2.destroyAllWindows()
您已经注意到我们添加了 time.sleep(.05) ,这只是帧速率的延迟,因此您可以确认所有汽车均已正确识别,也可以通过在其中添加注释标签来轻松删除它。
本文引用了Rajeev Ratan创建的Udemy上的Python with Deep Learning课程中的Master Computer Vision™OpenCV4 in Python with Deep Learning课程,订阅该课程以了解有关Computer Vision和Python的更多信息。