python 现成的人脸检测

前言

本文是利用训练好的模型 快速运行人脸识别与人脸关键点识别

分为两部分:利用mctnn的tensorflow模型,和利用opencv自带的级联分类器进行人脸检测

目录

cascade opencv 识别

mtcnn识别


cascade opencv 识别

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

或者在安装完python-opencv的盘里搜这几个文件

classifier_face = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml")
classifier_eye = cv2.CascadeClassifier("haarcascade_eye.xml")
classifier_mouth=cv2.CascadeClassifier("haarcascade_mcs_mouth.xml")

# !/usr/bin/env python
# coding=utf-8
import os
import numpy
from PIL import Image, ImageDraw
import cv2
#created by chenfenyu 2018.3.20


playCapture = cv2.VideoCapture(0)
#获取外接摄像头
#eye = cv2.imread("eye.png")
#mouth = cv2.imread("mouth.png")
size = (int(playCapture.get(cv2.CAP_PROP_FRAME_WIDTH) + 0.5), int(playCapture.get(cv2.CAP_PROP_FRAME_HEIGHT) + 0.5))
#获取摄像头返回的宽和高

#fourcc = cv2.VideoWriter_fourcc(*'mp4v')
#video = cv2.VideoWriter("/Users/funny/Downloads/a.avi", fourcc, 5, size)


classifier_face = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml")
classifier_eye = cv2.CascadeClassifier("haarcascade_eye.xml")
classifier_mouth=cv2.CascadeClassifier("haarcascade_mcs_mouth.xml")
while playCapture.isOpened():
    success, img = playCapture.read()
    if success:
        '''第一个参数ret的值为True或False,代表有没有读到图片
           第二个参数是frame,是当前截取一帧的图片
        '''
        faceRects_face = classifier_face.detectMultiScale(img, 1.2, 2, cv2.CASCADE_SCALE_IMAGE, (20, 20))
        #检测器:detectMultiScale参数(图像,每次缩小图像的比例,匹配成功所需要的周围矩形框的数目,检测的类型,匹配物体的大小范围)
        key = cv2.waitKey(1)
        #键盘等待
        if len(faceRects_face) > 0:
            #检测到人脸
            for faceRect_face in faceRects_face:
                x, y, w, h = faceRect_face
                #获取图像x起点,y起点,宽,高
                h1=int(float(h/1.5))
                #截取人脸区域高度的一半位置,以精确识别眼睛的位置
                intx=int(x)
                inty=int(y)
                intw=int(w)
                inth=int(h)
                #转换类型为int,方便之后图像截取
                my = int(float(y + 0.7 * h))
                #截取人脸区域下半部分左上角的y起点,以精确识别嘴巴的位置
                mh = int(0.4 * h)
                #截取人脸区域下半部分高度,以精确识别嘴巴的位置
                img_facehalf = img[inty:(inty+h1), intx:intx+intw]
                img_facehalf_bottom = img[my:(my + mh), intx:intx + intw]
                '''img获取坐标为,【y,y+h之间(竖):x,x+w之间(横)范围内的数组】
                   img_facehalf是截取人脸识别到区域上半部分
                   img_facehalf_bottom是截取人脸识别到区域下半部分
                '''
                cv2.rectangle(img, (int(x), my), (int(x) + int(w), my + mh), (0, 255, 0), 2, 0)
                '''矩形画出区域 rectangle参数(图像,左顶点坐标(x,y),右下顶点坐标(x+w,y+h),线条颜色,线条粗细)
                    画出人脸识别下部分区域,方便定位
                '''
                faceRects_mouth = classifier_mouth.detectMultiScale(img_facehalf_bottom, 1.1, 1, cv2.CASCADE_SCALE_IMAGE, (5, 20))
                #嘴巴检测器
                if len(faceRects_mouth) > 0:
                    for faceRect_mouth in faceRects_mouth:
                        xm1, ym1, wm1, hm2 = faceRect_mouth
                        cv2.rectangle(img_facehalf_bottom, (int(xm1), int(ym1)), (int(xm1) + int(wm1), int(ym1) + int(hm2)), (0,0, 255), 2, 0)
                        try:
                            img_mx = cv2.resize(mouth, (wm1, hm2), interpolation=cv2.INTER_CUBIC)
                        except:
                            pass
                        #if key == ord('z'):
                        #    img[my+ym1:(my+ym1+hm2), intx+xm1:(intx + xm1+wm1)] = img_mx
                cv2.rectangle(img, (int(x), int(y)), (int(x) + int(w), int(y) + int(h1)), (0, 255, 0), 2, 0)
                # 画出人脸识别上部分区域,方便定位
                faceRects_eye = classifier_eye.detectMultiScale(img_facehalf, 1.2, 2, cv2.CASCADE_SCALE_IMAGE, (20, 20))
                #检测器识别眼睛
                if len(faceRects_eye) > 0:
                    #检测到眼睛后循环
                    eye_tag = []
                    #定义一个列表存放两只眼睛坐标
                    for faceRect_eye in faceRects_eye:
                        x1, y1, w1, h2 = faceRect_eye
                        cv2.rectangle(img_facehalf, (int(x1), int(y1)), (int(x1) + int(w1), int(y1) + int(h2)), (0, 255, 0), 2, 0)
                        #画出眼睛区域
                        a = ((inty+y1),(inty+y1 + h2), (intx+x1),(intx+x1 + w1))
                        #定义a变量获取眼睛坐标,现在img顶点位置已经改变,需要加上intx和inty的值才可以
                        eye_tag.append(a)
                        #通过append存入数组a中
                    n_eyetag = numpy.array(eye_tag)
                    #存放为ndarray数组类型,输入内容为[[x1 y1 x1+w y1+h][x1 y1 x1+w y1+h]...],后面会获取多维数组的下标来替换数值

                    #if len(faceRects_eye)==2:
                    #    img_ex=cv2.resize(eye,(n_eyetag[0,1]-n_eyetag[0,0], n_eyetag[0,3]-n_eyetag[0,2]),interpolation=cv2.INTER_CUBIC)
                    #    img_ex1 = cv2.resize(eye, (n_eyetag[1, 1] - n_eyetag[1, 0], n_eyetag[1, 3] - n_eyetag[1, 2]), interpolation=cv2.INTER_CUBIC)
                        #if key == ord('p'):
                        #    img[n_eyetag[0,0]:n_eyetag[0,1],n_eyetag[0,2]:n_eyetag[0,3]]=img_ex
                        #    img[n_eyetag[1, 0]:n_eyetag[1, 1], n_eyetag[1, 2]:n_eyetag[1, 3]] = img_ex1
                    #if len(faceRects_eye)==1:
                    #    # 眼睛识别到一个时,替换图片
                    #    img_ex = cv2.resize(eye, (n_eyetag[0, 1] - n_eyetag[0, 0], n_eyetag[0, 3] - n_eyetag[0, 2]), interpolation=cv2.INTER_CUBIC)
                    #    if key == ord('p'):
                    #        img[n_eyetag[0, 0]:n_eyetag[0, 1], n_eyetag[0, 2]:n_eyetag[0, 3]] = img_ex

                #video.write(img)
        cv2.imshow('video', img)
        #显示图片,标题名字为video
        cv2.resizeWindow('video',1280,720)
        #调整窗口大小video为1280*720
        if key == ord('q'):
        #检测到键盘输入q,退出循环
            break

#video.release()
#不再录制视频
cap.release()
cv2.destroyAllWindows()

 

mtcnn识别

模型下载:https://github.com/imistyrain/MTCNN/blob/master/tensorflow/mtcnn.pb

import argparse,cv2
#from mtcnn import MTCNN
import tensorflow as tf
class MTCNN:

    def __init__(self, model_path, min_size=40, factor=0.709, thresholds=[0.6, 0.7, 0.7]):
        self.min_size = min_size
        self.factor = factor
        self.thresholds = thresholds

        graph = tf.Graph()
        with graph.as_default():
            with open(model_path, 'rb') as f:
                graph_def = tf.GraphDef.FromString(f.read())
                tf.import_graph_def(graph_def, name='')
        self.graph = graph
        config = tf.ConfigProto(
            allow_soft_placement=True,
            intra_op_parallelism_threads=4,
            inter_op_parallelism_threads=4)
        config.gpu_options.allow_growth = True
        self.sess = tf.Session(graph=graph, config=config)

    def detect(self, img):
        feeds = {
            self.graph.get_operation_by_name('input').outputs[0]: img,
            self.graph.get_operation_by_name('min_size').outputs[0]: self.min_size,
            self.graph.get_operation_by_name('thresholds').outputs[0]: self.thresholds,
            self.graph.get_operation_by_name('factor').outputs[0]: self.factor
        }
        fetches = [self.graph.get_operation_by_name('prob').outputs[0],
                  self.graph.get_operation_by_name('landmarks').outputs[0],
                  self.graph.get_operation_by_name('box').outputs[0]]
        prob, landmarks, box = self.sess.run(fetches, feeds)
        return box, prob, landmarks
def test_image(imgpath):
    mtcnn = MTCNN('./mtcnn.pb')
    img = cv2.imread(imgpath)

    bbox, scores, landmarks = mtcnn.detect(img)

    print('total box:', len(bbox))
    for box, pts in zip(bbox, landmarks):
        box = box.astype('int32')
        img = cv2.rectangle(img, (box[1], box[0]), (box[3], box[2]), (255, 0, 0), 3)

        pts = pts.astype('int32')
        for i in range(5):
            img = cv2.circle(img, (pts[i+5], pts[i]), 1, (0, 255, 0), 2)
    cv2.imshow('image', img)
    cv2.waitKey()

def test_camera(index=0):
    mtcnn = MTCNN('./mtcnn.pb')
    cap=cv2.VideoCapture(index)
    while True:
        ret,img=cap.read()
        if not ret:
            break
        bbox, scores, landmarks = mtcnn.detect(img)
        #print('total box:', len(bbox))
        for box, pts in zip(bbox, landmarks):
            box = box.astype('int32')
            img = cv2.rectangle(img, (box[1], box[0]), (box[3], box[2]), (255, 0, 0), 3)
            pts = pts.astype('int32')
            for i in range(5):
                img = cv2.circle(img, (pts[i+5], pts[i]), 1, (0, 255, 0), 2)
        cv2.imshow('img', img)
        key = cv2.waitKey(1)
        if key ==ord('q'):
            break

if __name__ == '__main__':
    #test_image()
    test_camera()

参考:https://www.cnblogs.com/fightccc/p/8616068.html

扫描二维码关注公众号,回复: 11314092 查看本文章

猜你喜欢

转载自blog.csdn.net/ptgood/article/details/96743885
今日推荐