📅大四是整个大学期间最忙碌的时光,一边要忙着准备考研,考公,考教资或者实习为毕业后面临的就业升学做准备,一边要为毕业设计耗费大量精力。近几年各个学校要求的毕设项目越来越难,有不少课题是研究生级别难度的,对本科同学来说是充满挑战。为帮助大家顺利通过和节省时间与精力投入到更重要的就业和考试中去,学长分享优质的选题经验和毕设项目与技术思路。
🚀对毕设有任何疑问都可以问学长哦!
本次分享的课题是
🎯opencv的人脸面部识别
课题背景与意义
现在,面部识别已成为生活中的一部分。我们在手机、平板电脑等设备中使用人脸信息进行解锁的时候,这时就要求获取我们的实时面部图像,并将其储存在数据库中以进一步表明我们的身份。
通过对输入图像进行迭代和预测可以完成这个过程。同样,实时人脸识别可与OpenCV框架python的实现配合使用。再将它们组合在一个组合级别中,以实现用于实时目的的模型。
课题实现技术思路
OpenCV 有三种人脸识别的算法:
- Eigenfaces 是通过 PCA(主成分分析)实现的,它识别人脸数据集的主成分,并计算出待识别图像区域相对于数据集的发散程度(0
20k),该值越小,表示差别越小,0值表示完全匹配。低于4k5k都是相当可靠的识别。 - FisherFaces 是从 PCA发展而来,采用更复杂的计算,容易得到更准确的结果。低于4k~5k都是相当可靠的识别。
- LBPH 将人脸分成小单元,并将其与模型中的对应单元进行比较,对每个区域的匹配值产生一个直方图。它允许待检测人脸区域可以和数据集中图像的形状、大小不同,更方便灵活。参考值低于50则算是好的识别,高于80则认为比较差。
当然,除了这三种预定义的算法外,我们可以自己写深度学习算法或者其他机器学习的分类算法来进行人脸识别,这里不再详述。
不管使用哪种算法都需要有训练集。从视频或者动图创建训练集的效率比较高。我从网上下载了一些明星的动图,然后分解,检测人脸区域,全部存为200X200的灰度图,存入对应的文件夹中,创建训练集。
from PIL import Imageimport osimport cv2def gifSplit2Array(gif_path): import numpy as np img = Image.open(gif_path) for i in range(img.n_frames): img.seek(i) new = Image.new("RGBA", img.size) new.paste(img) arr = np.array(new).astype(np.uint8) # image: img (PIL Image): yield arr[:,:,2::-1] # 逆序(RGB 转BGR), 舍弃alpha通道, 输出数组供openCV使用def face_generate(img): gray =cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) front_face_cascade = cv2.CascadeClassifier(r'E:\Python36\MyPythonFiles\my OpenCV\face_detection\cascades/haarcascade_frontalface_default.xml')#检测正脸 faces0 = front_face_cascade.detectMultiScale(gray, 1.02, 5) #eye_cascade = cv2.CascadeClassifier('./cascades/haarcascade_eye.xml')#检测眼睛 eye_cascade = cv2.CascadeClassifier(r'E:\Python36\MyPythonFiles\my OpenCV\face_detection\cascades/haarcascade_eye_tree_eyeglasses.xml')#检测眼睛 for (x, y, w, h) in faces0: face_area = gray[y: y+h, x: x+w] # (疑似)人脸区域 quasi_eyes = eye_cascade.detectMultiScale(face_area, 1.03, 5, 0)#在人脸区域检测眼睛 if len(quasi_eyes) ==0: continue quasi_eyes = tuple(filter(lambda x : x[2]/w>0.18 and x[1]<0.5*h, quasi_eyes)) # ex,ey,ew,eh; ew/w>0.18 #尺寸过滤 ,且眼睛在脸的上半部 if len(quasi_eyes) <1 : continue yield cv2.resize(face_area, (200,200))i = 0for gif_path in ("Yangme5.gif","Yangme6.gif","Shishi.gif","Shishi2.gif","Shishi3.gif","Shishi3.gif" ,"Yangzi.gif","Yangzi2.gif","Yangzi3.gif","Zhenshuang.gif","ZDY.gif", "ZDY2.gif"): print(gif_path) for img in gifSplit2Array(gif_path): for face in face_generate(img): cv2.imwrite("./dataset/%s.pgm" % (i), face) print(i) i += 1
我们可以剔除掉其中一些效果不好的图片。
接着我们加载数据集,训练模型:
def load_dataset(datasetPath): names = [] X = [] y = [] ID = 0 for name in os.listdir(datasetPath): subpath = os.path.join(datasetPath, name) if os.path.isdir(subpath): names.append(name) for file in os.listdir(subpath): im = cv2.imread(os.path.join(subpath,file), cv2.IMREAD_GRAYSCALE) X.append(np.asarray(im, dtype = np.uint8)) y.append(ID) ID += 1 X = np.asarray(X) y = np.asarray(y, dtype = np.int32) return X, y, names datasetPath =".\dataset" X, y , names = load_dataset(datasetPath)#报错找不到face模块是因为只安装了主模块#pip uninstall opencv-python, pip install opencv0-contrib-python#创建人脸识别模型(三种识别模式)#model = cv2.face.EigenFaceRecognizer_create() #createEigenFaceRecognizer()函数已被舍弃#model = cv2.face.FisherFaceRecognizer_create()model = cv2.face.LBPHFaceRecognizer_create() #model.train(X, y)
最后我们将待预测的图像中的人脸区域与训练集中的图像进行比对预测:
def recognize(img): global model, names gray =cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) front_face_cascade = cv2.CascadeClassifier(r'E:\Python36\MyPythonFiles\my OpenCV\face_detection\cascades/haarcascade_frontalface_default.xml')#检测正脸 faces0 = front_face_cascade.detectMultiScale(gray, 1.025, 5) eye_cascade = cv2.CascadeClassifier(r'E:\Python36\MyPythonFiles\my OpenCV\face_detection\cascades/haarcascade_eye_tree_eyeglasses.xml')#检测眼睛 for (x, y, w, h) in faces0: #print(x,y,w,h) face_area = gray[y: y+h, x: x+w] #疑似人脸区域 quasi_eyes = eye_cascade.detectMultiScale(face_area, 1.03, 5, 0)#在人脸区域检测眼睛 if len(quasi_eyes) ==0: continue quasi_eyes = tuple(filter(lambda x : x[2]/w>0.15, quasi_eyes)) # ex,ey,ew,eh; ew/w>0.18 #尺寸过滤 #print(quasi_eyes) if len(quasi_eyes) <1 : continue#if len(quasi_eyes) <2 : continue cv2.rectangle(img, (x,y), (x+w,y+h), (0,0,255), 2) #画红色矩形框标记正脸 roi = cv2.resize(face_area, (200,200), interpolation = cv2.INTER_LINEAR) #尺寸缩放到与训练集中图片的尺寸一致 cv2.imwrite("e.pgm", roi) #若识别错误,可以添加到正确的数据集,提高后续的识别率 ID_predict, confidence = model.predict(roi)#预测!!! name = names[ID_predict] print("name:%s, confidence:%.2f"%(name, confidence)) text = name if confidence <70 else "unknow" #10000 for EigenFaces #70 for LBPH cv2.putText(img, text , (x, y-20), cv2.FONT_HERSHEY_SIMPLEX,1,(0,255,0),2)#绘制绿色文字 return imgimgPath = "AA.jpg"img = cv2.imread(imgPath)cv2.imshow(imgPath, recognize(img))cv2.waitKey()cv2.destroyAllWindows()
下面是一些预测结果的展示:
单人照:
伪双人照:
三人照(杀马特的诗诗......):
胡歌不在数据集中,所以肯定会识别错误,我们需舍弃置信度过差的结果:
当然,真实的识别效果没这么理想,识别的准确度主要取决于我们的数据集的优劣。
🚀海浪学长的作品示例:
大数据算法项目
机器视觉算法项目
微信小程序项目
Unity3D游戏项目
最后
🏆为帮助大家节省时间,如果对开题选题,或者相关的技术有不理解,不知道毕设如何下手,都可以随时来问学长,我将根据你的具体情况,提供帮助。
版权归原作者 HaiLang_IT 所有, 如有侵权,请联系我们删除。