图片人脸检测——opencv+dlib两种方法

视频人脸检测:https://blog.csdn.net/Lee_01/article/details/89145740

一、使用opencv的haarcascades检测模型

模型下载地址:https://github.com/opencv/opencv/tree/master/data/haarcascades

本项目直接下载opencv的源码,源码中就包含了模型文件

项目结构:

opencv图像矩阵表示:矩阵左上角为原点(0,0),从左往右为x轴正向,从上往下为y轴正向

代码如下:

import sys
import cv2
import numpy as np
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(model_path, file_path):
    color_image = cv2.imread(file_path)
    # 图片转换成灰色(去除色彩干扰,让图片识别更准确)
    gray_image = cv2.cvtColor(color_image, cv2.COLOR_BGR2GRAY)

    # 获取OpenCV人脸识别分类器
    detector = cv2.CascadeClassifier(model_path)
    # 用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, np.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(np.asarray(img), cv2.COLOR_RGB2BGR)
    return img


MODEL_PATH = "opencv-master/data/haarcascades/haarcascade_frontalface_default.xml"
if len(sys.argv) == 1 or "-h" in sys.argv or "--help" in sys.argv:
    _help()
else:
    face_detect(MODEL_PATH, sys.argv[1])

检测效果:

二、使用dlib的shape_predictor_68_face_landmarks模型

该模型能够检测人脸的68个特征点(facial landmarks),定位图像中的眼睛,眉毛,鼻子,嘴巴,下颌线(ROI,Region of Interest)

Facial feature detection is also referred to as “facial landmark detection”, “facial keypoint detection” and “face alignment” in the literature

点击查看图像来源

下颌线[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,本项目把下载好的模型文件放在model目录中

模型检测原理: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")
    # 检测人脸
    # The 1 in the second argument indicates that we should upsample the image 1 time.
    faces = detector(gray_image, 1)  

    # 调用训练好的卷积神经网络(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)
            # 参数分别为:图像,圆心坐标,半径,颜色,线条粗细   # HL
            cv2.circle(color_image, pt_pos, 2, (0, 0, 255), -1)  
            # 利用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/

  • 4
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值