使用Tensorflow实现的MTCNN和MobileFaceNet实现的人脸识别系统GUI界面 附代码 详细教程

本文涉及的产品
视觉智能开放平台,图像资源包5000点
视觉智能开放平台,视频资源包5000点
视觉智能开放平台,分割抠图1万点
简介: 使用Tensorflow实现的MTCNN和MobileFaceNet实现的人脸识别系统GUI界面 附代码 详细教程

代码:https://download.csdn.net/download/qq_38735017/87425916


前言


本教程是教程是介绍如何使用 Tensorflow 实现的 MTCNN 和 MobileFaceNet 实现的人脸识别,并不介绍如何训练模型。关于如何训练 MTCNN 和 MobileFaceNet,这两个模型都是比较轻量的模型,所以就算这两个模型在 CPU 环境下也有比较好的预测速度,众所周知,笔者比较喜欢轻量级的模型,如何让我从准确率和预测速度上选择,我会更倾向于速度,因本人主要是研究深度学习在移动设备等嵌入式设备上的的部署。好了,下面就来介绍如何实现这两个模型实现三种人脸识别,使用路径进行人脸注册和人脸识别,使用摄像头实现人脸注册和人脸识别,通过 HTTP 实现人脸注册和人脸识别。


本地人脸图像识别


本地人脸图像识别就是要通过路径读取本地的图像进行人脸注册或者人脸识别,对应的代码为 path_infer.py。首先要加载好人脸识别的两个模型,一个是人脸检测和关键点检测模型 MTCNN 和人脸识别模型 MobileFaceNet,加载这两个模型已经封装在一个工具中了,方便加载。 然后 add_faces() 这个函数是从 temp 路径中读取手动添加的图片的人脸库中,具体来说,例如你有 100 张已经用人脸中对应人名字来命名图片文件名,但是你不能直接添加到人脸库 face_db 中,因为人脸库中是存放经过 MTCNN 模型处理过的图片,所以大规模添加人脸图片需要通过暂存在 temp 文件夹中的方式来然程序自动添加。最后是读取人脸库中图像,通过 MobileFaceNet 预测获取每张人脸的特征值存放在到一个列表中,等着之后的人脸对比识别。


# 检测人脸检测模型mtcnn_detector=load_mtcnn()# 加载人脸识别模型face_sess,inputs_placeholder,embeddings=load_mobilefacenet()# 添加人脸add_faces(mtcnn_detector)# 加载已经注册的人脸faces_db=load_faces(face_sess,inputs_placeholder,embeddings)


人脸注册是通过图像路径读取人脸图像,然后使用 MTCNN 检测图像中的人脸,并通过人脸关键点进行人脸对齐,最后裁剪并缩放成 112*112 的图片,并以注册名命名文件存储在人脸库中。

defface_register(img_path,name):image=cv2.imdecode(np.fromfile(img_path,dtype=np.uint8),1)faces,landmarks=mtcnn_detector.detect(image)iffaces.shape[0]isnot0:faces_sum=0bbox=[]points=[]fori,faceinenumerate(faces):ifround(faces[i,4],6)>0.95:bbox=faces[i,0:4]points=landmarks[i,:].reshape((5,2))faces_sum+=1iffaces_sum==1:nimg=face_preprocess.preprocess(image,bbox,points,image_size='112,112')cv2.imencode('.png',nimg)[1].tofile('face_db/%s.png'%name)print("注册成功!")else:print('注册图片有错,图片中有且只有一个人脸')else:print('注册图片有错,图片中有且只有一个人脸')

人脸识别是通过图像路径读取将要识别的人脸,通过经过 MTCNN 的检测人脸和对其,在使用 MobileFaceNet 预测人脸的特征,最终得到特征和人脸库中的特征值比较相似度,最终得到阈值超过 0.6 的最高相似度结果,对应的名称就是该人脸识别的结果。最后把结果在图像中画框和标记上名称并显示出来。

defface_recognition(img_path):image=cv2.imdecode(np.fromfile(img_path,dtype=np.uint8),1)faces,landmarks=mtcnn_detector.detect(image)iffaces.shape[0]isnot0:faces_sum=0fori,faceinenumerate(faces):ifround(faces[i,4],6)>0.95:faces_sum+=1iffaces_sum>0:# 人脸信息info_location=np.zeros(faces_sum)info_location[0]=1info_name=[]probs=[]# 提取图像中的人脸input_images=np.zeros((faces.shape[0],112,112,3))fori,faceinenumerate(faces):ifround(faces[i,4],6)>0.95:bbox=faces[i,0:4]points=landmarks[i,:].reshape((5,2))nimg=face_preprocess.preprocess(image,bbox,points,image_size='112,112')nimg=nimg-127.5nimg=nimg*0.0078125input_images[i,:]=nimg# 进行人脸识别feed_dict={inputs_placeholder:input_images}emb_arrays=face_sess.run(embeddings,feed_dict=feed_dict)emb_arrays=sklearn.preprocessing.normalize(emb_arrays)fori,embeddinginenumerate(emb_arrays):embedding=embedding.flatten()temp_dict={}# 比较已经存在的人脸数据库forcom_faceinfaces_db:ret,sim=feature_compare(embedding,com_face["feature"],0.70)temp_dict[com_face["name"]]=simdict=sorted(temp_dict.items(),key=lambdad:d[1],reverse=True)ifdict[0][1]>VERIFICATION_THRESHOLD:name=dict[0][0]probs.append(dict[0][1])info_name.append(name)else:probs.append(dict[0][1])info_name.append("unknown")forkinrange(faces_sum):# 写上人脸信息x1,y1,x2,y2=faces[k][0],faces[k][1],faces[k][2],faces[k][3]x1=max(int(x1),0)y1=max(int(y1),0)x2=min(int(x2),image.shape[1])y2=min(int(y2),image.shape[0])prob='%.2f'%probs[k]label="{}, {}".format(info_name[k],prob)cv2img=cv2.cvtColor(image,cv2.COLOR_BGR2RGB)pilimg=Image.fromarray(cv2img)draw=ImageDraw.Draw(pilimg)font=ImageFont.truetype('font/simfang.ttf',18,encoding="utf-8")draw.text((x1,y1-18),label,(255,0,0),font=font)image=cv2.cvtColor(np.array(pilimg),cv2.COLOR_RGB2BGR)cv2.rectangle(image,(x1,y1),(x2,y2),(255,0,0),2)cv2.imshow('image',image)cv2.waitKey(0)cv2.destroyAllWindows()

最后的动时选择是人脸注册还是人脸识别。

if__name__=='__main__':i=int(input("请选择功能,1为注册人脸,2为识别人脸:"))image_path=input("请输入图片路径:")ifi==1:user_name=input("请输入注册名:")face_register(image_path,user_name)elifi==2:face_recognition(image_path)else:print("功能选择错误")

日志输出如下:

loaded face: 张伟.png
loaded face: 迪丽热巴.png
请选择功能,1为注册人脸,2为识别人脸:1
请输入图片路径:test.png
请输入注册名:夜雨飘零
注册成功!

识别效果图:

4f6eb356866be3241bb635ab164b8f16.jpg

相机人脸识别


在 camera_infer.py 实现使用相机的人脸识别,通过调用相机获取图像,进行人脸注册和人脸识别,在使用人脸注册或者人脸识别之前,同样先加载人脸检测模型 MTCNN 和 MobileFaceNet,并将临时 temp 文件夹中的人脸经过 MTCNN 处理添加到人脸库中,最后把人脸库中的人脸使用 MobileFaceNet 预测得到特征值,并报特征值和对应的人脸名称存放在列表中。

# 检测人脸检测模型mtcnn_detector=load_mtcnn()# 加载人脸识别模型face_sess,inputs_placeholder,embeddings=load_mobilefacenet()# 添加人脸add_faces(mtcnn_detector)# 加载已经注册的人脸faces_db=load_faces(face_sess,inputs_placeholder,embeddings)

通过使用摄像头实时获取图像,在人脸注册这里当摄像头拍摄到人脸之后,可以点击 y 键拍照,拍照获得到图片之后,需要经过 MTCNN 检测判断是否存在人脸,检测成功之后,会对人脸进行裁剪并以注册名直接存储在人脸库中 face_db。

defface_register():print("点击y确认拍照!")cap=cv2.VideoCapture(0)whileTrue:ret,frame=cap.read()ifret:cv2.imshow('image',frame)ifcv2.waitKey(1)&0xFF==ord('y'):faces,landmarks=mtcnn_detector.detect(frame)iffaces.shape[0]isnot0:faces_sum=0bbox=[]points=[]fori,faceinenumerate(faces):ifround(faces[i,4],6)>0.95:bbox=faces[i,0:4]points=landmarks[i,:].reshape((5,2))faces_sum+=1iffaces_sum==1:nimg=face_preprocess.preprocess(frame,bbox,points,image_size='112,112')user_name=input("请输入注册名:")cv2.imencode('.png',nimg)[1].tofile('face_db/%s.png'%user_name)print("注册成功!")else:print('注册图片有错,图片中有且只有一个人脸')else:print('注册图片有错,图片中有且只有一个人脸')break

在人脸识别中,通过调用摄像头实时获取图像,通过使用 MTCNN 检测人脸的位置,并使用 MobileFaceNet 进行识别,最终在图像上画框并写上识别的名字,结果会跟着摄像头获取的图像实时识别的。

defface_recognition():cap=cv2.VideoCapture(0)whileTrue:ret,frame=cap.read()ifret:faces,landmarks=mtcnn_detector.detect(frame)iffaces.shape[0]isnot0:faces_sum=0fori,faceinenumerate(faces):ifround(faces[i,4],6)>0.95:faces_sum+=1iffaces_sum==0:continue# 人脸信息info_location=np.zeros(faces_sum)info_location[0]=1info_name=[]probs=[]# 提取图像中的人脸input_images=np.zeros((faces.shape[0],112,112,3))fori,faceinenumerate(faces):ifround(faces[i,4],6)>0.95:bbox=faces[i,0:4]points=landmarks[i,:].reshape((5,2))nimg=face_preprocess.preprocess(frame,bbox,points,image_size='112,112')nimg=nimg-127.5nimg=nimg*0.0078125input_images[i,:]=nimg# 进行人脸识别feed_dict={inputs_placeholder:input_images}emb_arrays=face_sess.run(embeddings,feed_dict=feed_dict)emb_arrays=sklearn.preprocessing.normalize(emb_arrays)fori,embeddinginenumerate(emb_arrays):embedding=embedding.flatten()temp_dict={}# 比较已经存在的人脸数据库forcom_faceinfaces_db:ret,sim=feature_compare(embedding,com_face["feature"],0.70)temp_dict[com_face["name"]]=simdict=sorted(temp_dict.items(),key=lambdad:d[1],reverse=True)ifdict[0][1]>VERIFICATION_THRESHOLD:name=dict[0][0]probs.append(dict[0][1])info_name.append(name)else:probs.append(dict[0][1])info_name.append("unknown")forkinrange(faces_sum):# 写上人脸信息x1,y1,x2,y2=faces[k][0],faces[k][1],faces[k][2],faces[k][3]x1=max(int(x1),0)y1=max(int(y1),0)x2=min(int(x2),frame.shape[1])y2=min(int(y2),frame.shape[0])prob='%.2f'%probs[k]label="{}, {}".format(info_name[k],prob)cv2img=cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)pilimg=Image.fromarray(cv2img)draw=ImageDraw.Draw(pilimg)font=ImageFont.truetype('font/simfang.ttf',18,encoding="utf-8")draw.text((x1,y1-18),label,(255,0,0),font=font)frame=cv2.cvtColor(np.array(pilimg),cv2.COLOR_RGB2BGR)cv2.rectangle(frame,(x1,y1),(x2,y2),(255,0,0),2)cv2.imshow('image',frame)ifcv2.waitKey(1)&0xFF==ord('q'):break

在启动程序中,通过选择功能,选择注册人脸或者是识别人脸。

if__name__=='__main__':i=int(input("请选择功能,1为注册人脸,2为识别人脸:"))ifi==1:face_register()elifi==2:face_recognition()else:print("功能选择错误")

日志输出如下:

loaded face: 张伟.png
loaded face: 迪丽热巴.png
请选择功能,1为注册人脸,2为识别人脸:1
点击y确认拍照!
请输入注册名:夜雨飘零
注册成功!


识别效果图:

10eb2a37e96a1b4cebc390aa84064906.jpg


通过服务接口识别


程序在 server_main.py 中实现,通过使用 Flask 提供网络服务接口,如果要允许跨域访问需要设置 CORS(app),本程序虽然是默认开启跨域访问,但是为了可以在浏览器上调用摄像头,启动的 host 设置为 localhost。另外还要加载 MTCNN 模型和 MobileFaceNet 模型,并报人脸库的图像加载到程序中。

app=Flask(__name__)# 允许跨越访问CORS(app)# 人脸识别阈值VERIFICATION_THRESHOLD=config.VERIFICATION_THRESHOLD# 检测人脸检测模型mtcnn_detector=load_mtcnn()# 加载人脸识别模型face_sess,inputs_placeholder,embeddings=load_mobilefacenet()# 加载已经注册的人脸faces_db=load_faces(face_sess,inputs_placeholder,embeddings)

提供一个 /register 的人脸注册接口,通过表单上传的图像和注册名,经过 MTCNN 检测,是否包含人脸,如果注册成功,将会把图像裁剪并储存在人脸库中 face_db。并更新已经加载的人脸库,注意这是全部重新读取更新。


@app.route("/register",methods=['POST'])defregister():globalfaces_dbupload_file=request.files['image']user_name=request.values.get("name")ifupload_file:try:image=cv2.imdecode(np.frombuffer(upload_file.read(),np.uint8),cv2.IMREAD_UNCHANGED)faces,landmarks=mtcnn_detector.detect(image)iffaces.shape[0]isnot0:faces_sum=0bbox=[]points=[]fori,faceinenumerate(faces):ifround(faces[i,4],6)>0.95:bbox=faces[i,0:4]points=landmarks[i,:].reshape((5,2))faces_sum+=1iffaces_sum==1:nimg=face_preprocess.preprocess(image,bbox,points,image_size='112,112')cv2.imencode('.png',nimg)[1].tofile('face_db/%s.png'%user_name)# 更新人脸库faces_db=load_faces(face_sess,inputs_placeholder,embeddings)returnstr({"code":0,"msg":"success"})returnstr({"code":3,"msg":"image not or much face"})except:returnstr({"code":2,"msg":"this file is not image or not face"})else:returnstr({"code":1,"msg":"file is None"})

提供 /recognition 人脸识别接口,通过上传图片进行人脸识别,把识别的结果返回给用户,返回的结果不仅包括的识别的名字,还包括人脸框和关键点。因为也提供了一个 is_chrome_camera 参数,这个是方便在浏览器上调用摄像头获取图像进行预测,因为如果直接把浏览器拍摄到的图像直接预测会出现错误,所以如果是浏览器拍照识别,需要先存储起来,然后重新读取。

@app.route("/recognition",methods=['POST'])defrecognition():start_time1=time.time()upload_file=request.files['image']is_chrome_camera=request.values.get("is_chrome_camera")ifupload_file:try:img=cv2.imdecode(np.frombuffer(upload_file.read(),np.uint8),cv2.IMREAD_UNCHANGED)# 兼容浏览器摄像头拍照识别ifis_chrome_camera=="True":cv2.imwrite('test.png',img)img=cv2.imdecode(np.fromfile('test.png',dtype=np.uint8),1)except:returnstr({"error":2,"msg":"this file is not image"})try:info_name,probs,info_bbox,info_landmarks=recognition_face(img)ifinfo_nameisNone:returnstr({"error":3,"msg":"image not have face"})except:returnstr({"error":3,"msg":"image not have face"})# 封装识别结果data_faces=[]foriinrange(len(info_name)):data_faces.append({"name":info_name[i],"probability":probs[i],"bbox":list_to_json(np.around(info_bbox[i],decimals=2).tolist()),"landmarks":list_to_json(np.around(info_landmarks[i],decimals=2).tolist())})data=str({"code":0,"msg":"success","data":data_faces}).replace("'",'"')print('duration:[%.0fms]'%((time.time()-start_time1)*1000),data)returndataelse:returnstr({"error":1,"msg":"file is None"})

在 templates 目录下创建 index.html 文件,主要是以下两个表单和一个拍摄实时显示的 video,拍照的图像在 canvas 显示,最后上传。

<formaction="/register"enctype="multipart/form-data"method="post">
    注册人脸:<inputtype="file"requiredaccept="image/*"name="image"><br>
    注册名称:<inputtype="text"name="name"><br><inputtype="submit"value="上传"></form><br/><br/><br/><formaction="/recognition"enctype="multipart/form-data"method="post">
    预测人脸:<inputtype="file"requiredaccept="image/*"name="image"><br><inputtype="submit"value="上传"></form><br/><br/><br/><videoid="video"width="640"height="480"autoplay></video><buttonid="snap">拍照</button><br/><br/><canvasid="canvas"width="640"height="480"></canvas><buttonid="upload">上传</button>

通过下面启动整个服务。

@app.route('/')defhome():returnrender_template("index.html")if__name__=='__main__':app.run(host=config.HOST,port=config.POST)

日志输出如下:

loaded face: 张伟.png
loaded face: 迪丽热巴.png
 * Serving Flask app "server_main" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://localhost:5000/ (Press CTRL+C to quit)

页面图:

0106e3446f98b028b2150ae3c1a76c1f.jpg


识别返回结果:


431f3a7c141b6a41991b91068d125edd.jpg


相关文章
|
8天前
|
机器学习/深度学习 人工智能 算法
猫狗宠物识别系统Python+TensorFlow+人工智能+深度学习+卷积网络算法
宠物识别系统使用Python和TensorFlow搭建卷积神经网络,基于37种常见猫狗数据集训练高精度模型,并保存为h5格式。通过Django框架搭建Web平台,用户上传宠物图片即可识别其名称,提供便捷的宠物识别服务。
126 55
|
2月前
|
并行计算 Shell TensorFlow
Tensorflow-GPU训练MTCNN出现错误-Could not create cudnn handle: CUDNN_STATUS_NOT_INITIALIZED
在使用TensorFlow-GPU训练MTCNN时,如果遇到“Could not create cudnn handle: CUDNN_STATUS_NOT_INITIALIZED”错误,通常是由于TensorFlow、CUDA和cuDNN版本不兼容或显存分配问题导致的,可以通过安装匹配的版本或在代码中设置动态显存分配来解决。
58 1
Tensorflow-GPU训练MTCNN出现错误-Could not create cudnn handle: CUDNN_STATUS_NOT_INITIALIZED
|
2月前
|
计算机视觉 Python
基于Dlib的人脸识别客户端(UI界面)
基于Dlib的人脸识别客户端(UI界面)
71 2
|
2月前
|
机器学习/深度学习 TensorFlow 算法框架/工具
【大作业-04】手把手教你构建垃圾分类系统-基于tensorflow2.3
本文介绍了基于TensorFlow 2.3的垃圾分类系统,通过B站视频和博客详细讲解了系统的构建过程。系统使用了包含8万张图片、245个类别的数据集,训练了LeNet和MobileNet两个卷积神经网络模型,并通过PyQt5构建了图形化界面,用户上传图片后,系统能识别垃圾的具体种类。此外,还提供了模型和数据集的下载链接,方便读者复现实验。垃圾分类对于提高资源利用率、减少环境污染具有重要意义。
78 0
【大作业-04】手把手教你构建垃圾分类系统-基于tensorflow2.3
|
3月前
|
机器学习/深度学习 算法 TensorFlow
动物识别系统Python+卷积神经网络算法+TensorFlow+人工智能+图像识别+计算机毕业设计项目
动物识别系统。本项目以Python作为主要编程语言,并基于TensorFlow搭建ResNet50卷积神经网络算法模型,通过收集4种常见的动物图像数据集(猫、狗、鸡、马)然后进行模型训练,得到一个识别精度较高的模型文件,然后保存为本地格式的H5格式文件。再基于Django开发Web网页端操作界面,实现用户上传一张动物图片,识别其名称。
112 1
动物识别系统Python+卷积神经网络算法+TensorFlow+人工智能+图像识别+计算机毕业设计项目
|
17天前
|
机器学习/深度学习 人工智能 算法
【宠物识别系统】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+图像识别
宠物识别系统,本系统使用Python作为主要开发语言,基于TensorFlow搭建卷积神经网络算法,并收集了37种常见的猫狗宠物种类数据集【'阿比西尼亚猫(Abyssinian)', '孟加拉猫(Bengal)', '暹罗猫(Birman)', '孟买猫(Bombay)', '英国短毛猫(British Shorthair)', '埃及猫(Egyptian Mau)', '缅因猫(Maine Coon)', '波斯猫(Persian)', '布偶猫(Ragdoll)', '俄罗斯蓝猫(Russian Blue)', '暹罗猫(Siamese)', '斯芬克斯猫(Sphynx)', '美国斗牛犬
104 29
【宠物识别系统】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+图像识别
|
1月前
|
机器学习/深度学习 人工智能 算法
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络
垃圾识别分类系统。本系统采用Python作为主要编程语言,通过收集了5种常见的垃圾数据集('塑料', '玻璃', '纸张', '纸板', '金属'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对图像数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。然后使用Django搭建Web网页端可视化操作界面,实现用户在网页端上传一张垃圾图片识别其名称。
79 0
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络
|
1月前
|
机器学习/深度学习 人工智能 算法
基于深度学习的【蔬菜识别】系统实现~Python+人工智能+TensorFlow+算法模型
蔬菜识别系统,本系统使用Python作为主要编程语言,通过收集了8种常见的蔬菜图像数据集('土豆', '大白菜', '大葱', '莲藕', '菠菜', '西红柿', '韭菜', '黄瓜'),然后基于TensorFlow搭建卷积神经网络算法模型,通过多轮迭代训练最后得到一个识别精度较高的模型文件。在使用Django开发web网页端操作界面,实现用户上传一张蔬菜图片识别其名称。
89 0
基于深度学习的【蔬菜识别】系统实现~Python+人工智能+TensorFlow+算法模型
|
3月前
|
机器学习/深度学习 人工智能 算法
鸟类识别系统Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+ResNet50算法模型+图像识别
鸟类识别系统。本系统采用Python作为主要开发语言,通过使用加利福利亚大学开源的200种鸟类图像作为数据集。使用TensorFlow搭建ResNet50卷积神经网络算法模型,然后进行模型的迭代训练,得到一个识别精度较高的模型,然后在保存为本地的H5格式文件。在使用Django开发Web网页端操作界面,实现用户上传一张鸟类图像,识别其名称。
120 12
鸟类识别系统Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+ResNet50算法模型+图像识别
|
3月前
|
机器学习/深度学习 算法 TensorFlow
交通标志识别系统Python+卷积神经网络算法+深度学习人工智能+TensorFlow模型训练+计算机课设项目+Django网页界面
交通标志识别系统。本系统使用Python作为主要编程语言,在交通标志图像识别功能实现中,基于TensorFlow搭建卷积神经网络算法模型,通过对收集到的58种常见的交通标志图像作为数据集,进行迭代训练最后得到一个识别精度较高的模型文件,然后保存为本地的h5格式文件。再使用Django开发Web网页端操作界面,实现用户上传一张交通标志图片,识别其名称。
127 6
交通标志识别系统Python+卷积神经网络算法+深度学习人工智能+TensorFlow模型训练+计算机课设项目+Django网页界面

热门文章

最新文章