首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

打造本地人脸门禁系统(二)——训练AI

本期我们要用在《打造本地人脸门禁系统(一)——数据采集》中获得的人脸照片灰度图对AI进行训练,并用AI控制门禁。

1.用照片进行数据训练

新建第二个程序“02Train_Face.py”,先导入库:“import cv2”“import os”“import numpy as np”和“from PIL import Image”;建立变量recognizer,赋值为“cv2.face.LBPHFaceRecognizer_create()”,作用是使用LBPH(Local Binary Patterns Histograms:局部二进制编码直方图)算法生成LBPH人脸识别器的实例模型,也就是先以每个像素为中心去判断自己与周围像素灰度值的大小关系并进行二进制编码,获得整幅图像的LBP编码图像,最终通过比较不同的人脸图像LBP编码直方图来实现人脸识别;建立变量detector,赋值为“cv2.CascadeClassifier("haarcascade_frontalface_default.xml")”,作用是加载调用人脸检测分类器,类似于上一步的使用人脸检测的级联分类器读取识别检测模型haarcascade_frontalface_default.xml文件。

接下来,使用def自定义get_images_and_labels(path)函数,其中的参数path是文件路径。建立变量image_paths,赋值为“[os.path.join(path,f) for f in os.listdir(path)]”,作用是返回当前路径下的文件名列表;再建立face_samples和ids两个空列表,通过“for image_path in image_paths”循环,完成图片文件的读取转换以及数据取样训练等功能,最终通过return语句返回变量face_samples和ids的值;最后,将保存人脸照片的PicData文件夹名称作为参数传入函数:get_images_and_labels("PicData"),通过变量faces和ids对应获取函数中face_samples和ids的返回值;再将faces和ids传入recognizer.train()中进行训练:“recognizer.train(faces,np.array(ids))”,训练结束后将生成的训练数据trainner.yml文件保存至Data文件夹中:“recognizer.save("Data/trainner.yml")”(如图1)。     

运行程序,一段时间之后(与第一步人脸采集的照片数量有关),在Data文件夹中就会有trainner.yml文件生成,其中的内容就是根据人脸照片进行各种特征信息提取的数据,这个yml文件就是第三步进行人脸识别的“纲领”(如图2)。

2.加载训练数据进行人脸识别及门禁动作控制

新建第三个程序“03Recognize_Face.py”,先导入待用的各种库模块:“import cv2”“import time”“from pinpong.board import Board,Pin,Servo”;接着,进行外设硬件及人脸识别的初始化操作:初始化主板型号为树莓派:“Board("rpi").begin()”;红色、黄色和绿色LED灯分别接在扩展板的5号、6号和12号引脚,均设置为数字输出状态:“Red_LED = Pin(Pin.D5,Pin.OUT)”“Yellow_LED = Pin(Pin.D6,Pin.OUT)”“Green_LED = Pin(Pin.D12,Pin.OUT)”;初始化连接在18号引脚的舵机:“Door_Control = Servo(Pin(Pin.D18))”,并且将其横杆的默认状态设置为0度关门:“Door_Control.write_angle(0)”;再将红色和绿色LED灯的默认状态设置为关闭:“Red_LED.value(0)”“Green_LED.value(0)”。

建立变量recognizer,赋值为“cv2.face.LBPHFaceRecognizer_create()”,作用是准备好人脸识别方法,并且读取并调用第二步训练好的trainner.yml文件:“recognizer.read('Data/trainner.yml')”;建立变量faceCascade,赋值为“cv2.CascadeClassifier("haarcascade_frontalface_default.xml")”,作用是再次调用人脸分类器haarcascade_frontalface_default.xml文件;建立变量font,赋值为“cv2.FONT_HERSHEY_SIMPLEX”,作用是加载正常大小的无衬线字体;语句“idnum = 1”的作用是设置与ID号对应的用户名,语句“names = ['Master']”的作用是人脸识别结果满足设置条件时的显示用户标识,如果之前采集和训练的人脸数目不止一人的话,此时可设置对应用户的名称(比如“ZhangSan”“LiSi”等);然后,调用摄像头进行人脸捕获:“cam = cv2.VideoCapture(0)”“minW = 0.1*cam.get(3)”“minH = 0.1*cam.get(4)”。

接下来,使用def自定义open_close_door()函数,实现的功能是控制红绿灯模块和舵机执行人脸识别成功之后的动作——先亮红灯并有文字提示:“Red_LED.value(1)”“print("正在开门中...")”,循环“for i in range(0,91,15)”的主体语句是“Door_Control.write_angle(i)”和“time.sleep(1)”,作用是控制舵机每次逆时针转动15度、停顿1秒钟,6次循环结束后,舵机的门禁杆会从之前的0度转至90度停止;然后,警示红灯熄灭、亮通行指示的绿灯,并且有文字提示信息出现,时间周期为7秒钟:“Red_LED.value(0)”“Green_LED.value(1)”“print("请通行...")”“time.sleep(7)”;通行结束后,绿灯熄灭、红灯亮起,并且仍有文字提示:“Green_LED.value(0)”“Red_LED.value(1)”“print("正在关门中...")”;再次通过类似的循环“for i in range(91,0,-15)”,控制舵机从90度顺时针方向恢复至0度:“Door_Control.write_angle(i)”“time.sleep(1)”,结束后熄灭红灯:“Red_LED.value(0)”(如图3)。

在“while True”循环结构中,先设置黄灯为熄灭状态:“Yellow_LED.value(0)”,再从摄像头读取视频画面并进行灰度转换:“ret, img = cam.read()”“gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)”;接下来的人脸检测“faces = faceCascade.detectMultiScale”以及循环“for (x,y,w,h) in faces”与第二步类似,而且基本上都是OpenCV编程调用的固定用法,在此不再赘述。值得一提的是,循环中的“if confidence >=80”选择结构是对人脸识别置信度进行判断,如果条件成立,表示识别出的人脸是“合法用户”,则执行开门通行open_close_door()函数,否则便会在人脸区域标注“Stranger!”(陌生人);每次循环均设置有0.2秒钟的停顿,控制黄灯在未识别出正常人脸时不停闪烁;同样,检测期间可随时通过按下字母“q”键进行程序的退出和资源的释放以及监测窗口的关闭等操作:“if cv2.waitKey(10) & 0xFF == ord("q"):break”“cam.release()”“cv2.destroyAllWindows()”(如图4)。

3.测试本地人脸门禁系统是否正常工作

运行程序“03Recognize_Face.py”,舵机会保持在0度水平位置(禁行状态),同时黄灯会不停闪烁;尝试在摄像头前拍照,如果识别出的人脸置信度低于设置的80%,摄像头即时预览画面中的人脸区域顶端显示为“Stranger!”,同时左下角显示其识别置信度为79%,黄灯持续闪烁,舵机无动作(如图5)。

再次尝试,当显示的人脸置信度显示为84%(不低于80%)时,人脸区域顶端的显示提示信息变为“[‘Master’]”(主人),此时的红灯会亮起,舵机控制门杆逐渐从0度转至90度,接着绿灯亮起(红灯熄灭),此时,“合法用户”有7秒钟的时间通过门禁(同时在屏幕上也有对应的文字提示信息出现);然后红灯亮起(绿灯熄灭),舵机控制门杆从90度反方向恢复至0度,再次进入黄灯闪烁的人脸检测状态(如图6)。

编辑|张毅

审核|吴新

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OP4trAi6M0TqdrNuIhKfIYTA0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券