在图像中识别特定对象被称为对象检测。这项任务可以通过多种技术实现,但本文将使用预训练的XML文件和Haar级联。这是执行对象检测的最简单方法之一。
Haar级联曾被用于低边缘设备上的对象检测,并且是OpenCV中最流行的对象检测算法之一。由于Haar级联的计算量不大,因此它在计算能力有限的小设备上非常受欢迎。本文将介绍如何使用Haar级联进行人脸检测。
本文是作为“数据科学博客马拉松”的一部分发布的。
Haar级联是一种基于特征的对象检测算法,用于从图像中检测对象。级联函数在许多正负图像上进行训练以进行检测。
该算法不需要大量的计算,并且可以实时运行。可以为自定义对象(如动物、汽车、自行车等)训练自己的级联函数。
Haar级联不能用于面部识别,因为它只识别匹配的形状和大小。
Haar级联使用级联函数和级联窗口。它尝试计算每个窗口的特征,并对正负进行分类。如果窗口可能是对象的一部分,则为正,否则为负。
Haar级联可以被理解为一个二元分类器。它为可能成为对象一部分的级联窗口分配正号,为不能成为对象一部分的窗口分配负号。
Haar级联可以实时工作,速度非常快。
与现代对象检测算法相比,Haar级联的准确性不高。
它检测到许多误报。这可以在一定程度上进行调整,但不能完全消除。
实现起来非常简单。
Haar级联的最大缺点是其误报检测。
有许多预训练的Haar级联文件,使实现变得非常容易。也可以训练自己的Haar级联,但这需要大量的数据进行训练。
OpenCV库在GitHub上管理一个,包含所有流行的预训练Haar级联文件,可以用于各种对象检测任务,例如:
Haar级联将特征存储在XML文件中;这些文件可以直接在OpenCV中加载,用于使用Haar级联进行对象检测。
如果正在使用OpenCV提供的仓库中的任何预训练对象检测,只需要下载预训练的XML文件。
在Python中安装OpenCV可以使用pip包管理器。
pip install opencv-python
# 或者
pip install opencv-contrib-python
在OpenCV中加载Haar级联XML文件。
face_detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
eye_detector = cv2.CascadeClassifier('haarcascade_eye.xml')
一旦XML文件加载,就可以调用检测器函数。
results = face_detector.detectMultiScale(gray_img, scaleFactor=1.15, minNeighbors=5, minSize=(34, 35), flags=cv2.CASCADE_SCALE_IMAGE)
results是检测到的对象周围的边界框坐标(x,y,w,h)列表。
detectMultiScale中的参数:
注意:对于对象检测,必须使用灰度图像,minNeighbors,scaleFactor,其他参数不是必需的。
让以使用预训练的Haar级联进行对象检测的第一个例子为例,将使用Python从图片中检测人脸。
下载用于面部检测的级联文件:。
import numpy as np
import cv2
# 加载Haar级联检测器
face_detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
# 从本地加载图像
img = cv2.imread('team_india.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
results = face_detector.detectMultiScale(gray, 1.3, 5)
对于results中的每个(x,y,w,h),在图片上绘制边界框。
for (x,y,w,h) in results:
cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
results包含图片中边界框的坐标。
detectMultiScale方法仅适用于灰度图像。
cv2.rectangle是OpenCV方法,允许在传递坐标后绘制矩形。
scaleFactor = 1.3,FineTuning参数从1到2。
Haar级联支持层次检测,这意味着Haar级联能够在单个帧内以层次方式检测多个对象。
假设需要检测人的面部和眼睛。要进行此任务,需要遵循以下步骤:
import numpy as np
import cv2
face_detector1 = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
eye_detector1 = cv2.CascadeClassifier('haarcascade_eye.xml')
img = cv2.imread('human.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces_result = face_detector.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces_result:
img = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
roi_gray = gray[y:y+h, x:x+w]
roi_color = img[y:y+h, x:x+w]
eyes = eye_detector.detectMultiScale(roi_gray)
for (ex,ey,ew,eh) in eyes:
cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
使用Haar级联的对象检测可以用于OpenCV视频流,只需要在OpenCV中读取视频或相机输入,其余的事情将与单帧相同。由于其计算要求轻,Haar级联每秒运行良好。
将读取OpenCV视频摄像头输入以实时获取图像。
import cv2
face_detector1 = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
eye_detector1 = cv2.CascadeClassifier('haarcascade_eye.xml')
# 读取输入图像
cap = cv2.VideoCapture(0)
while cap.isOpened()
_, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_detector1.detectMultiScale(gray,1.1, 4)
for (x,y, w, h) in faces:
cv2.rectangle(frame, pt1 = (x,y),pt2 = (x+w, y+h), color = (255,0,0),thickness = 3)
roi_gray = gray[y:y+h,x:x+w]
roi_color = frame[y:y+h, x:x+w]
eyes = eye_detector1.detectMultiScale(roi_gray)
for (ex,ey, ew, eh) in eyes:
cv2.rectangle(roi_color, (ex,ey), (ex+ew, ey+eh), (0,255,0), 5)
cv2.imshow("window", frame)
if cv2.waitKey(1) & 0xFF == ord('q')
break
frame.release()
眼睛和面部的边界框将是实时的,并且会随着每一帧而变化。
Haar级联仍然非常受欢迎,用于一些对象,如面部、汽车等,这些对象容易区分。Haar级联不能用于深层对象检测,如谷物类型等。
Haar级联算法有一些限制:
在本文中,讨论了Haar级联的工作原理以及如何使用Python中的OpenCV实现Haar级联进行对象检测。使用了预训练的Haar级联文件进行面部和眼睛检测,然后实时执行相同的操作。