前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于OpenCV for Python入门-自带人脸检测算法比较

关于OpenCV for Python入门-自带人脸检测算法比较

作者头像
python与大数据分析
发布2022-04-02 14:47:41
5180
发布2022-04-02 14:47:41
举报

本来学习OpenCV的目的就是为了做人脸识别、车辆识别、人群计数等等,识别人脸首先要进行人脸检测,OpenCV中内置了Haar Cascade人脸分类器,其中包括haarcascade_frontalface_alt、haarcascade_frontalface_alt_tree、haarcascade_frontalface_alt2、haarcascade_frontalface_default这四种,本文不求甚解,只是从比对上判断一下这几种内置分类器的可用性。

比较的依据,一个是下载的ORL人脸数据库,40个人物*10张照片(92*112像素);另一个是从网络上下载的几张集体照。

ORL人脸数据库,每一个目录就是个人物,就是人物标签

juhui1,1927年在比利时布鲁塞尔召开的第五次索尔维会议,共29个人,黑白照片

juhui2,1924年林徽因等与访问中国的泰戈尔合影,共7个人

juhui3,仍然是1927年在比利时布鲁塞尔召开的第五次索尔维会议,共29个人,但是是彩色照片

下面的代码是读取摄像头,进行人脸检测

代码语言:javascript
复制
import numpy as np
import cv2
import os

# 定义绿色跟踪框
color = (0, 255, 0)

# 读取当前笔记本摄像头
camera = cv2.VideoCapture(0)
# 判断摄像头是否打开
while camera.isOpened():
    #cap.read()返回两个参数赋给两个值。
    #   第一个参数ret的值为True或False,代表有没有读到图片。
    #   第二个参数是frame,是当前截取一帧的图片
    ret, frame = camera.read()
    if ret:
        # 获取当前帧
        image = frame
        # 进行颜色灰度转换
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        # 加载分类器,opencv自带的分类器,放在C:\Python\Python37\Lib\site-packages\cv2\data目录下,主要包括
        # haarcascade_eye 睁开的眼睛的检测
        # haarcascade_eye_tree_eyeglasses 戴眼镜时睁开的眼睛
        # haarcascade_frontalcatface      正脸检测
        # haarcascade_frontalcatface_extended     正脸检测
        # haarcascade_frontalface_alt     正脸检测
        # haarcascade_frontalface_alt_tree        正脸检测
        # haarcascade_frontalface_alt2    正脸检测
        # haarcascade_frontalface_default 正脸检测
        # haarcascade_fullbody    全身检测
        # haarcascade_lefteye_2splits     检测左眼开或闭合
        # haarcascade_licence_plate_rus_16stages  俄罗斯车牌
        # haarcascade_lowerbody   下肢检测
        # haarcascade_profileface 人脸轮廓检测
        # haarcascade_righteye_2splits    检测右眼开或闭合
        # haarcascade_russian_plate_number        俄罗斯车牌号
        # haarcascade_smile       微笑表情检测
        # haarcascade_upperbody   上半身检测
        classfier = cv2.CascadeClassifier("haarcascade_frontalface_alt2.xml")
        # detectMultiScale函数。可以检测出图片中所有的人脸,并将人脸用vector保存各个人脸的坐标、大小(用矩形表示),函数由分类器对象调用
        # 参数1:image--待检测图片,一般为灰度图像加快检测速度;
        # 参数2:objects--被检测物体的矩形框向量组;
        # 参数3:scaleFactor--表示在前后两次相继的扫描中,搜索窗口的比例系数。默认为1.1即每次搜索窗口依次扩大10%;
        # 参数4:minNeighbors--表示构成检测目标的相邻矩形的最小个数(默认为3个)。
        #         如果组成检测目标的小矩形的个数和小于 min_neighbors - 1 都会被排除。
        #         如果min_neighbors 为 0, 则函数不做任何操作就返回所有的被检候选矩形框,
        #         这种设定值一般用在用户自定义对检测结果的组合程序上;
        # 参数5:flags--要么使用默认值,要么使用CV_HAAR_DO_CANNY_PRUNING,如果设置为
        #         CV_HAAR_DO_CANNY_PRUNING,那么函数将会使用Canny边缘检测来排除边缘过多或过少的区域,
        #         因此这些区域通常不会是人脸所在区域;
        # 参数6、7:minSize和maxSize用来限制得到的目标区域的范围。
        faceRects = classfier.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=3, minSize=(32, 32))
        # 返回识别出来的脸部矩阵的位置数组 [[211 191 266 266] [211 191 266 266] [211 191 266 266]]
        # 如果已识别脸部对象
        if len(faceRects) > 0:
            # 循环输出识别的数组
            for faceRect in faceRects:
                # 获取矩阵的人脸的坐标、大小
                x, y, w, h = faceRect
                # 通过rectangle()在图片上构建矩阵图
                cv2.rectangle(image, (x - 10, y - 10), (x + w + 10, y + h + 10), color, 3)
                # 展示图片
                cv2.imshow("My Capture", image)
        # 按q键退出
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
# 关闭摄像头
camera.release()
# 关闭窗口
cv2.destroyAllWindows()

下面的代码是读取摄像头,进行人脸检测和眼睛检测

代码语言:javascript
复制
import numpy as np
import cv2
import os

# 定义绿色跟踪框
color = (0, 255, 0)
# 正脸检测分类器
face_cascade = cv2.CascadeClassifier('C:\\Python\\Python37\\Lib\\site-packages\\cv2\\data\\haarcascade_frontalface_alt2.xml')
# 睁开的眼睛的检测分类器,奇怪不加路径会报错
eye_cascade = cv2.CascadeClassifier('C:\\Python\\Python37\\Lib\\site-packages\\cv2\\data\\haarcascade_eye.xml')

# 读取当前笔记本摄像头
camera = cv2.VideoCapture(0 ,cv2.CAP_DSHOW)
# 判断摄像头是否打开
while camera.isOpened():
    ret, frame = camera.read()
    if ret:
        # 获取当前帧
        image = frame
        # 灰度转换
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        # 脸部检测
        faces = face_cascade.detectMultiScale(gray, 1.3, 5)
        # 遍历脸部检测数组
        for (x, y, w, h) in faces:
            # 输出脸部矩阵
            cv2.rectangle(image, (x, y), (x + w, y + h), (255, 0, 0), 2)
            # 在脸部范围内搜索眼睛,一个灰度图(用来识别眼睛),一个颜色图(用来输出眼睛矩阵)
            roi_gray = gray[y:y + h, x:x + w]
            roi_color = image[y:y + h, x:x + w]
            # 进行眼睛检测
            eyes = eye_cascade.detectMultiScale(roi_gray)
            # 在脸部区画眼睛矩阵
            for (ex, ey, ew, eh) in eyes:
               cv2.rectangle(roi_color, (ex, ey), (ex + ew, ey + eh), (0, 255, 0), 2)

            cv2.imshow('img', image)

        # 按q键退出
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
            
# 关闭摄像头
camera.release()
# 关闭窗口
cv2.destroyAllWindows()

用opencv内置分类器对几张聚会照片进行人脸检测。

代码语言:javascript
复制
import numpy as np
import cv2

imgname = 'C:\\Python\\Pycharm\\docxprocess\\picture\\predict\\juhui4.png'
face_cascade = cv2.CascadeClassifier(
    'C:\\Python\\Python37\\Lib\\site-packages\\cv2\\data\\haarcascade_frontalface_alt.xml')
# face_cascade = cv2.CascadeClassifier('C:\\Python\\Python37\\Lib\\site-packages\\cv2\\data\\haarcascade_frontalface_alt2.xml')
# face_cascade = cv2.CascadeClassifier('C:\\Python\\Python37\\Lib\\site-packages\\cv2\\data\\haarcascade_frontalface_alt_tree.xml')
# face_cascade = cv2.CascadeClassifier('C:\\Python\\Python37\\Lib\\site-packages\\cv2\\data\\haarcascade_frontalface_default.xml')
img = cv2.imread(imgname)
# img = cv2.imread('wukelan.jpeg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x, y, w, h) in faces:
    cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)

cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

比较检测出来的人脸,可以看出haarcascade_frontalface_alt_tree>haarcascade_frontalface_alt>haarcascade_frontalface_default>haarcascade_frontalface_alt2

下面是对ORL人脸数据库进行人脸检测。

代码语言:javascript
复制
import cv2
import numpy as np
import os
import shutil

# 载入图像,读取ORL人脸数据库,准备训练数据
def loadimageface(data):
    # 加载图片数据用于训练
    # params:data:训练数据所在的目录,要求图片尺寸一样
    #ret:
    #    images:[m,height,width]  m为样本数,height为高,width为宽
    #    names:名字的集合
    #    labels:标签
    images = []
    names = []
    labels = []
    face_casecade = cv2.CascadeClassifier('C:\\Python\\Python37\\Lib\\site-packages\\cv2\\data\\haarcascade_frontalface_default.xml')
    # haarcascade_frontalface_alt_tree  21
    # [ 3  9 13 13 13 13 15 17 24 31 33 34 34 34 35 35 36 37 37 37 37]
    # haarcascade_frontalface_alt   222
    # [ 0  0  1  1  1  1  1  1  1  1  1  2  2  2  2  2  2  2  2  3  3  3  3  3
    #   3  3  3  3  3  4  4  4  4  4  5  5  5  5  5  6  6  6  6  6  7  7  7  7
    #   8  8  9  9  9  9  9  9  9  9  9  9 10 10 10 12 12 12 12 12 12 12 12 12
    #  13 13 13 13 13 13 13 13 13 13 14 15 15 15 15 15 15 16 16 16 16 16 17 17
    #  17 17 18 18 18 18 18 18 19 20 20 21 21 21 21 21 21 21 21 22 22 22 22 22
    #  22 23 23 23 23 23 23 23 23 24 24 24 24 24 25 25 26 26 26 26 26 26 26 26
    #  29 29 29 29 29 30 30 30 30 30 31 31 31 31 31 31 31 31 31 31 32 32 32 33
    #  33 33 33 33 34 34 34 34 34 34 34 35 35 35 35 35 36 36 36 36 36 36 36 36
    #  36 37 37 37 37 37 37 37 37 37 37 38 38 38 38 38 38 38 38 38 39 39 39 39
    #  39 39 39 39 39]
    # haarcascade_frontalface_alt2  231
    # [ 0  0  0  1  1  1  1  1  1  1  1  1  2  2  2  2  2  2  2  3  3  3  3  3
    #   3  3  3  3  3  4  4  4  4  5  5  5  5  6  6  6  6  6  6  7  7  7  7  7
    #   7  8  8  9  9  9  9  9  9  9  9  9  9 10 10 10 12 12 12 12 12 12 12 12
    #  12 13 13 13 13 13 13 13 13 13 13 15 15 15 15 15 15 15 15 15 16 16 16 16
    #  16 16 16 16 17 17 17 17 17 18 18 18 18 18 19 19 19 20 20 21 21 21 21 21
    #  21 21 21 22 22 22 22 22 22 22 23 23 23 23 23 23 23 23 23 24 24 24 24 24
    #  25 25 26 26 26 26 26 28 29 29 29 29 29 30 30 30 30 31 31 31 31 31 31 31
    #  31 31 31 32 32 32 32 32 32 33 33 33 33 33 34 34 34 34 34 34 34 35 35 35
    #  35 35 36 36 36 36 36 36 36 36 36 37 37 37 37 37 37 37 37 37 37 38 38 38
    #  38 38 38 38 38 39 39 39 39 39 39 39 39 39]
    # haarcascade_frontalface_default   264
    # [ 0  0  0  0  0  1  1  1  1  1  1  1  1  2  2  2  2  2  2  2  2  2  2  3
    #   3  3  3  3  3  3  4  4  4  4  4  4  5  5  5  5  5  5  5  5  5  5  6  6
    #   6  6  6  6  6  7  7  7  7  7  7  7  8  8  9  9  9  9  9  9  9  9  9  9
    #  10 10 10 10 10 12 12 12 12 12 12 12 12 12 12 13 13 13 13 13 13 13 13 13
    #  13 14 14 14 14 14 14 14 15 15 15 15 15 15 16 16 16 16 16 16 16 16 16 17
    #  17 17 17 17 18 18 18 18 18 19 19 19 19 19 19 19 19 19 19 20 20 20 20 20
    #  20 21 21 21 21 21 21 22 22 22 22 23 23 23 23 23 23 23 24 24 24 24 24 25
    #  25 25 25 26 26 26 26 26 26 26 26 26 29 29 29 29 29 29 29 30 30 30 30 30
    #  30 30 31 31 31 31 31 31 31 31 31 32 32 32 32 33 33 33 33 33 33 33 33 34
    #  34 34 34 34 34 34 35 35 35 35 35 36 36 36 36 36 36 36 36 36 37 37 37 37
    #  37 37 37 37 37 37 38 38 38 38 38 38 38 38 38 39 39 39 39 39 39 39 39]
    label = 0
    # 遍历当前文件夹
    for subdir in os.listdir(data):

        print('processing ',subdir)
        # 构造路径全链路
        subpath = os.path.join(data, subdir)
        # 如果是否文件夹
        if os.path.isdir(subpath):
            # 每个文件夹代表一个人,也就是构造人的姓名
            names.append(subdir)
            # 遍历文件夹中的图片文件
            for filename in os.listdir(subpath):
                imgpath = os.path.join(subpath, filename)
                print('processing ', filename)
                # 读取图片,并转换为灰度图片
                # 灰度图片用于进行训练
                # 构造图片和标签关系
                img = cv2.imread(imgpath, cv2.IMREAD_COLOR)
                gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
                faces = face_casecade.detectMultiScale(gray_img, 1.3, 5)
                print('faces=',faces,'face num=',str(len(faces)))
                for (x, y, w, h) in faces:
                    cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)
                if (len(faces) > 0):
                    (x, y, w, h) = faces[0]
                    # 只返回图像的正面部分
                    images.append(gray_img[y:y + w, x:x + h])
                    labels.append(label)

                cv2.imshow('img', img)
            label += 1
    # 将图片转换为易于操作的ndarray形式
    images = np.asarray(images)
    # 将标签转为numpy格式
    labels = np.asarray(labels)
    return images, labels, names

if __name__ == '__main__':
    trainimage = 'C:\\Python\\Pycharm\\docxprocess\\picture\\ORL\\'
    X, y, names = loadimageface(trainimage)

从效果上cade_frontalface_default>haarcashaarcascade_frontalface_alt2>haarcascade_frontalface_alt>haarcascade_frontalface_alt_tree

这就比较尴尬了。。。到底选谁好呢?

说到底,Haar Cascade人脸分类器是入门级的人脸检测工具,只能用于好玩的测试,看样子只能用更加高级的工具了。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-03-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 python与大数据分析 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
人脸识别
腾讯云神图·人脸识别(Face Recognition)基于腾讯优图强大的面部分析技术,提供包括人脸检测与分析、比对、搜索、验证、五官定位、活体检测等多种功能,为开发者和企业提供高性能高可用的人脸识别服务。 可应用于在线娱乐、在线身份认证等多种应用场景,充分满足各行业客户的人脸属性识别及用户身份确认等需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档