一、基于OpenCV的haar分类器实现笑脸检测
1、Haar分类器介绍
🚀Haar分类器是一种基于机器学习的目标检测算法,它使用Haar特征描述图像中的目标。Haar特征是基于图像亮度的局部差异计算得出的,可以用来描述目标的边缘、角落和线条等特征。
使用Haar分类器进行目标检测的步骤大致如下:
🍎收集训练数据:需要大量包含目标的正样本图像和不包含目标的负样本图像。
🍌提取Haar特征:使用OpenCV等图像处理工具提取每个样本图像的Haar特征,并将其保存为向量形式。
🚗训练分类器:使用机器学习算法(如Adaboost)训练Haar分类器,使其能够准确地区分包含目标的图像和不包含目标的图像。opencv训练自己的xml分类器以及如何获取opencv_createsamples.exe和opencv_traincascade.exe_Lizaozao96的博客-CSDN博客
🍊目标检测:使用训练好的Haar分类器对新的图像进行检测。首先在图像中使用滑动窗口将图像划分为小块,在每个小块上使用分类器进行分类,如果检测到包含目标的区域,则将其输出为检测结果。
我们可以调用OpenCV训练好的分类器和自带的检测函数检测人脸、人眼等。
2、haar分类器的静态使用(处理图片)
首先只需要安装cv2的库就能玩啦~
pip install opencv-python
在以下代码中,我们首先加载了一个已经训练好的Haar分类器(这里使用的是检测人脸的分类器),然后将待检测的图像转换为灰度图像,并使用detectMultiScale方法对图像进行目标检测。如果检测到目标,则在目标所在位置绘制一个矩形框,并显示检测结果。
python
import cv2
# 加载分类器
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
# 加载图像
img = cv2.imread('lena.jpg')
# 将图像转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 使用分类器进行人脸检测
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
# 在检测到的人脸上绘制矩形框
for (x,y,w,h) in faces:
cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
# 显示检测结果
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果如下:
以上就为对lena"长老"的图片简单操作。调用了 haarcascade_frontalface_default.xml模型文件实现了人脸框检测。
3、haar分类器的动态使用(对摄像头视频进行处理)
首先我们需要准备三个文件,分别是 'haarcascade_frontalface_default.xml、 haarcascade_eye.xml和 haarcascade_smile.xml分别用来识别人脸、眼睛和笑容。
可以使用上述代码的加载分类器方式,也可以将cv2包里面的模型文件拿出来供我们复用,这里我使用的是虚拟环境,haar的一系列模型文件都在 venv\Lib\site-packages\cv2\data目录下。
接下来我用直接传入模型文件的方式来使用这三个方法(画出脸框、眼眶和嘴框),并结合电脑摄像头,代码如下:
python
import cv2
haar_front_face_xml = 'haarcascade_frontalface_default.xml'
haar_eye_xml = 'haarcascade_eye.xml'
smileharr = 'haarcascade_smile.xml'
# 视频中的人脸检测
def DynamicDetect():
'''
打开摄像头,读取帧,检测帧中的人脸,扫描检测到的人脸中的眼睛,对⼈脸绘制蓝蓝色的矩形框,对人眼和笑绘制绿⾊的矩形框
'''
# 创建3个级联分类器 加载3个 .xml 分类器⽂件
face_cascade = cv2.CascadeClassifier(haar_front_face_xml)
eye_cascade = cv2.CascadeClassifier(haar_eye_xml)
smile_cascade = cv2.CascadeClassifier(smileharr)
# 打开摄像头
camera = cv2.VideoCapture(0)
cv2.namedWindow('Dynamic')
while True:
# 读取1帧图像
ret, frame = camera.read()
# 判断图片读取成功?
if ret:
gray_img = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 人脸检测
faces = face_cascade.detectMultiScale(gray_img, 1.3, 5)
for (x, y, w, h) in faces:
# 在原图像上绘制矩形
cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)
roi_gray = gray_img[y:y + h, x:x + w]
# 眼睛和笑脸检测
eyes = eye_cascade.detectMultiScale(roi_gray, 1.03, 5, 0, (40, 40))
smile = smile_cascade.detectMultiScale(roi_gray, 1.03, 5, 0, (40, 40))
for (ex, ey, ew, eh) in eyes:
cv2.rectangle(frame, (ex + x, ey + y), (x + ex + ew, y + ey + eh), (0, 255, 0), 2)
for (sx, sy, sw, sh) in smile:
cv2.rectangle(frame, (sx + x, sy + y), (x + sx + sw, y + sy + sh), (0, 255, 0), 2)
cv2.imshow('Dynamic', frame)
# 如果按下q键则退出
if cv2.waitKey(100) & 0xff == ord('q'):
break
camera.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
DynamicDetect()