【写在前面:笔者是一个才接触python半年之久的编程菜鸡,刚好这学期的课程需要用到python做一些有关计算机视觉的设计,于是就根据自己所学,同时借鉴了一些CSDN上各位大佬的思路和代码,做了一个简单的涉及人脸识别,口罩识别,口罩下人脸预测的小系统。一是作为学习记录,二是希望对大家有点帮助,对于不足之处,也希望各路大佬可以不吝赐教。本文为作者原创文章,文中所示的图片、代码皆来自网络或笔者自制,仅做学习、记录使用,如果某些东西涉及侵权,请作者大大告知笔者,可以对此进行补充说明。如有人私自引入商业使用构成侵权或违法犯罪,则笔者概不负责。】

目 录

  • 一、先看一下实现的核心效果
  • 二、原理介绍
    • 2.1人脸识别
    • 2.2口罩识别
    • 2.3人脸补全
    • 2.4交互界面
  • 三、系统实现过程中的思考和遇到的问题
    • 3.1是否戴口罩的判定问题
    • 3.2人脸补全时的问题
      • 3.2.1人脸补全的详细过程
      • 3.2.2人脸补全过程中的问题及选择
    • 3.3交互界面的问题
  • 四、总结
  • 五、完整代码
    • 1、主程序
    • 2、人脸预测(sklearn的方法)
    • 3、用于训练模型的原始人脸数据处理
  • 【参考资料】

完整代码在文章后面有
源文件:
1、(代币充足的老板麻烦点这个,赏个代币,谢谢谢谢老板!!!!)CSDN下载地址
2、(像我一样没币的就百度盘吧,哭了…)百度网盘 提取码:gno7
3、 GitHub等以后有机会再传吧

一、先看一下实现的核心效果

首先是UI交互界面,本来想用个HTML做的,但是由于HTML与python的交互过于复杂,时间不大够,所以最后就做了个简单的。效果如下

人脸识别部分的实现情况比较正常,用opencv库提供的xml,实现情况如下

口罩识别则用的博主Cheney-渣渣杰训练出来的xml,效果如下

最后就是口罩预测部分,效果如下

二、原理介绍

2.1人脸识别

人脸识别是计算机视觉中一个相对完整的模块,基本上所有学习计算机视觉的课程都会涉及到人脸识别这块的内容。在百度百科中是这么定义的:人脸识别,是基于人的脸部特征信息进行身份识别的一种生物识别技术。用摄像机或摄像头采集含有人脸的图像或视频流,并自动在图像中检测和跟踪人脸,进而对检测到的人脸进行脸部识别的一系列相关技术,通常也叫做人像识别、面部识别。

简单来说,这就是图像识别的一个部分,利用图像差值等图像处理的方法,对具有特定特征的图像进行提取,然后再将这些特征信息保存好,在需要的时候,就可以调用该文件中保存好的训练特征,对目标图像进行匹配,从而找出在图像中我们所需要的特征。就比如在这个系统中的人脸。

具体的算法和方程在此我就不写了,大家找找文献和博客应该有很多很详细的方法介绍。

然后在这个系统中,主要是用博主柒澈言写的人脸识别之笑脸检测中的代码为主体框架搭建的。细节之处再根据具体需求具体改。

2.2口罩识别

口罩识别的具体方法同人脸识别大抵相同。这个系统中用的是博主Cheney-渣渣杰训练出来的数据,用起来效果一般,从他的博文中也可以看到,由于也是今年疫情这种大环境下的突发奇想,所以训练的数据量并不算很大,导致最终识别口罩时稍微有一点不灵敏。不过还是很感谢他的分享(至少不用我自己练数据了嘿嘿),用来做个作业够用了。详细的情况可以去他的博客看看。对识别精度有要求的朋友建议另找一下其他训练数据。

然而对于口罩识别这块的实现,最初我是想了两种解决方法的,第一是能够直接找到这种训练好的数据自然是最好的,实在不行自己训练就比较麻烦。第二是识别眼睛,直接使用opencv中开源出来的文件,去识别眼睛,然后在画框的时候画多一点就好了。

但是经过测试,opencv中开源的文件去识别眼睛、额头等都识别的不算好(好吧个人觉得识别效果巨烂),且如果用这个逻辑去写,会出现两个问题。其一是识别精度不高,容易产生误判,这没什么好说的,精度问题;其二是说不定只是露个眼睛出来,然后被识别到了判定成戴口罩,这就会带来两个结果,好的地方是,如果识别精度够高,我们只需要很少的特征就可以判定这个是不是人,且判断是否为全脸(用于后期补全),不好的地方则是,误判几率会很大,比如给个侧脸,识别到了眼睛,然后就被判定为带口罩了。

所以综合考虑,第一种方法的时间复杂度比较小,难度也比较小(找到了训练好的数据简直不能更舒服),所以选择执行第一种方案。

2.3人脸补全

人脸补全这一块用的是python中的sklearn库,可以说是数据处理中的一个经典库。

其主要原理就是机器学习,机器学习分为有监督学习和无监督学习,人脸补全是属于有监督学习的一种(上面说的识别应该也是监督学习的一种)。具体公式性的算法解释我也不在这写了,网上资料蛮全的。

实现思路大概是这样的,由于人在带上口罩后也就遮住了鼻子往下的部分,大致上可以看成是上下对半开的脸,上半部分露出来,下半部分被挡住。这样一来,我们就可以用人脸补全的方法进行补全。首先用原始图像训练模型,然后将识别出来的戴口罩的人脸图像截出来,将图像规格修改成训练图像相同的图像,然后代回到模型中进行预测就可以了,其大致流程与网络毒刘的这篇文章基本一致,这套代码基本上算是满大街都是了,是很经典的一个机器学习的例子。所以在笔者设计的这个系统中,将其稍加修改就可以用来预测人脸了。

2.4交互界面

这个部分算是整个系统中最简单的一个部分,直接调用easygui库就可以了。使用起来也很简单,一行代码搞定,不得不说Life is short,use python诚不欺我。

三、系统实现过程中的思考和遇到的问题

首先附上流程草图(时间不够,只完成了一条线,后续部分以后有时间再补)

3.1是否戴口罩的判定问题

按照正常的逻辑来讲,这一步只需要一个if结构就可以了,但是在实际实现的过程中,笔者发现opencv的识别人脸能力太强,而口罩识别的识别能力太弱。即有时候会出现戴口罩的人能被人脸识别识别到但口罩识别无反应的情况,或者两个识别同时生效的情况。这样,就会导致如果简单用一个if进行判定,极其容易就造成误判。

笔者认为这里可能的原因有几个:

1、笔者的人脸识别用错了文件。在设计中,笔者对比过opencv开源的人脸特征识别中几个文件的识别情况,有好有坏,最终由于haarcascade_frontalface_default.xml文件的识别效果较好,所以用了这个文件。可能在这个训练集中,就是可以识别口罩的。由于缺乏具体测试,所以笔者也没办法证明这一点。

2、口罩识别的训练模型精度尚缺。如同前文所述,该口罩识别的模型用的是网友提供的模型,在其博文中也提到了,训练的图片数量不算特别多,且图片素材均是在网上找的。所以其精度不高也是情理之中、预料之内的。作为作业来说足以,无可厚非。

3.2人脸补全时的问题

这个问题算是整个系统中问题最大的地方。一开始想用的是sklearn中提供的人脸数据,仿照那个上半张脸预测下半张脸的程序去做,然后将训练好的模型保存,再在系统设计中调用就好了。但是总会遇到特征不符合的情况。报出如(ValueError: query data dimension must match training data dimension)这类的错误。接下来说一下人脸补全的过程和笔者的解决方法。

3.2.1人脸补全的详细过程

导包不说了,能看到这里的朋友应该不至于导包出问题。第一步是导入数据,这里的数据无论是自己输入还是从sklearn上调用,都是数组类型的数据,在sklearn上的人脸数据,是400组的64x64的彩色数据。对于彩色图像,即RGB图像,其数据是像下面写的三维数组的形式(例为64x64x3的三维数组)

[[[174 174 174]
[165 165 165]
[123 123 123]

[156 156 156]
[167 167 167]
[167 167 167]]

[[ 41 41 41]
[ 46 46 46]
[ 59 59 59]

[ 37 37 37]
[ 49 49 49]
[ 58 58 58]]]

利用cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)对图像进行降维处理,将会使得彩色的图像降成灰度图像,即三维数组降成二维数组,其数据形式如下所示(例为64x64的二维数组)

[[174 165 123 … 156 167 167]
[176 173 111 … 152 164 172]
[174 139 104 … 148 169 163]

[ 43 55 57 … 37 47 45]
[ 32 49 53 … 45 41 53]
[ 41 46 59 … 37 49 58]]

其中具体的降维算法这里就不细说了,可以查得到,基本上我们知道其数据形式是怎么样的就足够了。

降维之后,我们需要将数据进行切分,这里将数据切分成了上下两个部分,由于这里用的是64x64的数据,所以将直接用行切片即可。

X = data[:,:32].reshape(400,-1)   #上半张脸
y = data[:,32:].reshape(400,-1)   #下半张脸

由于sklearn中的是400个图像,所以这里将整体切片(data是400x64x64的三维数组),然后将图像reshape成一个400行2048(32x64)列的二维数组。如下所示

[[0.30991736 0.3677686 0.41735536 … 0.61157024 0.59917355 0.55785125]
[0.45454547 0.47107437 0.5123967 … 0.18181819 0.18181819 0.18181819]
[0.3181818 0.40082645 0.49173555 … 0.5785124 0.58264464 0.58677685]

[0.5 0.53305787 0.607438 … 0.42975205 0.4338843 0.446281 ]
[0.21487603 0.21900827 0.21900827 … 0.74380165 0.7355372 0.7066116 ]
[0.5165289 0.46280992 0.28099173 … 0.6528926 0.59090906 0.57438016]]

这样一来我们只需要根据index去抽取数据进行训练(fit)、预测(predict)就可以了。值得注意的是:这里无论是训练还是预测,都是以1行2048列的二维数组的形式传入,如果不是二维数组,就是发生上文写到的特征不匹配的问题。 只要注意好这个问题,其他的东西就直接跟着例子来就可以了。

3.2.2人脸补全过程中的问题及选择

由于人脸补全这块有很多种回归方法可以使用,所以首先对比了一下各种回归方法的效果,其中的参数按默认的来,效果如下

如上图所示,可以看出,KNN、岭回归、决策树的预测效果相对来说较好,但是由于岭回归的时间复杂度会相对较高(好吧也不尽然是,主要是当时岭回归的时候数据报错,我以为是回归出问题了,换了个回归试试,后面也没换回来),决策树的方式出现了两个一模一样的预测(第五行和第九行,可能是决策树原理的问题)。所以最终选择了KNN作为回归方法。

为了调整KNN中n_neighbor的系数,笔者做了以下的对比图

从图中可以很明显的看出当n_neighbor的系数为1时预测的效果比较好。所以系数敲定为1。

由于最初出现数据特征不匹配的问题,考虑到sklearn上提供的人脸图片数据无法获取(好吧其实是当时没想到怎么获取,print一下就可以了),所以最后选择自己在百度上下载图片然后进行数据训练。结果如下图所示

(别骂了别骂了,我知道预测图片是真的丑…)

这个训练结果是利用已经做好的人脸识别程序扣出其中的可被识别的人脸部分,将图片降为二维(灰度图),图片大小统一控制成64x64像素,保存到output文件夹中,如图所示,再人为剔除一些劣质头像图,得到的最原始的140张可训练的图像。其原图和处理后的图像分别如下所示


由于数据量才140份,最后成功导入python进行训练的数据才120份,所以才会得到上面哪样的歪瓜裂枣的结果,但是总的来说并不碍事,至少最终口罩预测出来的结果不算太离谱(如第一部分所示)

在这个系统中,笔者用的方法比较笨(因为最开始出问题了,为了完成不择手段),是将目标图像的上半脸append到整个数据组中,在共121份数据中,切前120份作为训练组,最后一个,即目标图像作为预测组进行预测。这样做的结果就是这个系统做出来的效果。当然也可以将训练好的模型包保存,最后再调用predict就好了。在源文件的cascades文件夹中也有几个用sklearn训练好的模型,有需要的朋友可以下载调用。由于最后的结果都差不多,所以在这个系统中我就没有改代码了,就直接用这种笨方法完成了系统。

3.3交互界面的问题

在交互上,最初我想的是用HTML+python的方法去做,这样可用css使得交互页面更加美观,也可以用js提升交互体验,不像现在这样操作过分简单。但是在查阅了相关资料后发现,HTML与Python的交互目前是比较差的,没有什么方法可以直接让数据在HTML和Python中进行交互,可行的方法是将数据保存至本地的txt中,再上传到HTML端或者Python端。然而这种方法对于图片来说实在太过鸡肋,实现起来也相对麻烦和费时,故放弃了这种用HTML作为交互端的方法。

四、总结

  • 从结果上看,在不考虑预测准度的情况下,这个系统还是可以很好的给出一个参考的预测图像的。结合在设计过程中遇到的问题(最开始在切分图像时数据出了很大问题,所以方法换了很多次),笔者认为,假如将sklearn上的训练出的预测模型运用到这里,可能会有更好的预测效果。

  • 在识别口罩中,用的是网友提供的训练模型,由于其训练的图片数量也不算大,所以会经常出现口罩识别失灵的状况,在face文件夹中的数张口罩图片,仅仅能够成功识别一个,这样的识别率无疑太低了一点。且由于opencv提供的人脸识别模型过于强大,所以常常会出现人脸识别成功但是口罩识别失败的问题,导致有些判断结构没办法完成,对于这一点也是可以在后续进一步改进的。

  • 在后续的设计中,只要将原始人脸数据的规模加大,再仔细调整n_neighbors的参数,或者采用其他回归方法进行预测,应该也可以得到更加精细、准确的预测图像。

  • 在图像切分上,由于问题已被解决,所以可以对代码进行优化,使得代码更为美观、简洁。

五、完整代码

注释应该算蛮完整的,应该不难看懂

编译器:pycharm 2019.3.3
opencv-python:4.2.0.34
numpy:1.18.5
scipy:1.4.1
matplotlib:3.2.1
easygui:0.98.1
scikit-learn:0.23.1

1、主程序

import easygui as eg
import cv2
import glob
import numpy as np
import matplotlib.pyplot as plt
from sklearn.neighbors import KNeighborsRegressordef face_recognition(paths):    #人脸识别函数judge = True   #判定是否检测到人脸# 人脸检测器faceCascade = cv2.CascadeClassifier('./cascades/haarcascade_frontalface_default.xml')count=0paths = paths.replace('\\','/')  #修改路径中的斜杠,用 \ 在opencv中会报错img =cv2.imread(paths)   #读取照片gray= cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  #灰度处理# 首先检测人脸,返回的是框住人脸的矩形框faces = faceCascade.detectMultiScale(gray,scaleFactor= 1.1,minNeighbors=8,minSize=(55, 55),flags=cv2.CASCADE_SCALE_IMAGE)# 画出每一个人脸,提取出人脸所在区域for (x, y, w, h) in faces:cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)cv2.imshow('Smile%d'%count, img)count += 1judge = Falsecv2.waitKey(0)cv2.destroyAllWindows()return judgedef select_path():   #文件路径选择函数paths = eg.fileopenbox()return pathsdef select_module():   #模块选择函数module = eg.buttonbox(msg='                                请选择相应的模块', title='摄像测量_识别项目', choices=('人脸识别', '车牌识别', '敬请期待...'),images='6b9140dc984e48589c6a6fe4b0c9317c_th.gif', default_choice=('Button[2]'), cancel_choice=None,callback=None, run=True)return moduledef camera_face_recognition():  #开摄像头的人脸识别cap = cv2.VideoCapture(0)eg.msgbox('                                 按q退出摄像头', ok_button='确定')while (True):# Capture frame-by-frame  逐帧截取ret, frame = cap.read()# Our operations on the frame come heregray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)xmlfile = r'./cascades/haarcascade_frontalface_default.xml'  #人脸识别modexmlfile_1 = r'./cascades/cascade.xml'   #口罩识别mode# 人脸识别face_cascade = cv2.CascadeClassifier(xmlfile)faces = face_cascade.detectMultiScale(gray,scaleFactor=1.15,minNeighbors=5,minSize=(5, 5),)#框出人脸,绿色框for (x, y, w, h) in faces:cv2.rectangle(frame, (x, y), (x + w, y + w), (0, 255, 0), 2)# 口罩识别face_cascade01 = cv2.CascadeClassifier(xmlfile_1)faces01 = face_cascade01.detectMultiScale(gray,scaleFactor=1.15,minNeighbors=5,minSize=(5, 5),)#框出口罩,红色框for (x, y, w, h) in faces01:cv2.rectangle(frame, (x, y), (x + w, y + w), (0, 0, 255), 2)cv2.imshow("frame", frame)# Display the resulting frameif cv2.waitKey(1) & 0xFF == ord('q'):   #按q退出摄像头break# When everything done, release the capturecap.release()cv2.destroyAllWindows()def face_predict(paths):     #人脸预测# 人脸检测器faceCascade = cv2.CascadeClassifier('./cascades/cascade.xml')# paths = glob.glob('./faces/girl4.jpg')count = 0data_path = glob.glob('./output/*.jpg')data_origin = []# 总数据,120份for i in data_path:img = cv2.imread(i)gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)data_origin.append(gray)# 写入需要预测的图像paths = paths.replace('\\', '/')  # 修改路径中的斜杠,用 \ 在opencv中会报错img = cv2.imread(paths)# 读取照片gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 首先检测戴口罩的人脸,返回的是框住人脸的矩形框faces = faceCascade.detectMultiScale(gray,scaleFactor=1.1,minNeighbors=8,minSize=(55, 55),flags=cv2.CASCADE_SCALE_IMAGE)# 画出每一个人脸,提取出人脸所在区域for (x, y, w, h) in faces:cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)# #提取脸部区域roi_gray = gray[y:y + h, x:x + w]  # 用于检测笑脸,减少计算量roi_test = cv2.resize(roi_gray, (64, 64))path_save = './' + str(count) + '.jpg'cv2.imwrite(path_save, roi_test)data_test = glob.glob(path_save)for i in data_test:img = cv2.imread(i)gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)data_origin.append(gray)data_origin = np.array(data_origin)X = data_origin[:, :32].reshape(121, -1)  # 上半张脸y = data_origin[:, 32:].reshape(121, -1)  # 下半张脸#121组数据中,前120组为训练组,最后一个为预测组,即目标预测对象X_train = X[:120, :]X_test = X[120:121, :]y_train = y[:120, :]y_test = y[120:121, :]#可尝试加入其它回归进行预测estimators = {}estimators['predict'] = KNeighborsRegressor(n_neighbors=1)  # KNN算法predict_ = {}for key, model in estimators.items():model.fit(X_train, y_train)y_ = model.predict(X_test)  # 根据上半张脸预测下半张脸的数据predict_[key] = y_# 可视化plt.figure(figsize=(3 * 2, 1 * 2))  # 1行3列for i in range(1):# 第一列  原图ax = plt.subplot(1, 3, 1 + 3 * i)face_up = X_test.reshape(32, 64)face_down = y_test.reshape(32, 64)ax.imshow(np.concatenate([face_up, face_down], axis=0), cmap=plt.cm.gray)# 如果想去掉刻度 可以用 ax.axis('off')if i == 0:ax.set_title('Original_image')  # 在第一行添加title# 第二列  上半脸ax = plt.subplot(1, 3, 2 + 3 * i)ax.imshow(face_up, cmap=plt.cm.gray)if i == 0:ax.set_title('Face_up')# 第三列  预测的全脸for j, key in enumerate(predict_):ax = plt.subplot(1, 3, 3 + j + 3 * i)y_ = predict_[key]face_down_ = y_.reshape(32, 64)ax.imshow(np.concatenate([face_up, face_down_], axis=0), cmap=plt.cm.gray)if i == 0:ax.set_title(key)plt.show()# plt.savefig('./预测图.jpg', dpi=500)  # 存图def mask_recogniton(paths):      #口罩识别mask = False# 口罩检测器faceCascade = cv2.CascadeClassifier('./cascades/cascade.xml')# paths = glob.glob('./faces/u=*.jpg')count = 0paths = paths.replace('\\','/')  #修改路径中的斜杠,用 \ 在opencv中会报错img = cv2.imread(paths)# 读取照片gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 首先检测人脸,返回的是框住人脸的矩形框faces = faceCascade.detectMultiScale(gray,scaleFactor=1.1,minNeighbors=8,minSize=(55, 55),flags=cv2.CASCADE_SCALE_IMAGE)# 画出每一个人脸,提取出人脸所在区域for (x, y, w, h) in faces:cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)cv2.imshow('Smile%d' % count, img)count += 1mask = Truecv2.waitKey(0)cv2.destroyAllWindows()return maskdef image_selection():  #图片选择函数selection = eg.buttonbox(msg='                                请选择图像打开方式', title='摄像测量_识别项目',choices=('图片', '摄像头'),default_choice=('Button[2]'), cancel_choice=None, callback=None, run=True)return selectionif __name__ == '__main__':#模块选择while(True):module = select_module()if(module == None):  #选择x则退出程序breakelif(module == '6b9140dc984e48589c6a6fe4b0c9317c_th.gif'):  #按图片无效,继续循环passelif(module == '人脸识别'):  #人脸识别selection = image_selection()#图片/摄像机 选择if (selection == '图片'):paths = select_path()judge = face_recognition(paths)# if judge:   #if judge = = true即没有检测到人脸  由于这里mask检测不是很灵敏,但是人脸检测灵敏过头,会出现带着口罩也被判为人脸的情况,所以这判定去掉mask = mask_recogniton(paths)if mask:face_predict(paths)passelif(selection == '摄像头'):camera_face_recognition()else:passpasselif (module == '车牌识别'):   #车牌识别,没做好,继续循环passelif(module == '敬请期待...'):passelse:pass

2、人脸预测(sklearn的方法)

import numpy as np
import matplotlib.pyplot as plt
import joblibimport sklearn.datasets as datasets
import scipy.io as siofrom sklearn.linear_model import LinearRegression,Ridge,Lasso
from sklearn.neighbors import KNeighborsRegressor
from sklearn.model_selection import train_test_split
from sklearn.svm import SVR
from sklearn import tree
from sklearn.metrics import precision_recall_curve
from sklearn.metrics import classification_report
from sklearn.model_selection import train_test_splitface = datasets.fetch_olivetti_faces()  #联网请求,获取数据data = face['images']
index = np.random.randint(400,size = 1)[0]  #随机抽取图片观察
plt.imshow(data[index],cmap = plt.cm.gray)  #灰度处理#切分图片  因为图片shape是(400,64,64)
X = data[:,:32].reshape(400,-1)   #上半张脸
y = data[:,32:].reshape(400,-1)   #下半张脸X_train,X_test,y_train,y_test = train_test_split(X,y,test_size = 10)  #留10组数据做测试#切分数据
index = np.random.randint(390,size = 1)[0]face_up = X_train[index].reshape(32,64)
face_down = y_train[index].reshape(32,64)ax = plt.subplot(1,2,1)
ax.imshow(face_up,cmap = plt.cm.gray)ax = plt.subplot(1,2,2)
ax.imshow(face_down,cmap = plt.cm.gray)#生成算法 放入字典中
estimators = {}
estimators['KNN'] = KNeighborsRegressor(n_neighbors = 5)  #KNN算法
estimators['lr'] = LinearRegression()  #线性回归
estimators['Ridge'] = Ridge(alpha = 0.1)  #岭回归
estimators['Lasso'] = Lasso(alpha = 0.1)  #罗斯回归
'''支持向量机的非线性回归不清楚什么原因无法训练处模型,会出现数据量不对等的报错'''
# estimators['rbf'] = SVR(kernel='rbf')  #高斯  非线性
# estimators['poly'] = SVR(kernel='poly')  #多项式  非线性
# estimators['sigmoid'] = SVR(kernel='sigmoid')  #Sigmoid核函数  非线性
estimators['tree'] = tree.DecisionTreeRegressor()  #决策树#数据训练,训练出来的结果放入字典中,方便后期plt呈现
predict_ = {}
for key, model in estimators.items():model.fit(X_train, y_train)y_ = model.predict(X_test)  # 根据上半张脸预测下半张脸的数据predict_[key] = y_# 可视化
plt.figure(figsize=(7 * 2, 10 * 2))  # 10行6列  X_test中有10个样本 1列真实数据 2列是半张脸 34567是不同算法预测的for i in range(10):# 第一列ax = plt.subplot(10, 7, 1 + 7 * i)  # 10行7列 索引为1+7iface_up = X_test[i].reshape(32, 64)face_down = y_test[i].reshape(32, 64)ax.imshow(np.concatenate([face_up, face_down], axis=0), cmap=plt.cm.gray)# 如果想去掉刻度 可以用 ax.axis('off')if i == 0:ax.set_title('True')  # 在第一行添加title# 第二列ax = plt.subplot(10, 7, 2 + 7 * i)ax.imshow(face_up, cmap=plt.cm.gray)if i == 0:ax.set_title('Face_up')# 第三、四、五、六列for j, key in enumerate(predict_):ax = plt.subplot(10, 7, 3 + j + 7 * i)y_ = predict_[key]face_down_ = y_[i].reshape(32, 64)ax.imshow(np.concatenate([face_up, face_down_], axis=0), cmap=plt.cm.gray)if i == 0:ax.set_title(key)plt.savefig('./Desktop/回归图.jpg', dpi=500)  # 存图'''对比之后发现决策树的效果可能更好,故保存该模型'''
tree_module = tree.DecisionTreeRegressor()  #决策树
tree_module.fit(X_train,y_train)
joblib.dump(tree_module, './tree_module.pkl')

3、用于训练模型的原始人脸数据处理

import cv2
import glob# 人脸检测器
faceCascade = cv2.CascadeClassifier('./cascades/haarcascade_frontalface_default.xml')paths = glob.glob('./face_origin_data_*/*.jpg')
count = 0
for path in paths:img = cv2.imread(path)# 读取照片gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 首先检测人脸,返回的是框住人脸的矩形框faces = faceCascade.detectMultiScale(gray,scaleFactor=1.1,minNeighbors=8,minSize=(55, 55),flags=cv2.CASCADE_SCALE_IMAGE)# 画出每一个人脸,提取出人脸所在区域for (x, y, w, h) in faces:cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)# #提取脸部区域roi_gray = gray[y:y+h, x:x+w]#用于检测笑脸,减少计算量# roi_color = img[y:y+h, x:x+w]#用于画笑脸,因为用提取的区域进行分类,返回的参数是根据这个区域的roi_test = cv2.resize(roi_gray,(64,64))path_save = './output/'+ str(count) + '.jpg'cv2.imwrite(path_save,roi_test)# 全部显示出来# cv2.imshow('Smile%d' % count, roi_test)count += 1c = cv2.waitKey(0)
cv2.destroyAllWindows()

【参考资料】

感谢以下博主提供的灵感和代码(博主+文章标题+网址)

[1] yzy_1996, HTML网页调用本地Python程序,https://blog.csdn.net/yzy_1996/article/details/80223053

[2] 柒澈言, 人脸识别之笑脸检测, https://blog.csdn.net/weixin_43493559/article/details/106599574

[3] 行动π, python 可视化界面学习简易教程, https://blog.csdn.net/wenqiangxin/article/details/84555128

[4] weixin_30782871, python 可视化界面, https://blog.csdn.net/weixin_30782871/article/details/99562137?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159290748119724839260348%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=159290748119724839260348&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-3-99562137.first_rank_v2_rank_v25&utm_term=python+%E5%8F%AF%E8%A7%86%E5%8C%96%E7%95%8C%E9%9D%A2

[5] 考古学家lx, Python 调用摄像头进行人脸识别, https://blog.csdn.net/weixin_43582101/article/details/88913164

[6] 姬小野, python openCV调用摄像头进行人脸识别, https://blog.csdn.net/wjh2622075127/article/details/90712424

[7] Cheney-渣渣杰, 基于Opencv的口罩佩戴识别系统, https://blog.csdn.net/cj151525/article/details/104984897

[8] 心静禅定ing, python实现人脸口罩检测(基于opencv和深度学习两种方法), https://blog.csdn.net/qq_43987474/article/details/106649335

[9] 网络毒刘, 【机器学习】六种算法在人脸补全中的应用比较(K近邻,线性,决策树,岭回归,套索回归,ElasticNet), https://blog.csdn.net/qq_41856814/article/details/103299271?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159299804019724843341245%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=159299804019724843341245&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_v2~rank_v25-8-103299271.first_rank_v2_rank_v25&utm_term=%E4%BA%BA%E8%84%B8%E8%A1%A5%E5%85%A8

[10] 蜂口小程序_ IT, 怎样降低遮挡对人脸识别的影响,人脸图像算法研究, https://blog.csdn.net/qq_43019117/article/details/82746795?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159299870219725222436468%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=159299870219725222436468&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_v2~rank_v25-5-82746795.first_rank_v2_rank_v25&utm_term=%E4%BA%BA%E8%84%B8%E8%A1%A5%E5%85%A8

[11] Data_IT_Farmer, 机器学习-训练模型的保存与恢复(sklearn), https://blog.csdn.net/helloxiaozhe/article/details/80658438?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159300301919195188413798%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=159300301919195188413798&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_v2~rank_v25-1-80658438.first_rank_v2_rank_v25&utm_term=%E5%9B%9E%E5%BD%92%E8%AE%AD%E7%BB%83%E5%87%BA%E6%9D%A5%E7%9A%84%E6%A8%A1%E5%9E%8B%E4%BF%9D%E5%AD%98

[12] pentiumCM, 机器学习之训练好的模型保存与加载, https://blog.csdn.net/pentiumCM/article/details/104370401?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159301052219725250109770%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=159301052219725250109770&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-1-104370401.first_rank_v2_rank_v25&utm_term=python%E4%BF%9D%E5%AD%98%E8%AE%AD%E7%BB%83%E5%A5%BD%E7%9A%84%E6%A8%A1%E5%9E%8B

[13] TheRebel_, k-svd实现人脸缺失像素补全, https://blog.csdn.net/Anonymity_/article/details/85196505?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159305814519195264552496%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=159305814519195264552496&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_v2~rank_v25-20-85196505.first_rank_v2_rank_v25&utm_term=%E4%BA%BA%E8%84%B8%E8%A1%A5%E5%85%A8

[14] Simonn_z, python+opencv 识别圆形物体并将图像抠出, https://blog.csdn.net/BOB_sm/article/details/106722952

[15] DXT00, OpenCV检测图像中的长方形画布或纸张并提取图像内容, https://blog.csdn.net/qq_32095699/article/details/80262429?ops_request_misc=&request_id=&biz_id=102&utm_term=%E8%AF%86%E5%88%AB%E6%96%B9%E7%89%A9%E4%BD%93%E5%B9%B6%E5%B0%86%E5%9B%BE%E5%83%8F%E6%8A%A0%E5%87%BA&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-1-80262429

[16] 菜鸟Jon, python爬取百度图片, https://blog.csdn.net/csdnmgq/article/details/93197047?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159350775819726869063583%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=159350775819726869063583&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_click~default-1-93197047.first_rank_v2_rank_v25&utm_term=%E7%88%AC%E7%99%BE%E5%BA%A6%E5%9B%BE%E7%89%87

[17] 一颗小树x, python 对文件夹下图片批量重命名, https://blog.csdn.net/qq_41204464/article/details/85483480?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159350904619195265964145%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=159350904619195265964145&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v3~pc_rank_v2-2-85483480.first_rank_ecpm_v3_pc_rank_v2&utm_term=%E5%B0%86%E6%96%87%E4%BB%B6%E5%A4%B9%E7%9A%84%E5%9B%BE%E7%89%87%E9%87%8D%E5%91%BD%E5%90%8D

[18] 倔强的小彬雅, 机器学习入门-用KNN实现手写数字图片识别, https://blog.csdn.net/Snow_yuki/article/details/89789071?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159351794319725250140434%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=159351794319725250140434&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v3~pc_rank_v2-11-89789071.first_rank_ecpm_v3_pc_rank_v2&utm_term=%E7%94%A8%E6%9C%AC%E5%9C%B0%E5%9B%BE%E7%89%87%E5%81%9A%E6%9C%BA%E5%99%A8%E8%AE%AD%E7%BB%83

【Python+OpenCV+sklearn+easygui】人脸(口罩)识别+口罩下人脸补全的系统设计相关推荐

  1. 基于wxpython+MySQL--实现人脸检测识别的宿舍人脸检测系统

    基于wxpython+MySQL--实现人脸检测识别的宿舍人脸检测系统 一.功能需求 二.数据库建立 2.1 初始化数据库 2.2 压缩/解压数据流 2.3 输入数据 三.宿舍管理 3.1 新建录入 ...

  2. 部分代码_(python openCV)用71行代码实现获取人脸部分并存储功能

    前言: 今天为大家带来的内容是,(python openCV)用71行代码实现获取人脸部分并存储功能!希望能够帮助到大家,代码较多,部分是用图片方式呈现出来,为了有更好的观赏性和收藏便利. 提示: 本 ...

  3. 人脸离线识别模块_人脸消费机离线刷脸如何实现?

    随着越来越多刷卡刷脸一卡通的设备出现.大家在享受一卡通的便利的同时.也在考虑人脸消费机的基本功能和安全属性,人脸消费机,是指人脸在消费访客管理方面的相关.在人脸刷脸进行消费的时候是一下几个阶段1.人脸 ...

  4. python最新技术开锁工具_这个库厉害了,自动补全 Python 代码,节省 50% 敲码时间...

    摘要:介绍一个优秀代码自动补全工具库. 近日,Reddit 上的一篇帖子引起了网友的热议.帖子作者「mlvpj」称: 「我们使用深度学习完成了一个简单的项目,可以自动进行 Python 代码补全.」 ...

  5. python手写答题卡识别_基于 Python OpenCV 的简易答题卡识别

    又有一个多月的时间了呢 = = 刚想起来还欠着一篇文章没写,趁着没忘干净赶紧补上 先上样卡(A4,扫描图片为600dpi) 整体并不是很复杂,但一口气手工切40+张也是够累,所以想办法自己写了个识别程 ...

  6. python+opencv通过颜色阙值识别黑色飞机,并且输出中心点

    1.下载opencv-python,使用命令 pip install opencv-python=4.5.2.52 2.黑色阙值范围 lower = np.array([0,0,0]) upper = ...

  7. python opencv 二维码定位识别

    # --coding:utf-8-- from Camera.sdk.Camera import Camerafrom math import sin,cos,radians,fabs import ...

  8. python opencv实现 tiff转raw格式以及扩充体积补零

    ##tiff转raw格式 import numpy as np import imageio import cv2 src = np.fromfile("路径名.tiff" , d ...

  9. python每个字符后添加空格_python实现指定字符串补全空格的方法

    有什么方法可以指定字符串长度,不够的自动补空格 char定义的是一个半角字符. 当人心变成市场,当市场变成战场,战场埋葬多少理想. char[]定义的是一个不定长的数组,实际上是指针,用前要初始化.不 ...

最新文章

  1. 【转】Visual C#创建和使用ActiveX组件
  2. 京东商城背后的AI技术能力揭秘 - 基于关键词自动生成摘要
  3. pycharm调试显示图片
  4. 多看看 leetcode 128. 最长连续序列
  5. 2018-04-12 Linux学习
  6. Python 标准库 18.5 - asyncio
  7. Spring Data JPA的持久层
  8. 一个案例、6个步骤全程详解A/B测试,看这篇就够了!
  9. php 上传100m文件,PHP向MySQL中insert100M以上的文件
  10. 基于JAVA+SpringMVC+Mybatis+MYSQL的奖助学金贷款信息管理系统
  11. mysql undrop_MySQL · 数据恢复 · undrop-for-innodb
  12. mongodb之mongostat 的字段含义解析
  13. 快速查找文件的神器Listary
  14. linux下安装yum命令
  15. 数据挖掘原理与算法_【干货】UIUC韩家炜老师2020年新课:CS512 数据挖掘:原理与算法,附PPT...
  16. Java软件开发技术交流群
  17. autocad字体ccfang,求CAD字体hzmsdi.shx 发到我邮箱,185955330@qq.com
  18. 360测网速服务器维护,360网速测试器还你真实网速 提供专门维护服务
  19. 大数据分析案例:电力窃漏电用户自动识别
  20. 修改Linux swap大小,LINUX操作系统如何调整SWAP大小

热门文章

  1. 利用python实现ANN算法预测岩石单轴抗压强度的经验模型代码。设置岩石密度、孔隙度、施密特回弹值、动岩石参数作为输出层...
  2. Unable to find script library '/aspnet_client/system-web/1-1-4322/webvalidation.js'
  3. 关于NC6.X企业报表取不了数的问题及其解决方法。
  4. 开发一款系统软件大概需要多少钱呢
  5. char **argv什么意思呢
  6. Queen Collisions
  7. 华大单片机HC32L130/HC32L136红外端口配置
  8. 文献笔记:Contrast-Phys: Unsupervised Video-based Remote Physiological Measurement viaSpatiotemporal Con
  9. 苹果 Mac Big Sur 如何更改锁屏时间?
  10. python线性回归预测pm2.5_李宏毅 线性回归预测PM2.5