当前位置:   article > 正文

使用opencv和face_recognition进行人脸识别_opencv 4.8 face recognition

opencv 4.8 face recognition

该代码包含人脸数据采集和人脸识别两部分。

import face_recognition
import cv2 as cv
import numpy as np
import time
import os
class Rec_frg(object):
    #定义全局变量
    def __init__(self):
        self.video_path = r"D:\pythonItems\opencv1\vodeo"
        self.image_data_path = r"D:\pythonItems\opencv1\reg_facedata"
        self.nums = 40
        self.name = []
        self.face_encodings = []
    # 定义函数:用于计算视屏时长
    def video_duration(self,filename):
        cap = cv.VideoCapture(filename)
        if cap.isOpened():
            rate = cap.get(5)
            frame_num = cap.get(7)
            duration = frame_num // rate * 30
            times = duration // 60
            return times
        return -1

    #定义方法:用于收集数据
    def image_datacolloct(self):
        waitKey_count = 0
        #显示该文件夹下的所有内容
        video_path = os.listdir(self.video_path)
        #分别显示每一个视屏
        for path_v in video_path:
            img_num = 1
            # 找到每个视屏的绝对路径
            p = r"{}".format(os.path.join(self.video_path,path_v))
            #调用函数计算视屏时长
            all_times = self.video_duration(p)
            #打开视屏
            capture = cv.VideoCapture(p)
            while True:
                have_landmasks = True
                # 构造保存图片时图片的名称
                name = path_v.split(".")[0] +"_"+ str(img_num)
                # 通过视屏名称,找出每个人的名字
                label_name = path_v.split(".")[0]
                #显示时频每一帧
                ret, frame = capture.read()
                #缩小视屏宽、高为原来的一般
                frame = cv.resize(frame, (0, 0), fx=0.5, fy=0.5)
                #将每一帧的BGR格式转换为RGB格式
                rgb_small_frame_data = frame[:, :, ::-1]
                if ret == False:
                    break
                #找出每一帧中人脸的位置
                face_location = face_recognition.face_locations(rgb_small_frame_data)
                #训练集面部特征编码
                if waitKey_count == 0:
                    face_encoding = face_recognition.face_encodings(rgb_small_frame_data,model= "large")
                    if len(face_encoding) == 0:
                        have_landmasks = False
                    else:
                        have_landmasks = True
                        #将np.array()类型转换为list类型
                        fs = face_encoding[0].tolist()
                        #将数据和标签添加到列表中
                        self.face_encodings.append(fs)
                        self.name.append(label_name)
                        #保存图片
                        cv.imwrite("D:/pythonItems/opencv1/reg_facedata/"+name+".jpg",frame)
                        img_num += 1
                #设置退出条件
                if img_num > self.nums:
                    break
                c = cv.waitKey(1)
                if c == 27:
                    break
                #设置人脸数据获取条件
                if len(face_location) > 0 and have_landmasks == True:
                    waitKey_count += 1
                    print("wait",waitKey_count)
                if waitKey_count == all_times - 1:
                    waitKey_count = 0
                cv.imshow("face", frame)
            #释放资源
            capture.release()
        #显示收集好的数据及标签
        print("location", self.face_encodings)
        print("name", self.name)
        #将数据和标签存入文件中用于识别时使用
        f_data = open("data.txt", "w")
        f_name = open("name.txt","w")
        f_data.write(str(self.face_encodings))
        f_name.write(str(self.name))
        #关闭文件
        f_data.close()
        f_name.close()
        #关闭所有窗口
        cv.destroyAllWindows()
    #定义方法:用于识别
    def face_dances(self,video_name):
        success = 0
        fail = 0
        known_face_encodings = []
        video_capture = cv.VideoCapture(video_name)
        #读取人脸编码数据和标签
        data_file = open("data.txt", "r")
        label_file = open("name.txt","r")
        data = eval(data_file.read())
        #将从文件中读取出的每一张人脸数据的类型转化为 np.array()类型
        for i in data:
            list_to_array = np.array(i)
            known_face_encodings.append(list_to_array)
        known_face_names = eval(label_file.read())
        #关闭文件
        data_file.close()
        label_file.close()

        # 初始化变量
        process_this_frame = True
        time1 = time.time()

        while True:
            face_names = []
            name_str = ""
            # 读取视屏每一帧
            ret, frame = video_capture.read()
            if ret == False:
                break
            # 将视屏款、高缩小一半
            frame = cv.resize(frame, (0, 0), fx=0.5, fy=0.5)

            # 将BGR格式转化为RGB
            rgb_small_frame = frame[:, :, ::-1]

            # 只处理每隔一帧的视频以节省时间
            if process_this_frame:
                # 定位所找到的人脸的位置
                face_locations = face_recognition.face_locations(rgb_small_frame)
                # 对面部特征进行编码
                face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations,model= "large")
                #循环每一个编码好的人脸
                for face_encoding in face_encodings:
                    # 由面部编码匹配人脸
                    matches = face_recognition.compare_faces(known_face_encodings, face_encoding,tolerance=0.5)
                   #计算 "Ture" 的个数
                    true_count = matches.count(True)
                    # print(matches)
                    # print(true_count)
                    #计算要识别的人脸和每个已知人脸之间的距离
                    face_distances = face_recognition.face_distance(known_face_encodings, face_encoding)
                    #找出最小距离的索引
                    best_match_index = np.argmin(face_distances)
                    #判断条件
                    if matches[best_match_index] == False or true_count < self.nums:
                        name = "Unknown"
                        #循环每一张人脸
                        for top, right, bottom, left in face_locations:
                            #画出人脸框
                            cv.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)
                            fail += 1
                            # 画出标签背景框
                            cv.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv.FILLED)
                            font = cv.FONT_HERSHEY_DUPLEX
                            #显示标签
                            cv.putText(frame, name, (left + 6, bottom - 6), font, 0.6, (255, 255, 255), 2)
                            if fail == 10:
                                print("识别失败!")
                                fail = 0
                                #计算时间
                                time2 = time.time()
                                spend = time2 - time1
                                print("花费时长:", spend)
                                time1 = time.time()

                    else:
                        #找出距离最小人脸的名字
                        name = known_face_names[best_match_index]
                        face_names.append(name)
                        #将人脸和相应的标签合并,并循环每一张人脸
                        for (top, right, bottom, left),name in zip(face_locations,face_names):
                            # 画出人脸框
                            cv.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 2)
                            success += 1
                            # 画出标签背景框
                            cv.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 255, 0), cv.FILLED)
                            font = cv.FONT_HERSHEY_DUPLEX
                            #显示标签
                            cv.putText(frame, name, (left + 6, bottom - 6), font, 0.6, (255, 255, 255), 2)
                            if success == 10:
                                for name_one in face_names:
                                    name_str += name_one+"  "
                                print("    识别成功!")
                                print(f"{name_str} 欢迎光临!")
                                time2 = time.time()
                                spend = time2 - time1
                                print("花费时长:", spend)
                                time1 = time.time()
                                success = 0


            # 显示每一帧视屏
            cv.imshow('Video', frame)

            #按ESC键退出
            key = cv.waitKey(1)
            if key == 27:
                break

        # 释放视屏资源,并关闭所有窗口
        video_capture.release()
        cv.destroyAllWindows()


#程序入口
if __name__ == "__main__":
    answer = input("人脸采集请输入0,输入其他进行识别!")
    video1 = "test.mp4"
    video2 = "girl_test.mp4"
    #实例化类
    Facerecognition = Rec_frg()
    #判断采集还是识别
    if answer == "0":
        Facerecognition.image_datacolloct()
        Facerecognition.face_dances(video1)
    else:
        Facerecognition.face_dances(video1)
  • 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
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225

结果(只显示人脸识别部分):

在这里插入图片描述
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/在线问答5/article/detail/945839
推荐阅读
相关标签
  

闽ICP备14008679号