前言:

虽然本段代码的目标是准确率计算,但识别率只是提供了一个简单的思路,单纯计算了正确的概率。代码的主要部分还是图片的匹配识别内容,所有的代码块都有响应的详尽解释,适合初期接触和了解的learner阅读。
在后续准备训练数据时繁琐的工作令人头大,准备了几十个图像就花去了我大半时间,图像处理中往往需要大量图片进行训练,显然这种情况下这种方法是不可行的,不过目前也是一种思路,接下来在接触的过程中会继续了解相关的计算和评测方法,争取找到最佳,计算效果最好的方法进行准确率的计算。本人也是才接触这部分内容,了解内容有限,大家有比较好的方法方式欢迎评论交流。

1 概率计算公式

实现自动计算识别准确概率:

r a t e = n r / ( n c − n u ) rate = n^r/(n^c-n^u) rate=nr/(nc−nu)
其中,上式rate为识别准确概率, nr为正确识别人脸图片个数,nc为文件夹下图片总数量,nu为未识别到人脸区域图像数量。

2 实现代码部分

该方法正确计算前提是:**将测试图像和训练的图像分辨放在一个文件夹下,并将测试图像与已有的训练图像使用相同的图片文件名称和格式。**因为我目前采取的是将图片名称作为图像是否正确识别判断的根据,根据测试图像名称和匹配的图像名称是否相同,判断识别是否正确。也尝试过使用面部编码数据是否相等进行判断,测试结果显然,这种方式是不可行 的,因为同一个人在不同照片中由于角度或者场景等各种因素的影响,编码方式不可能完全相同。
识别方法采用:opencv + face_recognition
识别率计算代码如下:

"""
import os
# class TestAccuracyRate():
import cv2
import face_recognition
import numpy as np

def trainImage():
    train_dir = 'rate_train_data' # 训练文件夹
    # 将训练文件夹下的图片放到一个列表中
    train_image_list = os.listdir(train_dir)
    print("训练图片数量:%s"%len(train_image_list))

    # 定义空列表,存放文读取的图片名称
    train_image_names_list = []
    # 存放读取的图片相对路径
    train_image_paths_list = []
    # 存放图片转化的numpy数组
    train_image_rec_list = []
    # 存放每个图片面部编码的第一个面部编码信息
    train_image_encodings_list = []
    '源文件读取训练数据'
    # 遍历列表,读取列表中的训练图片文件名
    for per_image in train_image_list:
        name = per_image.strip('.jpg')
        # print(name)
        train_image_names_list.append(name)  # 将读取的图片名称添加到预先定义好的列表中
        # 设定每幅图片的相对路径,根据路径读取每幅图片
        train_per_image_path = os.path.join(train_dir,per_image)
        train_image_paths_list.append(train_per_image_path) #将每幅图片的路径添加到预先定义好的列表中
        # 加载训练图像通过face_recognition学习如何识别它,将文档加载到numpy数组中,以便计算机进行识别。
        train_per_image_rec = face_recognition.load_image_file(train_per_image_path)
        train_image_rec_list.append(train_per_image_rec)
        # print(train_per_image_rec[0])
        # 获取每个图像面部编码信息
        train_per_image_encoding = face_recognition.face_encodings(train_per_image_rec)[0]
        # print("训练图片%s人脸检测完成"%name)
        train_image_encodings_list.append(train_per_image_encoding)
        # print(train_per_image_encoding)
    # print(train_image_names_list)
    return train_image_names_list,train_image_encodings_list

def testImage():
    '进行测试文件的自动读取'
    # 测试图片路径
    test_dir = 'rate_test_data' # 测试文件夹
    # 将测试图片名称读取到一个列表中
    test_image_list = os.listdir(test_dir)
    # print(test_image_list)
    # 获取测试图像总数量
    test_date_num = len(test_image_list)
    print('测试图片数量为:%s 张'%test_date_num)
    # 读取训练数据
    train_image_names_list, train_image_encodings_list = trainImage()
    print('========================')
    print("源文件读取完成。。。")
    # 设置初始人脸识别成功个数为0
    reco_count = 0 # 成功识别人脸识别数
    decate_count = 0 # 未成功识别人脸图片数
    right_reco_count = 0 #正确匹配人脸图片数
    undecate_count = 0  # 未成功检测到人脸数量
    unsuccess_reco_count =0 # 未成功识别人人脸数量
    unsuccess_reco_name_count = []  # 未成功识别人脸列表
    undecate_name_list = []  # 未成功检测人脸列表
    false_right_reco_name_list = [] # 识别并匹配成功,但未正确匹配人脸图片列表
    print("图像识别中。。。")
    # 遍历列表,进行测试图片处理
    for per_image in test_image_list:

        # 图像名称以人物名命名,读取人物名
        name = per_image.strip('.jpg')
        # 图像的相对路径
        test_per_image_path = os.path.join(test_dir, per_image)
        # cv读取图片,图像为bgr方式
        per_image_cv = cv2.imread(test_per_image_path)
        # print(per_image_cv)
        # cv2.imshow('per_image_cv',per_image_cv)
        # cv2.cvtColor():颜色空间转换函数。把图像从RGB转换到RGB颜色空间,对图片进行预处理。
        per_image_cvcolor = cv2.cvtColor(per_image_cv,cv2.COLOR_BGR2RGB)
        # cv2.imshow('per_image_cvcolor', per_image_cvcolor)
        # cv2.waitKey(0)
        # 获取图像面部编码中的面部编码信息
        '此处图片没有检测到人脸时往下执行则会报错,需要在下一步之前增加判断条件:是否检测到人脸信息!'
        per_image_encoding = face_recognition.face_encodings(per_image_cvcolor)
        # print(per_image_encoding)
        '判断条件:图片人脸编码是否为空!'
        if len(per_image_encoding)>0:
            decate_count+=1
            # 获取检测到人脸时面部编码信息中数组0位置面部编码
            per_image_encoding = per_image_encoding[0]
            "图像人脸识别部分代码,同时使用compare_faces和face_distance方法提高训练结果准确度。"
            # 根据面部编码匹配脸,布尔类型列表
            matchs_bool_list = face_recognition.compare_faces(train_image_encodings_list,per_image_encoding,tolerance=0.46)
            print(matchs_bool_list)
            print(train_image_names_list)
            # 根据面孔之间的欧氏距离,返回一个数值列表
            face_distances_list = face_recognition.face_distance(train_image_encodings_list,per_image_encoding)
            # 根据欧式距离,查找最相似面孔的索引
            print(face_distances_list)
            best_match_index = np.argmin(face_distances_list)
            print(best_match_index)
            # print(train_image_names_list[best_match_index])
            print("name:%s,match_name:%s" % (name, train_image_names_list[best_match_index]))
            if matchs_bool_list[best_match_index]:
                match_name = train_image_names_list[best_match_index]
                # best_match_encoding = train_image_encodings_list[best_match_index]
                print('匹配人物姓名:%s'%match_name)
                reco_count+=1
            else:
                unsuccess_reco_count+=1
                unsuccess_reco_name = name+'.jpg'
                unsuccess_reco_name_count.append(unsuccess_reco_name)
                match_name = 'unknown_person'
            # 设置文件名相同,根据文件名测试准确识别
            if name == match_name:
                right_reco_count+=1
            else:
                false_right_reco_name = name+'.jpg'
                false_right_reco_name_list.append(false_right_reco_name)
        else:
            undecate_count+=1
            undecate_name = name+'.jpg'
            undecate_name_list.append(undecate_name)
            print("图片%s.jpg未检测到有效人脸区域,请检测上传图片是否为人脸正面区域!"%name)
    # print("识别完成!")

    print("成功检测人脸图片数量:%s,未检测到人脸图片数量:%s || 成功识别成功匹配人脸数量:%s,成功识别未成功匹配到人脸图片数量%s || 正确匹配人脸图片数量:%s"%(decate_count,undecate_count,reco_count,unsuccess_reco_count,right_reco_count))
    # print("成功匹配人脸数量:%s"%reco_count)
    # print("正确匹配人脸图片数量:%s"%right_reco_count)
    print("成功识别未成功匹配到人脸图片名称列表:%s"%(unsuccess_reco_name_count))
    print("识别匹配成功,但未正确匹配人脸图片名称列表:%s" % (false_right_reco_name_list))
    print("未成功检测人脸图片名称列表:%s" % (undecate_name_list))
    reco_rate = reco_count / (test_date_num - undecate_count)
    # print("识别完成!识别成功率为:%s%%" % (reco_rate * 100))  # 识别准确率百分号显示
    right_reco_rate = right_reco_count / (test_date_num - undecate_count)
    print("识别完成!识别成功率为:%s%%,识别人物姓名准确匹配率为:%s%%" % ((reco_rate * 100),(right_reco_rate * 100)))  # 识别准确率百分号显示
# cv2.destroyAllWindows()

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐