face-recognition多人脸识别实时检测代码实例加精细化讲解

 

目录

完整代码(图片自己放) 

一.导库

二.加图片

三.BGR 转 RGB

四.检测人脸

face_locations(img, times_upsample=1, model="hog"):

五.人脸特征编码(将图片中的已知人脸图像编码成128维特征向量)

face_encodings(face_img, known_face_locations=None, num_jitters=1)

六.人脸组成“数据库”

七.打开摄像头,读取视频流

1.BGR 传 RGB

2.人脸检测

3.人脸特征编码

4.与数据库中的所有人脸进行匹配

循环结构(for-in)

(1)进行匹配

compare_faces(known_face_encodings, face_encoding_to_check, tolerance=0.6)

tolerance:容忍度,可调精度,越低越准。!!!!!解决精度问题!(2)计算距离

(3)判断:如果匹配,获取名字

(4)绘制人脸矩形框

(5)绘制、显示对应人脸的名字

(6)显示名字

putText(img, text, org, fontFace, fontScale, color, thickness=None, lineType=None, bottomLeftOrigin=None)

img :图像text :要绘制的文本字符串。org:文字添加到图片上的位置fontFace: 字体类型,参见#HersheyFontsfontScale :字体大小color:字体颜色thickness :字体粗细lineType :行类型。看 #LineTypesbottomLeftOrigin:为真时,图像数据源在左下角。反之,它就在左上角。

5.显示整个效果

6.判断 Q , 退出

八.关闭所有资源


完整代码(图片自己放) 

import cv2
import numpy as np
import face_recognition
name1 = cv2.imread("name1.jpg")
name2 = cv2.imread("name2.jpg")
name1_RGB = name1[:, :, ::-1]
name2_RGB = name2[:, :, ::-1]
name1_face = face_recognition.face_locations(name1_RGB)
name2_face = face_recognition.face_locations(name2_RGB)
name1_encoding = face_recognition.face_encodings(name1_RGB, name1_face)[0]
name2_encoding = face_recognition.face_encodings(name2_RGB, name2_face)[0]
encodings = [name1_encoding, name2_encoding]
names = ["name1", "name2"]
cap = cv2.VideoCapture(0)
if not cap.isOpened():
    raise  IOError("Camera Error !!!")

while True:
    ret, frame = cap.read()
    frame = cv2.resize(frame, (0,0), fx=0.5, fy=0.5)
    frame_RGB = frame[:, :, ::-1]
    faces_locations = face_recognition.face_locations(frame_RGB)
    faces_encodings = face_recognition.face_encodings(frame_RGB, faces_locations)
    for (top, right, bottom, left), face_encoding in zip(faces_locations, faces_encodings):
        matches = face_recognition.compare_faces(encodings, face_encoding)
        distances = face_recognition.face_distance(encodings, face_encoding)
        min_distance_index = np.argmin(distances) # 0, 1, 2
        name = "Unknown"
        if matches[min_distance_index]:
            name = names[min_distance_index]
        cv2.rectangle(frame, (left, top), (right, bottom), (0,255,0), 3)
        cv2.rectangle(frame, (left, bottom - 30),(right, bottom), (0,0,255), 3)
        cv2.putText(frame, name, (left+10 , bottom-10), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 255, 255), 1)
    cv2.imshow("face recognition", frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()

一.导库

import cv2
import numpy as np
import face_recognition

二.加图片

name1 = cv2.imread("name1.jpg")
name2 = cv2.imread("name2.jpg")

注意:name1.jpg/name2.jpg为自己要加入的图片

路径不要打错,文件名尽量不要用中文(请养成习惯)

路径错误:

 OpenCV(4.5.4-dev) D:aopencv-pythonopencv-pythonopencvmodulesimgprocsrccolor.cpp:182: error: (-215:Assertion failed) !_src.empty() in function 'cv::cvtColor'
TypeError: 'NoneType' object is not subscriptable

如果你的路径有中文:

python3中opencv读取中文名称的解决办法

import cv2
import numpy

def cv_imread(the_file_path):
    img = cv2.imdecode(np.fromfile(the_file_path,dtype=np.uint8),-1)
    return img

参考:Python 3.x 使用 opencv 无法读取中文路径如何解决? - 知乎

 附加:cv2的python版本中imwrite生成带有中文路径的图片

# python3版本
# imread
path_file = "....."
img = cv2.imdecode(np.fromfile(path_file,dtype=np.uint8),-1)

#imwrite
_path = "....."
cv2.imencode('.jpg',img)[1].tofile(_path)
# python 2版本
import cv2
import sys
reload(sys)
sys.setdefaultencoding('u8')
path_file = u"sample"
img = cv2.imread(path_file.decode('u8').encode('gbk'),-1)

参考:请教各位朋友cv2的python版本中imwrite无法生成带有中文路径的图片? - 知乎

三.BGR 转 RGB

name1_RGB = name1[:, :, ::-1]
name2_RGB = name2[:, :, ::-1]

四.检测人脸

name1_face = face_recognition.face_locations(name1_RGB)
name2_face = face_recognition.face_locations(name2_RGB)

face_locations:

face_locations(img, times_upsample=1, model="hog"):

img : 人脸位置的图像矩阵

times_upsample :查找次数

model :查找模式( 'hog' 不精确但是在CPU上运算速度快)( 'CNN' 是一种深度学习的精确查找,但是速度慢。需要GPU/CUDA加速。慎重选择!)

5.

五.人脸特征编码(将图片中的已知人脸图像编码成128维特征向量)

name1_encoding = face_recognition.face_encodings(name1_RGB, name1_face)[0]
name2_encoding = face_recognition.face_encodings(name2_RGB, name2_face)[0]

face_encodings(face_img, known_face_locations=None, num_jitters=1)

face_img :人脸位置的图像矩阵

known_face_locations :指定人脸位置 

num_jitters:计算编码时重新采样面的次数。越高越准,但更慢。

六.人脸组成“数据库”

encodings = [name1_encoding, name2_encoding]
names = ["name1", "name2"]

七.打开摄像头,读取视频流

cap = cv2.VideoCapture(0)
if not cap.isOpened():
    raise  IOError("Camera Error !!!")
while True:
    ret, frame = cap.read()
    frame = cv2.resize(frame, (0,0), fx=0.5, fy=0.5)

cap = cv2.VideoCapture(0)

0——表示打开笔记本的内置摄像头

视频文件路径——打开视频,如cap = cv2.VideoCapture("name.mp4")

ret,frame = cap.read()

 cap.read()——按帧读取视频

ret,frame——获cap.read()方法的两个返回值。(ret是布尔值,如果读取帧是正确的则返回True,如果文件读取到结尾,它的返回值就为False)(frame就是每一帧的图像,是个三维矩阵)

1.BGR 传 RGB

    frame_RGB = frame[:, :, ::-1]
    #请与上方的语句对齐,后方同。

注意:OpenCV读取的图片默认是BGR格式

2.人脸检测

    faces_locations = face_recognition.face_locations(frame_RGB)

3.人脸特征编码

    faces_encodings = face_recognition.face_encodings(frame_RGB, faces_locations)

4.与数据库中的所有人脸进行匹配

    for (top, right, bottom, left), face_encoding in zip(faces_locations, faces_encodings):

循环结构(for-in)

for x in y:

    循环体

执行流程:x依次表示y中的一个元素,遍历完所有元素循环结束

(1)进行匹配

        matches = face_recognition.compare_faces(encodings, face_encoding, tolerance=0.60)

compare_faces(known_face_encodings, face_encoding_to_check, tolerance=0.6)

known_face_encodings :已编码的人脸列表

face_encoding_to_check:要检测的单个人脸

tolerance:容忍度,可调精度,越低越准。!!!!!解决精度问题
(2)计算距离

        distances = face_recognition.face_distance(encodings, face_encoding)
        min_distance_index = np.argmin(distances) # 0, 1, 2
face_recognition.face_distance(face_encodings, face_to_compare)

给定面部编码列表,将它们与已知的面部编码进行比较,并获得每个比较面部的欧氏距离。距离告诉您脸部的相似程度。

(3)判断:如果匹配,获取名字

        name = "Unknown"
        if matches[min_distance_index]:
            name = names[min_distance_index]

(4)绘制人脸矩形框

        cv2.rectangle(frame, (left, top), (right, bottom), (0,255,0), 3)

 cv2.rectangle(image, start_point, end_point, color, thickness)

image:它是要在其上绘制矩形的图像。
start_point:它是矩形的起始坐标。坐标表示为两个值的元组,即(X坐标值,Y坐标值)。
end_point:它是矩形的结束坐标。坐标表示为两个值的元组,即(X坐标值ÿ坐标值)。
color:它是要绘制的矩形的边界线的颜色。
thickness:它是矩形边框线的粗细像素。厚度-1像素将以指定的颜色填充矩形形状。

(5)绘制、显示对应人脸的名字

        cv2.rectangle(frame, (left, bottom - 30),(right, bottom), (0,0,255), 3)

(6)显示名字

        cv2.putText(frame, name, (left+10 , bottom-10), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 255, 255), 1)

putText(img, text, org, fontFace, fontScale, color, thickness=None, lineType=None, bottomLeftOrigin=None)

img :图像
text :要绘制的文本字符串。
org:文字添加到图片上的位置
fontFace: 字体类型,参见#HersheyFonts
fontScale :字体大小
color:字体颜色
thickness :字体粗细
lineType :行类型。看 #LineTypes
bottomLeftOrigin:为真时,图像数据源在左下角。反之,它就在左上角。

5.显示整个效果

    cv2.imshow("face recognition", frame)

cv2.imshow(wname,img)

wname:窗口名字

img:图像

6.判断 Q , 退出

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

waitKey()——方法本身表示等待键盘输入

1——延时1ms切换到下一帧图像(对于视频而言);

0——只显示当前帧图像,相当于视频暂停,;

参数过大——会因为延时过久而卡顿感觉到卡顿。

八.关闭所有资源

cap.release()
cv2.destroyAllWindows()

release()——释放摄像头,调用destroyAllWindows()关闭所有图像窗口。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>