python-opencv人脸检测和识别实现(有代码和资源)

方法讲解

人脸检测,把图像分成一个个小块,对每一个小块判断是否是人脸,假如一张图被分成了5000块,则速度非常慢。
为了提高效率,OpenCV 提供 cascades 来避免这种情况。提供了一系列的xml文件
cascades :翻译 :小瀑布 级联
cascade 对于每个数据块,它都进行一个简单快速的检测。若过,会再进行一个更仔细的检测。该算法有 30 到 50 个这样的阶段,或者说 cascade。只有通过全部阶段,cascade才会判断检测到人脸。这样做的好处是:大多数小块都会在前几步就产生否定反馈,节约时间。
资源链接,该资源不仅仅包括人脸xml,还有其他眼睛等。赚取点积分吧。
OpenCV人脸识别xml文件.zip
或者
OpenCV官网
从官网Sources里找资源,data文件夹中有是特征文件,我们一般选用haarcascade_frontalface_default.xml

人脸检测

1人脸检测实现

import numpy as np
import cv2

# 实例化人脸分类器
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')#xml来源于资源文件。
# 读取测试图片
img = cv2.imread('faces.jpg',cv2.IMREAD_COLOR)
# 将原彩色图转换成灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 开始在灰度图上检测人脸,输出是人脸区域的外接矩形框
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=1)
# 遍历人脸检测结果
for (x,y,w,h) in faces:
    # 在原彩色图上画人脸矩形框
    cv2.rectangle(img,(x,y),(x+w,y+h),(255,255,0),2)
# 显示画好矩形框的图片
cv2.namedWindow('faces', cv2.WINDOW_AUTOSIZE)
cv2.imshow('faces',img)
# 等待退出键
cv2.waitKey(0)
# 销毁显示窗口
cv2.destroyAllWindows()

修改face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=1) 里的参数值可以得到不同的识别精度,有的识别出的人多,有的少。

2摄像头下人脸检测实现


import cv2 as cv
import numpy as np
def face_detect_demo(image):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    face_detector = cv.CascadeClassifier("haarcascade_frontalface_default.xml")
    faces = face_detector.detectMultiScale(gray, 1.2, 6)
    for x, y, w, h in faces:
        cv.rectangle(image, (x, y), (x+w, y+h), (0, 0, 255), 2)
    cv.imshow("result", image)

print("--------- Python OpenCV Tutorial ---------")

capture = cv.VideoCapture(0)
cv.namedWindow("result", cv.WINDOW_AUTOSIZE)
while(True):
    ret, frame = capture.read()
    frame = cv.flip(frame, 1)#左右翻转
    face_detect_demo(frame)
    c = cv.waitKey(10)
    if c == 27: # ESC
        break
cv.waitKey(0)
cv.destroyAllWindows()

手拿平板试下吧,博主我不上镜。
同理:调整 face_detector.detectMultiScale(gray, 1.2, 6) 的参数值,效果不一样。
python-opencv人脸检测和识别实现(有代码和资源)_第1张图片

人脸识别

前面讲得是人脸检测,即检测出图片是否含有脸。接下来完成人脸识别,即识别出当前脸是谁。
数据集

选取杨幂和刘亦菲的网图各几张。
python-opencv人脸检测和识别实现(有代码和资源)_第2张图片
python-opencv人脸检测和识别实现(有代码和资源)_第3张图片

训练模型并保存
注意:如果出现module ‘cv2.cv2’ has no attribute ‘face’ 错误信息。
说明没有安装opencv-contrib-python 包,这是OpenCV外带模块,外带模块是测试性能不足,所以没有一起放在opencv包里。
解决方法:pip install opencv-contrib-python

import os
import numpy as np
import cv2

#脸部检测函数
def face_detect_demo(image):
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    face_detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
    faces = face_detector.detectMultiScale(gray, 1.2, 6)
    # 如果未检测到面部,则返回原始图像
    if (len(faces) == 0):
        return None, None
    # 目前假设只有一张脸,xy为左上角坐标,wh为矩形的宽高
    (x, y, w, h) = faces[0]
    # 返回图像的脸部部分
    return gray[y:y + w, x:x + h], faces[0]

def ReFileName(dirPath):
    """
    :param dirPath: 文件夹路径
    :return:
    """
    # 对目录下的文件进行遍历
    faces=[]
    for file in os.listdir(dirPath):
        # 判断是否是文件
        if os.path.isfile(os.path.join(dirPath, file)) == True:
           c= os.path.basename(file)
           name = dirPath + '\\' + c
           img = cv2.imread(name)
           # 检测脸部
           face, rect = face_detect_demo(img)
           # 我们忽略未检测到的脸部
           if face is not None:
               # 将脸添加到脸部列表并添加相应的标签
               faces.append(face)
    cv2.waitKey(1)
    cv2.destroyAllWindows()
    return faces

#杨幂照读取
dirPathyangmi = r"C:\Users\Shineion\Desktop\yangmi"#文件路径
yangmi=ReFileName(dirPathyangmi)#调用函数

labelyangmi=np.array([0 for i in range(len(yangmi))])#标签处理
#刘亦菲照读取
dirPathliuyifei = r"C:\Users\Shineion\Desktop\yangmi"#文件路径
liuyifei=ReFileName(dirPathliuyifei)#调用函数
labelliuyifei=np.array([1 for i in range(len(liuyifei))])#标签处理

#拼接并打乱数据特征和标签
x=np.concatenate((yangmi,liuyifei),axis=0)
y=np.concatenate((labelyangmi,labelliuyifei),axis=0)

index = [i for i in range(len(y))] # test_data为测试数据
np.random.seed(1)
np.random.shuffle(index) # 打乱索引
train_data = x[index]
train_label = y[index]

#分类器
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.train(train_data, train_label)
# 保存训练数据
recognizer.write('train.yml')

人脸图像预测

import cv2
#人脸检测函数
def face_detect_demo(image):
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    face_detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
    faces = face_detector.detectMultiScale(gray, 1.2, 6)
    # 如果未检测到面部,则返回原始图像
    if (len(faces) == 0):
        return None, None
    # 目前假设只有一张脸,xy为左上角坐标,wh为矩形的宽高
    (x, y, w, h) = faces[0]
    # 返回图像的脸部部分
    return gray[y:y + w, x:x + h], faces[0]


#导入训练结果
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read('train.yml')#读取前文训练的结果


# 根据给定的人脸(x,y)坐标和宽度高度在图像上绘制矩形
def draw_rectangle(img, rect):
    (x, y, w, h) = rect#矩形框
    cv2.rectangle(img, (x, y), (x + w, y + h), (255, 255, 0), 2)

# 根据给定的人脸(x,y)坐标写出人名
def draw_text(img, text, x, y):
    cv2.putText(img, text, (x, y), cv2.FONT_HERSHEY_COMPLEX, 1, (128, 128, 0), 2)

# 此函数识别图像中的人物并在脸部周围绘制一个矩形及其人名
facelabel = ["yangmi", "liuyifei"]#人物名
def predict(image):
    # 生成图像的副本,保留原始图像
    img = image.copy()
    # 检测人脸区域
    face, rect = face_detect_demo(img)#face_detect_demo前面的人脸检测函数
    #print(rect)=[x,y,w,h]
    # 预测人脸名字
    label = recognizer.predict(face)
    print(label)#label[0]为名字,label[1]可信度数值越低,可信度越高(
    if label[1]<=50:
        # 获取由人脸识别器返回的相应标签的人名
        label_text = facelabel[label[0]]

        # 在检测到的脸部周围画一个矩形
        draw_rectangle(img, rect)
        # 标出预测的人名
        draw_text(img, label_text, rect[0], rect[1])
        # 返回预测的图像
        return img
    else:
        # 在检测到的脸部周围画一个矩形
        draw_rectangle(img, rect)
        # 标出预测的人名
        draw_text(img, "not find", rect[0], rect[1])
        # 返回预测的图像
        return img

test_img = cv2.imread("C:\\Users\\Shineion\\Desktop\\liuyifei\\8.jpg")
#执行预测
pred_img = predict(test_img)
cv2.imshow('result', pred_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

结果
python-opencv人脸检测和识别实现(有代码和资源)_第4张图片
换一个张图试下
python-opencv人脸检测和识别实现(有代码和资源)_第5张图片
再换张其他人的,来源网图,如有侵权,联系我删除。

注意事项:
1本文的训练集图片太少,所以测试有些误差,有的图片要识别出错。可以自己调整可信度系数和增加训练集图片
2.本文模型是二分类,也可以多分类。标签分别是[0,1,2,3,4,…],不需要one-hot化。这点不同于常规分类器
3.图片路径不能出现中文,OpenCV决定的。标注的名字不能出现中文,中文乱码,自己可以研究下OpenCV标注中文。

送上OpenCV学习资源:
自己总结的。
36篇博文带你学完opencv :python+opencv进阶版学习笔记目录

本想实现调用摄像头,然后在摄像头里识别人脸,其标注出人的名字。结果不成功,可能是摄像头里图片更新太快,反应不过来。等我有时间再研究下吧。

电气专业的计算机萌新,写博文不容易,如果你觉得本文不错,请点个赞支持下,谢谢。

在这里插入图片描述

你可能感兴趣的:(cv计算机视觉,opencv,人脸识别,python)