以下代码主要来源于网络,但经过自己调试修改后,已能完整运行,中间也碰到了很多坑,一一解决后写出来供大家参考!主要是cv2.face.属性不存在的问题,需要将opencv-python,opencv-contrib-python安装到位,不行的话,多用pip uninstall、install几次试试,我采用的opencv版本是3.4.2.16,另外重要一点:openCV不支持中文,文件夹或文件名不能出现中文。
'''
调用opencv的库实现人脸识别
学习openCV 2021-6-16
'''
import cv2
import numpy as np
import os
import shutil
#采集自己的人脸数据
def generator(data):
'''
打开摄像头,读取帧,检测该帧图像中的人脸,并进行剪切、缩放
生成图片满足以下格式:
1.灰度图,后缀为 .png
2.图像大小相同
3.params:
data:指定生成的人脸数据的保存路径
'''
name=input('my name:')
#拼接一个完整的路径
path=os.path.join(data,name)
#如果路径存在则删除路径
if os.path.isdir(path):
shutil.rmtree(path)
#创建文件夹
os.mkdir(path)
#创建一个级联分类器
# C:\Users\JC\AppData\Local\Programs\Python\Python37\Lib\site-packages\cv2\data\haarcascade_frontalface_default.xml
#似乎需要完整的路径,否则出错。
face_casecade=cv2.CascadeClassifier(r"C:\Users\JC\AppData\Local\Programs\Python\Python37\Lib\site-packages\cv2\data\haarcascade_frontalface_default.xml")
#打开摄像头
camera=cv2.VideoCapture(0)
cv2.namedWindow('Dynamic')
#计数
count=1
while(True):
#读取一帧图像
ret,frame=camera.read()
if ret:
#转换为灰度图
gray_img=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
#人脸检测
face=face_casecade.detectMultiScale(gray_img,1.3,5)
for (x,y,w,h) in face:
#在原图上绘制矩形
cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),2)
#调整图像大小
new_frame=cv2.resize(frame[y:y+h,x:x+w],(92,112))
#保存人脸
cv2.imwrite('%s/%s.png'%(path,str(count)),new_frame)
count+=1
cv2.imshow('Dynamic',frame)
#按下ESC键退出 或 已采集了128张图片
if cv2.waitKey(100) & 0xff==27 or count>128:
break
camera.release()
cv2.destroyAllWindows()
#载入图像 读取ORL人脸数据库,准备训练数据
def LoadImages(data):
'''
加载图片数据用于训练
params:
data:训练数据所在的目录,要求图片尺寸一样
ret:
images:[m,height,width] m为样本数,height为高,width为宽
names:名字的集合
labels:标签
'''
images=[]
names=[]
labels=[]
label=0
#遍历所有文件夹
for subdir in os.listdir(data):
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)
img=cv2.imread(imgpath,cv2.IMREAD_COLOR)
gray_img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
images.append(gray_img)
labels.append(label)
label+=1
images=np.asarray(images)
labels=np.asarray(labels)
return images,labels,names
#检验训练结果
def FaceRec(data):
#加载训练的数据
# X:images (多个人脸图像,如 张三 50张脸,李四 33个脸,王二麻子 35个脸)
# y:labels(似乎只是一个顺序号)
# names:names (即你输入的名字,可以识别多个人脸)
X,y,names=LoadImages(data)
##model这个位置把人弄死了,问题在于。。。?opencv-python 与 opencv-contrib-python 2个模块都要安装到位
##采用3.4.2.16版本,uninstall,install 搞几次,居然成了......
model = cv2.face.LBPHFaceRecognizer_create()
model.train(X,y)
#打开摄像头
camera=cv2.VideoCapture(0)
cv2.namedWindow('Dynamic')
#创建级联分类器
face_casecade=cv2.CascadeClassifier(r"C:\Users\JC\AppData\Local\Programs\Python\Python37\Lib\site-packages\cv2\data\haarcascade_frontalface_default.xml")
while(True):
#读取一帧图像 #ret:图像是否读取成功 #frame:该帧图像
ret,frame=camera.read()
#判断图像是否读取成功
if ret:
#转换为灰度图
gray_img=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
#利用级联分类器鉴别人脸
faces=face_casecade.detectMultiScale(gray_img,1.3,5)
#遍历每一帧图像,画出矩形
for (x,y,w,h) in faces:
frame=cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2) #蓝色
roi_gray=gray_img[y:y+h,x:x+w]
try:
#将图像转换为宽92 高112的图像
#resize(原图像,目标大小,(插值方法)interpolation=,)
roi_gray=cv2.resize(roi_gray,(92,112),interpolation=cv2.INTER_LINEAR)
params=model.predict(roi_gray)
#输出标签和可信度
print('Label:%s,confidence:%.2f'%(params[0],params[1]))
##putText:给照片添加文字 putText(输入图像,'所需添加的文字',左上角的坐标,字体,字体大小,颜色,字体粗细)
cv2.putText(frame,names[params[0]],(x,y-20),cv2.FONT_HERSHEY_SIMPLEX,1,255,2)
except:
continue
cv2.imshow('Dynamic',frame)
#按下ESC键退出
if cv2.waitKey(100) & 0xff==27:
break
camera.release()
cv2.destroyAllWindows()
if __name__=='__main__':
data=r'C:\Users\JC\Desktop\myCode\FaceTrack\FaceTrack\face'
generator(data)
FaceRec(data)