前言
学习opencv, 用网上找到的男女明星照骗试了下opencv的3种人脸识别机制, 似乎都不太行。
一、opencv 人脸识别函数
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 size
x_min = 9999
y_min = 9999
img_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 size
if 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 name
img_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 image
frontFaces = 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])
continue
else:
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_y
rate_x = x_min / img.shape[1] * 0.98
rate_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:
# grey
img_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_new
cv2.imwrite(strSource + "\\Unified\\" + img_Bingbing[i][1],img_template)
strSource = r'C:\Waley\Personal\Learning\Python\Image\TryFaceIdentify'
unifyImg(strSource)
- 挑一部分统一好尺寸的图片整合进一个列表,用来训练
src = list()
lables = list()
# LiYiFeng
for 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)
#YiYangQianXi
for 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 recognizer
recognizer_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 dataset
src = 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 creator
recognizer_eigenface = cv2.face.EigenFaceRecognizer_create()
recognizer_fisher = cv2.face.FisherFaceRecognizer_create()
recognizer_LBPH = cv2.face.LBPHFaceRecognizer_create()
#train recognizer
recognizer_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试试
|