• Python-中北大学人工智能OpenCV人脸识别(根据图片训练数据,根据训练好的数据识别人脸)


    1. 根据训练照片训练数据模型

    在这里插入图片描述
    训练流程:

    1. 读取文件夹下的所有文件,使用PIL 库中的Image方法打开图片,并将其转化为灰度图片。
    2. 加载人脸数据分类器,这里直接使用OpenCV库自带的(cv.CascadeClassifier(…))
    3. 使用numpy.array方法,让照片向量化。使用分类器detectMultiScale方法,提取图片脸部特征值。
    4. 将一个人的信息和脸部特征值写入到文件中,达到训练的目的

    照片命名格式:学号-1/学号-2+.jpg

    import cv2 as cv
    import os
    from PIL import Image
    import numpy as np
    
    
    # 根据jpgForTrainer文件夹中的图片进行训练,随后的训练数据保存到trainer/trainer.yml
    
    def getImageAndLabel(url):
        # 储存人脸数据
        faces_msg = []
        name = []
        # 保存图片信息
        imagePaths = [os.path.join(url, f) for f in os.listdir(url)]
        # 加载分类器
        detector = cv.CascadeClassifier('../haarcascade_frontalface_alt2.xml')
        # 遍历图片
        for pict in imagePaths:
            fileImg = Image.open(pict).convert('L')  # 打开灰度图像
            # 图片向量化
            imgNumpy = np.array(fileImg, 'uint8')
            face = detector.detectMultiScale(imgNumpy, 1.1, 5)  # 提取图片脸部特征值
            # 提取图片的学号
            ids = int(os.path.split(pict)[1].split('-')[0])
            flag = False
            for x, y, w, h in face:
                # 保存脸部数据
                flag = True
                name.append(ids)
                faces_msg.append(imgNumpy[y:y + h, x:x + w])  # 保存脸部数据
            if flag:
                print(f'DEBUG:捕捉到学号为{ids}的人脸,')
        print('DEBUG')
        print('id', name)
        print('face', faces_msg)
        return faces_msg, name
    
    
    if __name__ == '__main__':
        path = "../jpgForTrainer/"
        # 获取人脸特征和姓名
        faces, id = getImageAndLabel(path)
        # 加载识别器
        recognize = cv.face.LBPHFaceRecognizer_create()
        recognize.train(faces, np.array(id))
        # 保存文件
        recognize.write('../trainer/trainer.yml')
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    2. 根据训练的数据文件,进行人脸识别

    步骤:

    1. 将要识别的图片使用os模块,读取进来
    2. 使用cv2库(检测cv)cv.imread函数打开图片,调用人脸识别函数(自定义)进行识别,函数返回从训练数据里面查找的复合条件的学号,根据图片名称来判断识别是否准确
    3. 人脸识别函数中,使用data = cv.face.LBPHFaceRecognizer_create(),data.read(‘…/trainer/trainer.yml’)来加载训练好的数据。
    4. 使用data.predict函数来预测准确性,准确性在25以内的就可以认为识别成功,将学号写到图片上调用cv.imshow函数进行输出。可以使用cv.resize函数对图片进行缩放后再将识别信息写到图片上。
    5. 最后统计识别学号和照片名称学号对应的比例来计算识别成功率即可。
    # 测试人脸识别
    # 测试人脸识别
    import cv2 as cv
    import os
    
    # 加载训练数据文件
    data = cv.face.LBPHFaceRecognizer_create()
    data.read('../trainer/trainer.yml')
    
    # 错误数目
    fault = 0
    
    path = '../jpgForTest'
    
    
    # 根据jpgForTest里面的文件来进行识别测试
    
    # 识别模块
    def discern(_img):
        ret = []
        gray = cv.cvtColor(_img, cv.COLOR_BGR2GRAY)
        # 加载分类器
        detector = cv.CascadeClassifier('../haarcascade_frontalface_alt2.xml')
    
        face_data = detector.detectMultiScale(gray, 1.1, 5)
        resize = _img
        flag = False
        for x, y, w, h in face_data:
            flag = True
            cv.rectangle(_img, (x, y,), (x + w, y + h), color=(0, 0, 255), thickness=1)
            # 人脸识别
            s_id, confidence = data.predict(gray[y:y + h, x:x + w])
            resize = cv.resize(_img, dsize=(700, 600))
            if confidence > 80:
                # cv.putText(resize, 'UnKnow', (10, 50), cv.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1)
                pass
            else:
                print('标签id:', s_id, '置信评分:', confidence)
                cv.putText(resize, str(s_id), (5, 50), cv.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1)
                ret.append(s_id)
        if not flag:
            # 没检测到人脸
            resize = cv.resize(_img, dsize=(700, 600))
            cv.putText(resize, 'Not Find Face', (5, 50), cv.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1)
        # 压缩图片输出
        cv.imshow('result', resize)
        while True:
            get = cv.waitKey(1000)
            if ord(' ') == get or get == -1:
                break
        return ret
    
    
    # # 获取训练人的学号,以此来判断陌生人脸是否识别成功
    # def getMessage():
    #     target = os.listdir('../jpgForTrainer')
    #     msg = []
    #     for Str in target:
    #         tmp = Str.split('-')[0]
    #         if tmp not in msg:
    #             msg.append(tmp)
    #     return msg
    
    
    if __name__ == '__main__':
        files = os.listdir(path)  # 得到文件夹下的所有文件名称
        size = len(files)
        for file in files:  # 遍历文件夹
            stu_id = file.split('.')[0]
            print('-------\n' + path + "/" + file + "正在识别")
            img = cv.imread(path + '/' + file)
            ret = discern(img)
    
            if len(ret) == 0:
                fault += 1
                print(f'识别错误应该学号为{stu_id},识别学号为UnKnow')
            else:
                for item in ret:
                    if str(item) not in str(stu_id):
                        fault += 1
                        print(f'识别错误应该学号为{stu_id},识别学号为{ret}')
            print('\n----------\n')
        print(f'DEBUG:识别失败的个数{fault},测试识别总数{size}')
        print(f'测试成功概率{((size - fault) / size) * 100}%')
        cv.destroyAllWindows()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86

    需要注意的是:这个实验使用的haarcascade_frontalface_alt2.xml文件,是OpenCV自带的人脸图像提取算法,需根据实际路径选取

    代码中的置信评分越小,越可靠。

    参考资料
    一天搞定人脸识别项目!

    运行结果:
    在这里插入图片描述
    这个是我用训练集做的,准确度很高,经过测试。实际准确度在40%左右,比较低

  • 相关阅读:
    5G毫米波通信中的关键技术
    如何开始着手一篇Meta分析 | Meta分析的流程及方法
    Vue2、Vue3 和 React 中 Diff 算法的区别
    JS逆向分析某枝网的HMAC加密、wasm模块加密
    基于食肉植物优化的BP神经网络(分类应用) - 附代码
    18.定位元素练习-淘宝网
    宝塔FTP提示:553 Can‘t open that file: Permission denied的解决方案
    Leetcode刷题1373. 二叉搜索子树的最大键值和
    9月8日作业
    Chainlink Keepers 能够帮助 Web3 开发者更快开发的 7 个特性
  • 原文地址:https://blog.csdn.net/dodamce/article/details/127964648