图片人脸检测——opencv+dlib两种方法
视频人脸检测:https://blog.csdn.net/Lee_01/article/details/89145740
一、使用opencv的haarcascades检测模型
模型下载地址:https://github.com/opencv/opencv/tree/master/data/haarcascades
项目结构:
opencv图像矩阵表示:矩阵左上角为原点(0,0),从左往右为x轴正向,从上往下为y轴正向
代码如下:
import sys
import cv2
import numpy
from PIL import Image, ImageDraw, ImageFont
def _help():
print("Usage:")
print(" python pic_face_detect_cv.py <path of a picture>")
print("For example:")
print(" python pic_face_detect_cv.py pic/yangchaoyue.jpg")
def face_detect(file_path):
color_image = cv2.imread(file_path)
# 图片转换成灰色(去除色彩干扰,让图片识别更准确)
gray_image = cv2.cvtColor(color_image, cv2.COLOR_BGR2GRAY)
# 获取OpenCV人脸识别分类器
detector = cv2.CascadeClassifier("opencv-master/data/haarcascades/haarcascade_frontalface_default.xml")
# 用detector检测人脸
face_rects = detector.detectMultiScale(gray_image, scaleFactor=1.2, minNeighbors=3, minSize=(32, 32))
line_color = (0, 255, 0)
line_width = 2
# 在图片人脸位置上画矩形
if (len(face_rects)) > 0:
for face_rect in face_rects:
x, y, w, h = face_rect # (x,y)是图像矩阵左上角的坐标,w是矩阵的宽,h是矩阵的高
cv2.rectangle(color_image, (x, y), (x + w, y + h), line_color, line_width)
else:
print("没有检测到人脸!")
exit(0)
# 新建一个窗口用于显示图片,第一个参数为窗口名
# 第二个参数默认情况下是WINDOW_AUTOSIZE,如果在图片高清情况下,显示图片窗口很大,电脑屏幕放不下,并且窗口还不能通过拖动鼠标来调整
# WINDOW_NORMAL则可以正常显示图片,并且可以通过鼠标调整图片
color_image = cv2_img_add_text(color_image, "杨超越", 50, 50, (255, 0, 0), 40)
cv2.namedWindow("Image", cv2.WINDOW_NORMAL)
cv2.imshow("Image", color_image)
cv2.waitKey(0) # 点击图像后,按任意键继续
cv2.destroyAllWindows() # 销毁图像窗口
def cv2_img_add_text(img, text, left, top, text_color=(255, 0, 0), text_size=20):
"""
功能:opencv添加中文,解决乱码问题
"""
# 先判断是否为opencv图片类型
if isinstance(img, numpy.ndarray):
# 先将OpenCV图片格式转换成PIL的图片格式
img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
# 使用PIL绘制文字
draw = ImageDraw.Draw(img)
font_text = ImageFont.truetype("font/simsun.ttc", text_size, encoding="utf-8")
draw.text((left, top), text, text_color, font=font_text)
# 再将PIL图片格式转换成OpenCV的图片格式
img = cv2.cvtColor(numpy.asarray(img), cv2.COLOR_RGB2BGR)
return img
if len(sys.argv) == 1 or "-h" in sys.argv or "--help" in sys.argv:
_help()
else:
face_detect(sys.argv[1])
检测效果:
二、使用dlib的shape_predictor_68_face_landmarks模型
该模型能够检测人脸的68个特征点(facial landmarks),定位图像中的眼睛,眉毛,鼻子,嘴巴,下颌线(ROI,Region of Interest)
下颌线[1,17]
左眼眉毛[18,22]
右眼眉毛[23,27]
鼻梁[28,31]
鼻子[32,36]
左眼[37,42]
右眼[43,48]
上嘴唇外边缘[49,55]
下嘴唇外边缘[56,60]
下嘴唇内边缘[61,65]
上嘴唇内边缘[66,68]
- 用途:人脸检测,人脸对齐,换脸,眨眼检测等等
- 模型下载地址:http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2
- 模型检测原理:https://www.pyimagesearch.com/2014/11/10/histogram-oriented-gradients-object-detection/
项目结构:
代码如下:
import sys
import cv2
import dlib
def _help():
print("Usage:")
print(" python pic_face_detect_dlib.py <path of a picture>")
print("For example:")
print(" python pic_face_detect_dlib.py pic/HL.jpg")
def face_detect(file_path):
color_image = cv2.imread(file_path)
gray_image = cv2.cvtColor(color_image, cv2.COLOR_BGR2GRAY) # 将彩色图片转换为灰色图片,提高人脸检测的准确率
# 也可以不用转换灰色图像,但是BGR要转换为RGB
# color_image = cv2.imread(file_path, cv2.IMREAD_COLOR)
# B, G, R = cv2.split(color_image) # 分离三个颜色通道
# color_image = cv2.merge([R, G, B]) # 融合三个颜色通道生成新图片
# 人脸检测器
detector = dlib.get_frontal_face_detector()
# 特征点检测器
predictor = dlib.shape_predictor("model/shape_predictor_68_face_landmarks.dat")
# 检测人脸
faces = detector(gray_image, 1) # The 1 in the second argument indicates that we should upsample the image 1 time.
# 调用训练好的卷积神经网络(cnn)模型进行人脸检测
# cnn_face_detector = dlib.cnn_face_detection_model_v1('model/mmod_human_face_detector.dat')
# faces = cnn_face_detector(gray_image, 1)
for face in faces:
# 用矩形框住人脸
left = face.left()
top = face.top()
right = face.right()
bottom = face.bottom()
cv2.rectangle(color_image, (left, top), (right, bottom), (0, 255, 0), 2)
# 寻找人脸的68个标定点
shape = predictor(color_image, face)
# 遍历所有点,打印出其坐标,并圈出来
for idx, pt in enumerate(shape.parts()):
pt_pos = (pt.x, pt.y)
cv2.circle(color_image, pt_pos, 2, (0, 0, 255), -1) # 参数分别为:图像,圆心坐标,半径,颜色,线条粗细 # HL
# 利用cv2.putText输出1-68
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(color_image, str(idx + 1), pt_pos, font, 0.3, (255, 0, 0), 1, cv2.LINE_AA)
# 位置,字体,大小,颜色,字体厚度
cv2.namedWindow("Image", cv2.WINDOW_NORMAL)
cv2.imshow("Image", color_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
if len(sys.argv) == 1 or "-h" in sys.argv or "--help" in sys.argv:
_help()
else:
face_detect(sys.argv[1])
检测效果:
参考博客:
http://www.cnblogs.com/vipstone/p/8884991.html
http://www.cnblogs.com/vipstone/p/8998249.html
http://www.cnblogs.com/vipstone/p/8964656.html
https://www.pyimagesearch.com/2017/04/03/facial-landmarks-dlib-opencv-python/