文章目录
前言一、opencv 人脸识别函数二、从素材准备到预测三、意外的发现四、结论前言
学习opencv, 用网上找到的男女明星照骗试了下opencv的3种人脸识别机制, 似乎都不太行。
一、opencv 人脸识别函数
有3个识别器:recognizer_eigenface = cv2.face.EigenFaceRecognizer_create()recognizer_fisher = cv2.face.FisherFaceRecognizer_create()recognizer_LBPH = cv2.face.LBPHFaceRecognizer_create()
使用方法是一样的,都要先准备好训练集来训练,训练后再预测注意安装标准版的opencv-python是不行的,要安装opencv-contrib-python才行。
二、从素材准备到预测
下载图片男女明星各一组,每组2人,每人各9张。图片找小冰要的,度娘也一样。图片规整化
训练时要求图片尺寸统一,而下载来的图片大大小小,所以要统一到同一尺寸. 用简单粗暴的方法,查出所有图片的最小尺寸,然后将所有照片调到此尺寸。不能变形,不足的方向补黑边。
def unifyImg(strSource):#read all images and get the smallest sizex_min = 9999y_min = 9999img_Bingbing = list()img_file_list = os.listdir(strSource)for i in range(0,len(img_file_list)):strFileName = os.path.join(strSource,img_file_list[i]) if os.path.isfile(strFileName):img = cv2.imread(strFileName)if img is None:print('Failed when read file %s'%strFileName)continue# record sizeif img.shape[0] < y_min:y_min = img.shape[0]if img.shape[1] < x_min:x_min = img.shape[1]#store img and its nameimg_Bingbing.append([img,img_file_list[i]])#Resize images frontFaceCascade = cv2.CascadeClassifier(r'.\Lib\site-packages\cv2\data\haarcascade_frontalface_default.xml')profileFaceCascade = cv2.CascadeClassifier(r'.\Lib\site-packages\cv2\data\haarcascade_profileface.xml')for i in range(0,len(img_Bingbing)):img = img_Bingbing[i][0]#check if face is identified in the imagefrontFaces = frontFaceCascade.detectMultiScale(img)profileFaces = profileFaceCascade.detectMultiScale(img)if len(frontFaces) == 0:if len(profileFaces) == 0:print("no face detected on img: %s, deleted."%img_Bingbing[i][1])continueelse:x = profileFaces[0][0]y = profileFaces[0][1]w = profileFaces[0][2]h = profileFaces[0][3]else:x = frontFaces[0][0]y = frontFaces[0][1]w = frontFaces[0][2]h = frontFaces[0][3]img_new = img[y:y+h,x:x+w]cv2.imwrite(strSource + "\\Face_only\\" + img_Bingbing[i][1],img_new)# 98% make sure the output image size is smaller than the min_x or min_yrate_x = x_min / img.shape[1] * 0.98rate_y = y_min / img.shape[0] * 0.98 rate = min(rate_x, rate_y)img_new = cv2.resize(img, None, fx = rate, fy = rate)if len(img_new.shape) == 2:# greyimg_template = np.zeros((y_min, x_min),np.uint8) else:img_template = np.zeros((y_min, x_min, 3),np.uint8) h = img_new.shape[0]w = img_new.shape[1]img_template[0:h,0:w] = img_newcv2.imwrite(strSource + "\\Unified\\" + img_Bingbing[i][1],img_template)strSource = r'C:\Waley\Personal\Learning\Python\Image\TryFaceIdentify'unifyImg(strSource)
挑一部分统一好尺寸的图片整合进一个列表,用来训练
src = list()lables = list()# LiYiFengfor i in range(0,6):img = cv2.imread(strSource + "\\unified\\LYF_" + str(i+1) + ".jpg",cv2.IMREAD_GRAYSCALE)if img is None:print("Fail to read images")sys.exit(0)else:src.append(img)lables.append(0)#YiYangQianXifor i in range(0,6):img = cv2.imread(strSource + "\\unified\\YYQX_" + str(i+1) + ".jpg",cv2.IMREAD_GRAYSCALE)if img is None:print("Fail to read images")sys.exit(0)else:src.append(img)lables.append(1) names = {"0":"LiYiFeng","1":"YiYangQianXi"}#train recognizerrecognizer_eigenface.train(src,np.array(lables))recognizer_fisher.train(src, np.array(lables))recognizer_LBPH.train(src, np.array(lables))
识别
for i in range(7,10):img = cv2.imread(strSource + "\\unified\\LYF_" + str(i) + '.jpg',cv2.IMREAD_GRAYSCALE)print("LYF %d : "%i)lable, confidence = recognizer_eigenface.predict(img)print("predicted by Eigenface: %s, confidence is: %d"%(names[str(lable)],confidence))lable, confidence = recognizer_fisher.predict(img)print("predicted by Fisher: %s, confidence is: %d"%(names[str(lable)],confidence))lable, confidence = recognizer_LBPH.predict(img)print("predicted by LBPH: %s, confidence is: %d"%(names[str(lable)],confidence))print("\n\n")for i in range(7,10):img = cv2.imread(strSource + "\\unified\\YYQX_" + str(i) + '.jpg',cv2.IMREAD_GRAYSCALE)print("YYQX %d : "%i)lable, confidence = recognizer_eigenface.predict(img)print("predicted by Eigenface: %s, confidence is: %d"%(names[str(lable)],confidence))lable, confidence = recognizer_fisher.predict(img)print("predicted by Fisher: %s, confidence is: %d"%(names[str(lable)],confidence))lable, confidence = recognizer_LBPH.predict(img)print("predicted by LBPH: %s, confidence is: %d"%(names[str(lable)],confidence))
以上可以合并为一个函数,方便换人试验:
def trainAndPredict(strSource, strName1, strName2):# prepare training datasetsrc = list()lables = list()for i in range(0,6):img = cv2.imread(strSource + "\\unified\\" + strName1 + '_' + str(i+1) + ".jpg",cv2.IMREAD_GRAYSCALE)if img is None:print("Fail to read images")sys.exit(0)else:src.append(img)lables.append(0)for i in range(0,6):img = cv2.imread(strSource + "\\unified\\" + strName2 + '_' + str(i+1) + ".jpg",cv2.IMREAD_GRAYSCALE)if img is None:print("Fail to read images")sys.exit(0)else:src.append(img)lables.append(1) names = {"0":strName1,"1":strName2}#set up creatorrecognizer_eigenface = cv2.face.EigenFaceRecognizer_create()recognizer_fisher = cv2.face.FisherFaceRecognizer_create()recognizer_LBPH = cv2.face.LBPHFaceRecognizer_create()#train recognizerrecognizer_eigenface.train(src,np.array(lables))recognizer_fisher.train(src, np.array(lables))recognizer_LBPH.train(src, np.array(lables))for i in range(7,10):img = cv2.imread(strSource + "\\unified\\" + strName1 + '_' + str(i) + '.jpg',cv2.IMREAD_GRAYSCALE)print("%s %d : "%(strName1,i))lable, confidence = recognizer_eigenface.predict(img)print("predicted by Eigenface: %s, confidence is: %d"%(names[str(lable)],confidence))lable, confidence = recognizer_fisher.predict(img)print("predicted by Fisher: %s, confidence is: %d"%(names[str(lable)],confidence))lable, confidence = recognizer_LBPH.predict(img)print("predicted by LBPH: %s, confidence is: %d"%(names[str(lable)],confidence))print("\n\n")for i in range(7,10):img = cv2.imread(strSource + "\\unified\\" + strName2 + '_' + str(i) + '.jpg',cv2.IMREAD_GRAYSCALE)print("%s %d : "%(strName2,i))lable, confidence = recognizer_eigenface.predict(img)print("predicted by Eigenface: %s, confidence is: %d"%(names[str(lable)],confidence))lable, confidence = recognizer_fisher.predict(img)print("predicted by Fisher: %s, confidence is: %d"%(names[str(lable)],confidence))lable, confidence = recognizer_LBPH.predict(img)print("predicted by LBPH: %s, confidence is: %d"%(names[str(lable)],confidence))#strSource = r'C:\Waley\Personal\Learning\Python\Image\TryFaceIdentify'#strName1 = 'LYF'#strName2 = 'YYQX'strSource = r'C:\Waley\Personal\Learning\Python\Image\FaceIdentify'strName1 = 'LiBingbing'strName2 = 'YangMi'trainAndPredict(strSource, strName1, strName2)
结果让人意外
对于两位男明星,简直没有任何识别率。
这两位明星都不太熟悉,会不会是网站也是AI标的,标错了呢?哈哈。
换了两位女明星试验,效果似乎还行:
三、意外的发现
发现这张图片opencv 检测不出来脸部,正面侧面都不行。等继续研究为什么。发现这张图片opencv识别出来的脸部是错误的
识别出来的脸是肘部,
原因待进一步研究。
四、结论
将opencv 的人脸识别用于生产环境估计是不行的。下一步准备用同样的这些图片训练下TensorFlow试试
如果觉得《用opencv的人脸识别来分辨明星似乎不太灵光》对你有帮助,请点赞、收藏,并留下你的观点哦!