根据以下条件计算视频中未知人数

Count the number of unknown people in a video with following conditions

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

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

问题:

  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 秒内,此人应被视为未知人,并将计数加一。但事实并非如此。当人微笑时它会增加

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

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

如果目标之间的距离太大或太小。你会有失败的联想和虚假的联想。在这种情况下,您很可能必须通过获得更好的距离 function/face 编码函数来提高面部特征关联的准确性。

一些你可以用最少的努力来改善结果的事情。

首先,

而不是

frame1 -> 检测 -> 关联

frame2 -> 检测 -> 关联

frame3 -> 检测 -> 关联

。 ...

尝试

frame1 -> 检测 -> 跟踪

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

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

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

中找到它们

如图所示,即使你有多个人,也会减少错误关联或失败关联。

其次,

另一个你可以尝试的是场景使用骨架detection/tracking/association,坦白说,我真的分不清左男孩和右男孩。特别是当他们没有直接面对相机时,可能会出现多次失败的情况 detection/tracking/association.

然而,我们确实经常在骨骼检测中遇到这种类型的 pose/detection/association 问题,因为人们可以随时移动、跳舞和改变姿势。 github里面也有很多开源的骨骼检测追踪包。

取决于你想在这方面投入多少努力,可能还有很多其他解决方案。