计算符合以下条件的视频中的未知人数

时间:2019-07-01 10:07:28

标签: python python-3.x opencv face-recognition dlib

我有一个视频https://www.youtube.com/watch?v=LdNrXndwyCc。 我正在尝试计算此视频中的未知人数,但有以下限制:

  1. 每检测到一个新的唯一面部,未知计数就会增加。并将面部编码存储到列表(facelist)中。
  2. 假设第一帧包含2个人,第二帧包含4个人。 该代码将比较新面孔(新面孔编码)与旧面孔(面孔编码,存在于数组中)。并计算不在面孔列表中的新面孔的数量,并将此计数添加到未知面孔总数中。如果找到新面孔,则会将面孔编码附加到列表中。
  3. 在新帧中,如果没有面部编码与facelist的any元素匹配,则它将清除面孔列表。并将新的面部编码附加到面部列表中。未知人数会随着新人数的增加而增加。

问题:

  1. 一个人微笑或将其脸从前向左(或从前向右)旋转时,它将检测到该脸为新脸并增加未知数

  2. 几帧后无法正确检测到新面孔

在Python3,opencv2,face_recognition python的库中尝试过。平台Ubuntu 18.04

class FaceCount:
    def __init__(self):
        self.unknown_count=0

    def face_distance_to_conf(self,face_distance, face_match_threshold=0.6):
        if face_distance > face_match_threshold:
            range = (1.0 - face_match_threshold)
            linear_val = (1.0 - face_distance) / (range * 2.0)
            return linear_val
        else:
            range = face_match_threshold
            linear_val = 1.0 - (face_distance / (range * 2.0))
            return linear_val + ((1.0 - linear_val) * math.pow((linear_val - 0.5) * 2, 0.2))

    def countFaceThread(self,facelist,face_encodings):
        matched_with_no_one=True
        for face_encoding in face_encodings:      
            dup=False

            for face in facelist:

                match=face_recognition.compare_faces([face_encoding],face)[0]
                face_distanc=face_recognition.face_distance([face_encoding],face)
                percent=self.face_distance_to_conf(face_distanc)[0]
                print(percent)
                if match and percent>0.40:
                    dup=True
                    matched_with_no_one=False
                    break
            #print('finished Comparing')   
            if not dup:
                self.unknown_count+=1
                print("unknown_count---->",self.unknown_count)
                facelist.append(face_encoding)

        if matched_with_no_one:
            print("clearing facelist....")
            facelist.clear()
            print("unknown_count---->",self.unknown_count)
            for f_encode in face_encodings:
                facelist.append(f_encode)

    def countUnknown(self):
        cap = cv2.VideoCapture('livetest.webm')
        cap.set(cv2.CAP_PROP_POS_MSEC,30)
        facelist=[]
        while(cap.isOpened()):
            try:
                #istart=time.time()
                ret, frame = cap.read()

                #print('frame reading time------->',time.time()-istart)

                #start=time.time()
                rgb_frame = frame[:, :, ::-1]
                face_locations = face_recognition.face_locations(rgb_frame)

                face_encodings = face_recognition.face_encodings(rgb_frame, face_locations)
                #print("detection time----------->",time.time()-start)

                #start=time.time()
                cv2.imshow('frame', frame)
                for (top, right, bottom, left) in face_locations:
                    cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)
                    cv2.imshow('frame', frame)
                #print("showing the detected frame time----------->",time.time()-start)

                start=time.time()

                if facelist and face_encodings:
                    t2=threading.Thread(target=self.countFaceThread,args=(facelist,face_encodings))
                    t2.start()
                elif face_locations:
                    self.unknown_count+=len(face_locations)
                    print("unknown people------->",self.unknown_count)
                    for face in face_encodings:
                        facelist.append(face)
                    continue

                if cv2.waitKey(1) & 0xFF == ord('q'):
                    break

            except Exception as e:
                print(e)
    # When everything done, release the capture
        cap.release()
        cv2.destroyAllWindows()

if __name__=='__main__':

    t1=threading.Thread(target=FaceCount().countUnknown)
    t1.start()

https://www.youtube.com/watch?v=LdNrXndwyCc 播放这部影片 在0.02秒内,该人员应被视为未知人员,并将计数增加一。但事实并非如此。当人微笑时会增加

1 个答案:

答案 0 :(得分:2)

这不是python版本的问题。您要解决的问题非常具有挑战性。问题在于检测和关联部分。首先,您可能没有检测到,其次,检测到的对象可能未与下一帧关联。

match=face_recognition.compare_faces([face_encoding],face)[0]
face_distanc=face_recognition.face_distance([face_encoding],face) 

目标之间的距离太大或太小。您将拥有失败的关联和错误的关联。在这种情况下,您很可能必须通过获得更好的距离函数/人脸编码功能来提高人脸特征关联的准确性。

结合您可以以最小的努力来改善结果的事情。

首先

代替

frame1->检测->关联

frame2->检测->关联

frame3->检测->关联

。 ...

尝试

frame1->检测->跟踪

frame2->检测->跟踪->关联

frame3->检测->跟踪->关联

跟踪可以是任何方法,例如kct或tld跟踪器。它最初是作为单独的跟踪器实现的,有些工作将它们扩展为多个目标跟踪器。您可以在github中找到它们

enter image description here

如图所示,即使您有多人,也会减少假同事或失败同事的人数。

第二,

您可以尝试的另一件事是对场景使用骨骼检测/跟踪/关联,坦率地说,我无法真正区分左男孩和右男孩。特别是当它们不直接面对相机时,可能会出现多种检测/跟踪/关联失败的情况。

enter image description here

但是,在骨架检测中,我们确实经常遇到这种类型的姿势/检测/关联问题,人们可以一直移动,跳舞和改变姿势。 github中也有许多开源框架检测跟踪包。

enter image description here

取决于您要为此付出多少努力,可能会有许多其他解决方案。