python3__深度学习/机器学习__图像识别:OpenCV之级联分类器CascadeClassifier

1.理论说明

Haar-like矩形特征是用于物体检测的数字图像特征。这类矩形特征模板由两个或多个全等的黑白矩形相邻组合而成,而矩形特征值是白色矩形的灰度值的和减去黑色矩形的灰度值的和,矩形特征对一些简单的图形结构,如线段、边缘比较敏感。如果把这样的矩形放在一个非人脸区域,那么计算出的特征值应该和人脸特征值不一样,所以这些矩形就是为了把人脸特征量化,以区分人脸和非人脸。

以Haar特征分类器为基础的对象检测技术是一种非常有效的对象检测技术。它是基于机器学习的,使用大量的正负样本训练得到分类器。

2.重点函数

cv2.CascadeClassifier(path): 加载训练好的人脸识别分类器xml文件

cv2.CascadeClassifier(path).detectMultiScale(image, scaleFactor, minNeighbors): 检测并返回图像中的人脸矩阵列表

s.join(iterator): 以为分隔符链接迭代器中元素

shutil.move(src, dst, copy_function=copy2):将图像src移动到dst,相当于linux中的mv命令

3.程序

def readPicSaveFace(sourcePath, targetPath, invalidPath, *suffix):
    """
    从源路径中读取所有图片放入一个list,然后逐一进行检查,把其中的脸扣下来,存储到目标路径中
    :param sourcePath: 源路径
    :param targetPath: 目标路径
    :param invalidPath: 未识别出脸的图片存放路径
    :param suffix: 图片格式
    :return:
    """
    try:
        # 获取图片绝对路径
        ImagePaths = getAllPath(sourcePath, *suffix)

        count = 1

        # 加载人脸识别分类器
        # haarcascade_frontalface_alt.xml为库训练好的分类器文件,下载opencv,安装目录中可找到
        face_cascade = cv2.CascadeClassifier(r'E:\a_test\haarcascade_frontalface_alt2.xml')

        for imagePath in ImagePaths:
            img = cv2.imread(imagePath, cv2.IMREAD_GRAYSCALE)
            if type(img) != str:
                # 检测并返回图像中的人脸矩阵列表
                # 矩形区域左顶点对应x和y, 矩形区域的宽w, 矩形区域的高h
                faces = face_cascade.detectMultiScale(img, 1.01, 8)

                if len(faces):
                    for (x, y, w, h) in faces:
                        # 检查人脸像素,去除小于80像素的人脸
                        if w >= 80 and h >= 80:
                            # 生成文件名
                            listStr = [str(int(time.time())), str(count)]
                            fileName = '_'.join(listStr)  # s.join(iterator):以为分隔符链接迭代器中元素

                            # 扩大图片,可根据坐标调整
                            # img.shape[0]:height
                            # img.shape[1]:width
                            X = int(x * 0.5)
                            W = min(int((x + w) * 1.2), img.shape[1])
                            Y = int(y * 0.3)
                            H = min(int((y + h) * 1.4), img.shape[0])

                            # 重构矩形图片,并存储
                            f = cv2.resize(img[Y:H, X:W], (W - X, H - Y))
                            cv2.imwrite(targetPath + os.sep + '%s.jpg' % fileName, f)
                            count += 1
                            print(imagePath + "have face")
                else:
                    # 将未检测到人脸的图片移出
                    shutil.move(imagePath, invalidPath)
    except IOError:
        print("Error")

    else:
        print('Find ' + str(count - 1) + ' faces to Destination ' + targetPath)

4.完整人脸识别并扣取的程序

# ! /usr/bin/env python
# coding:utf-8
# python interpreter:3.6.2
# author: admin_maxin
# !/usr/bin/env python
# -*-coding:utf8-*-
import os
import cv2
import time
import shutil


def getAllPath(dirpath, *suffix):
    """
    获取文件夹下各图片路径
    :param dirpath: 文件路径
    :param suffix:  图片格式
    :return:
    """
    PathArray = []

    # 遍历文件树
    for r, ds, fs in os.walk(dirpath):
        # 生成文件绝对路径
        for fn in fs:
            if os.path.splitext(fn)[1] in suffix:
                fname = os.path.join(r, fn)
                PathArray.append(fname)
    return PathArray


def readPicSaveFace(sourcePath, targetPath, invalidPath, *suffix):
    """
    从源路径中读取所有图片放入一个list,然后逐一进行检查,把其中的脸扣下来,存储到目标路径中
    :param sourcePath: 源路径
    :param targetPath: 目标路径
    :param invalidPath: 未识别出脸的图片存放路径
    :param suffix: 图片格式
    :return:
    """
    try:
        # 获取图片绝对路径
        ImagePaths = getAllPath(sourcePath, *suffix)

        count = 1

        # 加载人脸识别分类器
        # haarcascade_frontalface_alt.xml为库训练好的分类器文件,下载opencv,安装目录中可找到
        face_cascade = cv2.CascadeClassifier(r'E:\a_test\haarcascade_frontalface_alt2.xml')

        for imagePath in ImagePaths:
            img = cv2.imread(imagePath, cv2.IMREAD_GRAYSCALE)
            if type(img) != str:
                # 检测并返回图像中的人脸矩阵列表
                # 矩形区域左顶点对应x和y, 矩形区域的宽w, 矩形区域的高h
                faces = face_cascade.detectMultiScale(img, 1.01, 8)

                if len(faces):
                    for (x, y, w, h) in faces:
                        # 检查人脸像素,去除小于80像素的人脸
                        if w >= 80 and h >= 80:
                            # 生成文件名
                            listStr = [str(int(time.time())), str(count)]
                            fileName = '_'.join(listStr)  # s.join(iterator):以为分隔符链接迭代器中元素

                            # 扩大图片,可根据坐标调整
                            # img.shape[0]:height
                            # img.shape[1]:width
                            X = int(x * 0.5)
                            W = min(int((x + w) * 1.2), img.shape[1])
                            Y = int(y * 0.3)
                            H = min(int((y + h) * 1.4), img.shape[0])

                            # 重构矩形图片,并存储
                            f = cv2.resize(img[Y:H, X:W], (W - X, H - Y))
                            cv2.imwrite(targetPath + os.sep + '%s.jpg' % fileName, f)
                            count += 1
                            print(imagePath + "have face")
                else:
                    # 将未检测到人脸的图片移出
                    shutil.move(imagePath, invalidPath)
    except IOError:
        print("Error")

    else:
        print('Find ' + str(count - 1) + ' faces to Destination ' + targetPath)


if __name__ == '__main__':
    invalidPath = r'E:\a_test\haveNoPeople'
    sourcePath = r'E:\a_test\data'
    targetPath = r'E:\a_test\faceOfPeople'
    readPicSaveFace(sourcePath, targetPath, invalidPath, '.jpg', '.JPG', '.png', '.PNG')

 

你可能感兴趣的:(Python,人工智能,机器学习,深度学习)