python进阶-12-opencv人脸识别

2020-04-02  本文已影响0人  西海岸虎皮猫大人

1 模块安装,读取图片

1.安装
pip install opencv-python

opencv c++写的,python可以调用c++库

2.读取图片
# coding=utf-8
import cv2 as cv
# 读取图片,路径中不能有中文
img = cv.imread('img/1.jpg')
# 显示
cv.imshow('read_img', img)
# 等待键盘输入,解决闪退问题,0表示无线等待
cv.waitKey(0)
# 释放内存空间,由于底层是c++
cv.destroyAllWindows()

2 图片灰度转换

opencv通道BGR,蓝绿红,只是顺序不同
灰度转换,去除彩色信息,降低计算强度,对人脸识别比较有效

# coding=utf-8
import cv2 as cv
img = cv.imread('img/1.jpg')
# 灰度转换
gray_img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
cv.imshow('BGR_img', gray_img)
# 保存图片
cv.imwrite('gray_img.jpg', gray_img)
cv.waitKey(0)
cv.destroyAllWindows()

3 修改图片尺寸

# coding=utf-8
import cv2 as cv
img = cv.imread('img/1.jpg')
print('图片形状:', img.shape)
# 修改尺寸,缩小
resize_img = cv.resize(img, dsize=(200, 200))
# 修改尺寸,放大
# resize_img = cv.resize(img, dsize=(2000, 2000))
cv.imshow('resize_img', resize_img)
# cv.waitKey(0)
# 输入q退出
while True:
    if ord('q') == cv.waitKey(0):
        break
cv.destroyAllWindows()

4.绘制图形

做人脸检测需要将人脸圈出来

# coding=utf-8
import cv2 as cv
img = cv.imread('img/1.jpg')
x, y, w, h = 100, 100, 100, 100
# 绘制矩形, color BGR 绿色 宽度2
cv.rectangle(img, (x, y, x+w, y+h), color=(0, 255, 0), thickness=2)
x, y, r = 200, 200, 100
# 绘制圆 center原点 radius半径 红色
cv.circle(img, center=(x, y), radius=r, color=(0, 0, 255))
cv.imshow('img', img)
cv.waitKey(0)
cv.destroyAllWindows()

5 人脸检测

特征,提取细节分析结果
Haar特征,实时人脸跟踪特征

5.1 下载Haar特征数据

下载地址:
https://opencv.org/releases/
速度较慢,下载完双击运行解压
附百度云:
链接:https://pan.baidu.com/s/1gl9qmoS7OJlsR_1cejMyow
提取码:1kgq

# coding=utf-8
import cv2 as cv


def face_detect_demo():
    # 图片转灰度
    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    # 加载特征数据,同目录下还有对于其他面部器官的特征数据
    face_detector = cv.CascadeClassifier('C:/sof/opencv/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml')
    faces = face_detector.detectMultiScale(gray)
    for x, y, w, h in faces:
        # 矩形圈出人脸
        cv.rectangle(img, (x, y), (x+w, y+h), color=(0, 255, 0), thickness=2)
    cv.imshow('img', img)


img = cv.imread('img/2.jpg')
face_detect_demo()

cv.waitKey(0)
cv.destroyAllWindows()

下一部分会讲如何通过调整参数提高检测精确度


image.png

6 检测多张人脸

与5中代码基本一致,增加了参数调整

# coding=utf-8
import cv2 as cv

def faces_detect_demo():
    # 图片转灰度
    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    # 加载特征数据,同目录下还有对于其他面部器官的特征数据
    face_detector = cv.CascadeClassifier('C:/sof/opencv/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml')
    # faces = face_detector.detectMultiScale(gray)
    # scaleFactor缩放比例, minNeighbors检测次数, maxSize最大区域, minSize最小区域
    # 通过调整以上参数提高检测精确度
    faces = face_detector.detectMultiScale(gray, scaleFactor=1.03, minNeighbors=5, maxSize=(55, 55), minSize=(30, 30))
    for x, y, w, h in faces:
        # 打印矩形区域的参数,根据该参数调整上述的maxSize和minSize
        print(x, y, w, h)
        # 矩形圈出人脸
        cv.rectangle(img, (x, y), (x+w, y+h), color=(0, 255, 0), thickness=2)
        # 原型圈出人脸
        cv.circle(img, center=(x+w//2, y+h//2), radius=w//2, color=(0, 255, 0), thickness=2)
    cv.imshow('img', img)


img = cv.imread('img/3.jpg')
faces_detect_demo()


cv.waitKey(0)
cv.destroyAllWindows()
image.png

7 视频人脸检测

对视频每一帧的图像进行人脸检测,图像检测方法与5中相同

# coding=utf-8
import cv2 as cv


def face_detect_demo(img):
    # 图片转灰度
    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    # 加载特征数据,同目录下还有对于其他面部器官的特征数据
    face_detector = cv.CascadeClassifier(
        'C:/sof/opencv/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml')
    faces = face_detector.detectMultiScale(gray)
    for x, y, w, h in faces:
        # 矩形圈出人脸
        cv.rectangle(img, (x, y), (x + w, y + h), color=(0, 255, 0), thickness=2)
    cv.imshow('img', img)


# 读取视频
cap = cv.VideoCapture('video/video.mp4')
while True:
    flag, frame = cap.read()
    # 如果视频读取到末尾
    if not flag:
        break
    # 对视频的每一帧调用图像检测方法
    face_detect_demo(frame)
    if ord('q') == cv.waitKey(10):
        break

cv.destroyAllWindows()
cap.release()

8.人脸识别

8.1 训练数据

人脸识别需要录入一些图像,训练数据
使用opencv的face模块
安装模块:

pip install opencv-contrib-python

报错:

ERROR: Could not install packages due to an EnvironmentError:

是由于pycharm程序运行中所致,关闭pycharm重新执行命令

代码实现

data/jm目录下存放了15个图片,1-5为人员1,6-10为人员2,11-15为人员3
训练后的数据保存至trainer目录
主要思路就是获取人脸区域和图像id列表,然后使用 cv2.face模块进行训练

# coding=utf-8
import os
import cv2
from PIL import Image
import numpy as np


def getImageAndLabels(path):
    facesSamples = []
    ids = []
    # 图片全路径列表
    imagePaths = [os.path.join(path, f) for f in os.listdir(path)]
    # 检测人脸
    face_detector = cv2.CascadeClassifier('C:/sof/opencv/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml')

    # 遍历列表中的图片
    for imagePath in imagePaths:
        # 打开图片 L模式
        PIL_img = Image.open(imagePath).convert('L')
        # 图像转为数组
        img_numpy = np.array(PIL_img, 'uint8')
        faces = face_detector.detectMultiScale(img_numpy)
        # 获取每张图片的id
        id = int(os.path.split(imagePath)[1].split('.')[0])
        for x,y,w,h in faces:
            # 切片提取人脸区域
            facesSamples.append(img_numpy[y:y+h,x:x+w])
            ids.append(id)
    return facesSamples, ids


if __name__ == '__main__':
    # 图像路径
    path = './data/jm'
    # 获取图像数组和id标签数组
    faces, ids = getImageAndLabels(path)
    # 获取循环对象
    recognizer = cv2.face.LBPHFaceRecognizer_create()
    recognizer.train(faces, np.array(ids))
    # 保存文件
    recognizer.write('trainer/trainer.yml')
8.2 人脸识别

基于LBPH,将检测到的人脸分为小单元,并与没模型中的对应单元进行比较,对每个区域的匹配值产生一个直方图
该算法是唯一允许模型样本人脸和检测人脸大小形状不同的算法
0完全识别,好的识别低于50,差的高于80

代码实现

思路比较简单,加载训练数据集,检测待识别人脸,然后predict即可

# coding=utf-8
import cv2
# 加载训练数据集文件
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read('trainer/trainer.yml')
# 准备识别的图片
img = cv2.imread('img/19.pgm')
# 检测人脸
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
face_detector = cv2.CascadeClassifier('C:/sof/opencv/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml')
faces = face_detector.detectMultiScale(gray)
for x, y, w, h in faces:
    # 矩形圈出人脸
    cv2.rectangle(img, (x, y), (x + w, y + h), color=(0, 255, 0), thickness=2)
    id, confidence = recognizer.predict(gray[y:y + h, x:x + w])
    print('标签id:', id, '执行评分:', confidence)


cv2.imshow('result', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
上一篇下一篇

猜你喜欢

热点阅读