人脸识别
一直跟着opencv3+计算机视觉来体验opencv的魅力,这次被小小坑了一下,源代码还找不到,小小吐槽一下。
-
准备数据
- 准备一堆正确的数据,用来给算法学习。推荐用摄像头直接捕获自己的脸然后生成符合要求的图片,用照片的话第一质量不行,第二数量可能不行,第三未必能正确识别。献上代码(util是之前用来管理视频获取源的可以不用):
import cv2
import sys
sys.path.append('../../src/')
import utils as util
def generate():
# opencv提供的脸部特征xml文件
face_cascade = cv2.CascadeClassifier(
'../cascades/haarcascade_frontalface_default.xml')
# 眼部特征描述文件
eye_cascade = cv2.CascadeClassifier('../cascades/haarcascade_eye.xml')
# 通过网络摄像头来获取视频
#camerVideo = util.VideoCapture(util.CAPTURE_TYPE_NET)
#camerVideo.capture = 'http://192.168.2.101:8880/video'
#camera = camerVideo.captureVideoFrom()
# 直接获取笔记本自己的摄像头视频
camera = cv2.VideoCapture(0)
count = 0
while (True):
ret, frame = camera.read()
# 将每一帧转化成灰度图片
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 根据特征文件的描述,在图片中找到脸
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x, y, w, h) in faces:
# 画个蓝色方框标注脸
img = cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)
# 截取蓝色标注部分的图像
f = cv2.resize(gray[y:y + h, x:x + w], (200, 200))
# 将蓝色区域的图像保存到本地
cv2.imwrite('../../attach/image/at/%s.pgm' % str(count), f)
count += 1
cv2.imshow('camera', frame)
if cv2.waitKey(1) & 0xff == ord("q"):
break
camera.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
generate()
好了,执行了上段代码你会得到一个文件夹,里面都是初步获取的图片,例如你执行开始1秒结束,然后你一秒有30帧那就会得到30张照片,里面可能有的是正确的你的脸,也有一些不是。把那些错误的删除掉。
-
注意后缀和大小,都会影响算法的正确性
读取数据
-
接下来让我们读取这些图片
import os import cv2 import sys sys.path.append('../../src/') import utils as util import numpy as np ''' 加载人脸数据库的图片信息 ''' # path就是图片所在的上一层文件夹 def read_images(path, sz=None): c = 0 x, y = [], [] # 根据传入的路径获取路径名,文件夹名和文件名 for dirname, dirnames, filenames in os.walk(path): for subdirname in dirnames: subject_path = os.path.join(dirname, subdirname) for filename in os.listdir(subject_path): try: # MAC平台所以加上了.DS_Store if (filename == ".directory" or filename == ".DS_Store"): continue filepath = os.path.join(subject_path, filename) # print(filepath) im = cv2.imread(os.path.join( subject_path, filename), cv2.IMREAD_GRAYSCALE) if (sz is not None): im = cv2.resize(im, (200, 200)) x.append(np.asarray(im, dtype=np.uint8)) y.append(c) except IOError as errno: print("I/O error({0}):".format(errno)) except: print("Unexpected error:", sys.exc_info()[0]) raise c = c + 1 return [x, y]
- 返回的图片元素的数组形式,用来递交给后面的训练函数 人脸识别
-
opencv3有三种训练方式,来生成数据的特征文件,我们可以用save方法保存下来。如果只是像我一样练习一下可以使用而不存储
def face_rec(): names = ['SuperMexel', '天才'] # if len(sys.argv) < 2: # print("USAGE: facerec_demo.py Somthing WRONG") # sys.exit() image_path = '../../attach/image/at/my_faces/' [X, y] = read_images(image_path) y = np.asarray(y, dtype=np.int32) if len(sys.argv) == 3: out_dir = sys.argv[2] # 指定训练算法的模型,开始训练 # model = cv2.face.EigenFaceRecognizer_create() model = cv2.face.LBPHFaceRecognizer_create() model.train(np.asarray(X), np.asarray(y)) # model.save('../../src/face_result/SuperMexel.xml') # camera = cv2.VideoCapture(0) camerVideo = util.VideoCapture(util.CAPTURE_TYPE_NET) camerVideo.capture = 'http://192.168.2.101:8880/video' camera = camerVideo.captureVideoFrom() face_cascade = cv2.CascadeClassifier( '../cascades/haarcascade_frontalface_default.xml') while (True): ret, img = camera.read() faces = face_cascade.detectMultiScale(img, 1.3, 5) for (x, y, w, h) in faces: img = cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) roi = gray[x:x + w, y:y + h] try: roi = cv2.resize( roi, (200, 200), interpolation=cv2.INTER_LINEAR) # 将屏幕捕获的图片和训练后参数比较,是否符合特征 params = model.predict(roi) print("Label: %s, Confidence: %.2f" % (params[0], params[1])) cv2.putText(img, names[params[0]], (x, y - 20), cv2.FONT_HERSHEY_SIMPLEX, 1, 255, 2) print('cv2.putText') except: # print("Unexpected error:", sys.exc_info()) continue print('error') cv2.imshow("camera", img) if cv2.waitKey(1) & 0xff == ord("q"): break cv2.destroyAllWindows()
最后就是能识别出自己啦,原谅我的大脸