目录
使用opencv进行人脸、眼睛、嘴的检测。
1 xml文件
- 方法① 下载
地址:https://github.com/opencv/opencv/tree/master/data/haarcascades
点击haarcascade_frontalface_default.xml文件
对着Raw右键,选择“链接另存为”,选择代码所在的路径即可,就可以下载这个文件啦。
其他文件的下载方式与上述文件的方式类似。
- 方法② 文件路径
如果已经安装OpenCV,那么可以在安装OpenCV的环境中找到这个文件。
/anaconda3/envs/python/lib/python/site-packages/cv2/data/haarcascade_frontalface_default.xml
具体的情况按照实际的去对照哈。
如果没有安装OpenCV的话,可以使用如下命令安装:
pip install opencv-python
找对应文件路径的方法如上。
2 涉及的函数
CascadeClassifier是Opencv中做人脸检测的一个级联分类器,既可以使用Haar特征,也可以使用LBP特征。要使用Haar级联分类器进行人脸检测,首先需要加载相应的分类器文件,比如haarcascade_frontalface_default.xml。然后,将图像转换为灰度图像,并使用detectMultiScale()函数进行人脸的检测操作。
- cv2.CascadeClassifier.detectMultiScale()函数
objects = cv2.CascadeClassifier.detectMultiScale( image[,scaleFactor[, minNeighbors[, flags[, minSize[, maxSize]]]]] )
输入:
①image:输入图像
②scaleFactor:搜索窗口的缩放比例大小。
③minNeighbors:默认值为3,意味着有3个以上的检测标记存在时,才认为人脸存在。如果希望提高检测的准确率,可以将该值设置的更大,但同时可能会让一些人脸无法被检测到。小于该值的目标将被忽略。
④flags:该参数通常被省略。
⑤minSize:目标的最小尺寸,小于这个尺寸的目标将被忽略。
⑥maxSize:最大目标的尺寸。大于该值的目标将被忽略。
返回:
①objects:目标对象的矩形框组。
3 实践
- 代码
import cv2
import matplotlib.pyplot as plt
import math
def dealImg(img):
b, g, r = cv2.split(img)
img_rgb = cv2.merge([r, g, b])
return img_rgb
def dealImageResult(img_path):
im = cv2.imread(img_path)
img = im.copy()
# 加载预训练的人脸级联分类器
face_detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
eye_detector = cv2.CascadeClassifier('haarcascade_eye.xml')
smile_detector = cv2.CascadeClassifier('haarcascade_smile.xml')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_detector.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=2, minSize=(125, 125))
label = f'OpenCV Haar Detected {str(len(faces))} faces'
if len(faces) > 1:
label = f'OpenCV Haar Detected {str(len(faces))} faces'
elif len(faces) == 1:
label = f'OpenCV Haar Detected {str(len(faces))} face'
else:
lable = " "
cv2.putText(img, label, (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 0), 2)
for (x, y, w, h) in faces:
# cv2.rectangle(img, (x, y), (x+w, y+h), (255, 255, 0), 1)
# r = int(math.sqrt(w/2*w/2 + h/2*h/2))
cv2.circle(img, (int(x+w/2), int(y+h/2)), int(h/2), (255, 255, 0), 2)
# 人脸切分
head = gray[y:y+h, x:x+w]
h_temp = int(h*0.6)
head_up = head[0:h_temp]
head_down = head[h_temp:]
# 检测眼睛
eyes = eye_detector.detectMultiScale(head_up, scaleFactor=1.2, minNeighbors=3, minSize=(10, 10))
for (ex, ey, ew, eh) in eyes:
cv2.rectangle(img, pt1=(ex+x, ey+y), pt2=(ex+ew+x, ey+eh+y), color=[0, 255, 0], thickness=2)
smile_result = smile_detector.detectMultiScale(head_down, scaleFactor=1.2, minNeighbors=3, minSize=(10, 10), maxSize=(80, 80))
for mx, my, mw, mh in smile_result:
cv2.rectangle(img, pt1=(mx+x, my+y+h_temp), pt2=(mx+mw+x, my+mh+y+h_temp), color=[255, 0, 0], thickness=2)
fig = plt.figure(figsize=(10, 10))
im = dealImg(im)
img = dealImg(img)
titles = ["img", "result"]
images = [im, img]
for i in range(2):
plt.subplot(1, 2, i + 1), plt.imshow(images[i], "gray")
plt.title("{}".format(titles[i]), fontsize=20, ha='center')
plt.xticks([]), plt.yticks([])
# plt.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=0.3, hspace=0)
# plt.tight_layout()
plt.show()
fig.savefig('test_results.jpg', bbox_inches='tight')
if __name__ == '__main__':
dealImageResult("test.jpeg")
pass
- 效果图
前文回顾