python3+opencv3实现人脸识别:
注释:本编也是菜鸡,心血都在这了。
import cv2 as cv
import numpy as np
import time
import os
import os.path
'导入几个必须的模块,除此之外还另需装"opencv-contrib-python"与"pytesseract"俩个"opencv"的扩展模块.下面的最基本的操作我就不说了,之说明一下与人脸识别有关的函数使用时的注意事项。
以下代码分三个函数, 分别是:
(1)存储图片数据库(拍几张你的照片)
(2)获取所存储的照片(将你/他/她 三人的照片与分别对应的序号(你:0,他:1,她2)赋给俩个列表变量)
(3)对比你之前拍好的照片与现在视频中的脸是不是一个人
注释:我用的虚拟机是ubantuy无法直接打开摄像头哦!
操作:虚拟机(M)(在虚拟机的左上方)-> 可移动设备(D) -> (选择你的摄像头连接)’
def face_data_save_demo():
'''copy的时候此处不知道为啥不能缩进'''
face_cascade = cv.CascadeClassifier("/home/fengkuanwen/下载/opencv/data/haarcascades/haarcascade_frontalface_default.xml")
‘创建人脸识别的一个及联分类器, 文件在opencv官网可以下载’
capture = cv.VideoCapture(0)
‘读取你电脑的第0个摄像头, 即是第一个,编译语言都是从0开始滴’
while True:
ret, frame = capture.read()
frame = cv.flip(frame, 1)
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.1, 5)
‘尽量是一个灰度图像,1.1表示在前后两次相继的扫描中,搜索窗口的比例系数,默认为1.1即每次搜索窗口依次扩大10%;5表示构成检测目标的相邻矩形的最小个数(默认为3个)。越多检测的精度越高’
for (x, y, w, h) in faces:
cv.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 1)
roi = gray[y: y+h, x: x+w]
roi = cv.resize(roi, (200, 200))
'''由于对比人脸时需要大小相同的图片,所以就改变以下图片大小'''
cv.imwrite("/home/fengkuanwen/faces/feng_face/NO.%s.pgm"%l, roi)
cv.imshow("face_data_save_demo", frame)
l += 1
time.sleep(0.1)
if cv.waitKey(20) == 27:
break
‘第二个函数’
def face_data_catah_demo(path):
x, y =[], []
c = 0
‘把我们之前照片从存储的位置读取出来’
for mainpath, dirnames, filenames in os.walk(path):
'''返回三个参数,第一个是path即咱们传入参数的路径,第二个是该路径下的全部文件夹名称(不包括子文件夹), 第三个参数是该路径下的全部文件名(不包括子文件)'''
for dirname in dirnames:
dirpath = os.path.join(mainpath, dirname)
'''dirpath就是每个文件夹的路路径:os.path.join("D:/", "美女.jpg")就为"D:/美女.jpg"'''
for face_name in os.listdir(dirpath):
'''os.listdir(path)就是该路径下的全部文件名称,在这里就是全部照片名称'''
face_path = os.path.join(dirpath, face_name)
'''对比之前就是每张照片的路径'''
img = cv.imread(face_path, cv.IMREAD_GRAYSCALE)
img = np.asarray(img, np.uint8)
'''需要改一下照片的字节类型'''
x.append(img)
y.append(c)
'''每一个c就是每一张照片的标签,相同人的照片的标签应该相同,就是feng文件夹里面所有的feng**的照片的标签都为0'''
c += 1
return x, y
‘第三个函数’
def face_recoglize(path):
x, y = face_data_catah_demo(path)
y = np.asarray(y, np.int32)
names = ["feng", "zhang"]
‘名称列表,此处注意名称所在的位置 应该与每张照片对应的标签相同,一会既可以索引出来’
model = cv.face_EigenFaceRecognizer.create()
'创建人脸识别器的模型,模型本身就是一个算法,还有俩个模型算法比较常用,分别是 "fisherfaces "与 “LBPH” ’
model.train(np.asarray(x), np.asarray(y))
‘对模型进行训练,训练的内容就是,每一张照片与其所对应的标签.’
face_cascade = cv.CascadeClassifier("/home/fengkuanwen/下载/opencv/data/haarcascades/haarcascade_frontalface_default.xml")
capture = cv.VideoCapture(0)
while True:
ret, frame = capture.read()
frame = cv.flip(frame, 1)
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.2, 5)
for (x, y, w, h) in faces:
cv.rectangle(frame, (x, y), (x+w, y+h), (0, 0, 255), 1)
roi = gray[y: y+h, x:x+w]
try:
''''由于可能会比较失败,所以用try'''
roi = cv.resize(roi, (200, 200), interpolation=cv.INTER_LINEAR)
‘之前说过要比较的人脸此寸应该相同,所以这里修改以下区域大小.’
params = model.predict(roi)
‘将之前训练过的模型与现在的人脸区域进行比较,若比较成功,即会返回成功照片对应的标签’
cv.putText(frame, names[params[0]], (x, y-20), cv.FONT_HERSHEY_COMPLEX, 1, (0, 255, 0), 1)
‘在要现实的图像上显现出文字,在这里parama[0]代表比较成功的结果,其值可以是0,1,2中的任意一个’
except:
continue
cv.imshow("face_recoglize", frame)
if cv.waitKey(20) == 27:
break
cv.destroyAllWindows()