OpenCV之路(三)

来源:互联网 发布:gz java 编辑:程序博客网 时间:2024/06/08 03:54

人脸识别

一直跟着opencv3+计算机视觉来体验opencv的魅力,这次被小小坑了一下,源代码还找不到,小小吐槽一下。

准备数据
准备一堆正确的数据,用来给算法学习。推荐用摄像头直接捕获自己的脸然后生成符合要求的图片,用照片的话第一质量不行,第二数量可能不行,第三未必能正确识别。献上代码(util是之前用来管理视频获取源的可以不用):
import cv2import syssys.path.append('../../src/')import utils as utildef 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 osimport cv2import syssys.path.append('../../src/')import utils as utilimport 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"):        breakcv2.destroyAllWindows()

最后就是能识别出自己啦,原谅我的大脸
这里写图片描述