基于树莓派的人脸识别门禁系统(python+OpenCV+PyQt)
技术难点:
我这里将获取的人脸照片存放到一个文件夹里面,将训练好的yml文件存放在另一个文件夹下面,如下,Face_data 存放的是人脸照片,Face_training 存放的是训练好的 yml 文件,faceReco.py 就是源码文件了,这三个文件都在同一级目录下。直接使用代码创建存放文件夹和训练文件夹。
# 创建目录,将获取的人脸照片放入指定的文件夹
self.file = "./Face_data/"
while(True):
ret, self.img = self.cap.read()
# 垂直翻转视频图像
self.img = cv2.flip(self.img, -1)
# 灰度化处理
gray = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY)
faces = faceCascade2.detectMultiScale(gray, 1.3, 5)
# 判断是否存在文件夹如果不存在则创建为文件夹
self.folder = os.path.exists(self.file)
if not self.folder:
# makedirs 满权限创建文件时如果路径不存在会创建这个路径
os.makedirs(self.file)
os.chmod(self.file,0777)
for (x,y,w,h) in faces:
cv2.rectangle(self.img, (x,y), (x+w,y+h), (255,0,0), 2)
self.count += 1
# 将捕获的图像保存到指定的文件夹中
bool = cv2.imwrite(self.file + "/User." + str(self.Edit_ID.text()) + '.' + str(self.count) + ".png", gray[y:y+h,x:x+w])
# 取60张人脸样本,停止录像
if self.count >= 60:
print("OK!")
break
从数据集文件夹中载入训练图片,获取到人脸和id,整理成list并返回,人后调用函数进行训练
# 函数获取图像和标签数据
def getImagesAndLabels(path):
imagePaths = [os.path.join(path,f) for f in os.listdir(path)]
faceSamples=[]
ids = []
self.progressBar.setProperty("value", 65)
for imagePath in imagePaths:
# 转换为灰度
PIL_img = Image.open(imagePath).convert('L')
img_numpy = np.array(PIL_img,'uint8')
id = int(os.path.split(imagePath)[-1].split(".")[1])
faces = faceCascade3.detectMultiScale(img_numpy)
for (x,y,w,h) in faces:
faceSamples.append(img_numpy[y:y+h,x:x+w])
ids.append(id)
return faceSamples,ids
self.progressBar.setProperty("value", 75)
print ("\n [INFO] Training faces. It will take a few seconds. Wait ...")
# 调用函数,传递文件夹路径参数
faces,ids = getImagesAndLabels(self.file)
# 训练人脸
self.recognizer.train(faces, np.array(ids))
self.progressBar.setProperty("value", 85)
# 创建文件夹
self.triningfile = "./Face_training/"
self.folder1 = os.path.exists(self.triningfile)
if not self.folder1:
os.makedirs(self.triningfile)
os.chmod(self.triningfile,0777)
# 将训练好的数据保存到指定文件夹中
self.recognizer.write(self.triningfile + "/trainer.yml")
# 打印经过训练的人脸编号和结束程序
print("\n [INFO] {0} faces trained. Exiting Program".format(len(np.unique(ids))))
self.progressBar.setProperty("value", 100)