Подсчитайте количество неизвестных в видео при следующих условиях - PullRequest
2 голосов
/ 01 июля 2019

У меня есть видео, https://www.youtube.com/watch?v=LdNrXndwyCc.Я пытаюсь подсчитать количество неизвестных людей в этом видео со следующими ограничениями:

  1. Число неизвестных будет увеличиваться при каждом новом уникальном обнаружении лица.и сохраняет кодировку лица в список (facelist).
  2. Предположим, что 1-й кадр содержит 2 человека, а 2-й кадр содержит 4 человека.Код будет сравнивать новые лица (кодирование новых лиц) со старыми лицами (кодировки лиц, присутствующие в массиве).и подсчитать количество новых лиц, которых нет в списке лиц, и добавить это количество к общему числу неизвестных лиц.если найдено новое лицо, оно добавляет кодировку лица в список.
  3. В новом кадре, если кодировка лица не соответствует ни одному из элементов списка, он очищает список лиц.И добавляет новые кодировки лица в список лиц.Число неизвестных будет увеличиваться в зависимости от количества новых людей.

Задача:

  1. Когда человек улыбается или поворачивает лицо спереди налево (или спереди)направо). Определяет лицо как новое лицо и увеличивает число неизвестных

  2. Не удается правильно определить новое лицо после нескольких кадров

Попробовал в Python3, opencv2, библиотеку python для face_recognition.Платформа 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 Ответ

2 голосов
/ 01 июля 2019

Это не проблема версии Python.Проблема, которую вы хотите решить, очень сложная.Проблема заключается в части обнаружения и ассоциации.Во-первых, у вас может не быть обнаружения, во-вторых, обнаруженный объект может быть не связан со следующим кадром.

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

Если расстояние слишком велико или слишком мало между целью.у вас будет неудачная ассоциация и ложная ассоциация.В этом случае вам, скорее всего, придется повысить точность сопоставления элементов лица, получив лучшую функцию расстояния / функцию кодирования лица.

Пара вещей, которые вы могли бы сделать с минимальными усилиями, чтобы улучшить результат.

Сначала

Вместо

frame1 -> обнаружение -> связать *> 1012 *

frame2 -> обнаружение -> связать

frame3 -> обнаружить -> связать

....

Попробуйте

frame1 -> обнаружить -> отслеживание

frame2 -> обнаружить -> отслеживание -> связать

frame3 -> обнаружить -> tracking -> assocaiate

Отслеживание может быть любым методом, таким как kct или tld tracker.Первоначально он реализован в виде отдельного трекера, и есть работа, которая расширяет их в несколько целевых трекеров.Вы можете найти их в github

enter image description here

Как показано на рисунке, даже если у вас несколько человек, было бы меньше ложных или неудачных партнеров.

Во-вторых,

Другая вещь, которую вы можете попробовать, - это использовать обнаружение / отслеживание / ассоциацию скелета для сцены, честно говоря, я не могу действительно различать левого и правого мальчика.Особенно, когда они не обращены непосредственно к камере, может быть несколько случаев неудачного обнаружения / отслеживания / ассоциации.

enter image description here

Однако мы часто сталкиваемся с таким типом вопроса о позе / обнаружении / ассоциации при обнаружении скелета, когда люди могут двигаться, танцевать и менять позы.время.В github также есть множество открытых пакетов отслеживания обнаружения скелетов.

enter image description here

Зависит от того, сколько усилий вы хотите приложить к этому, может быть много других решений.

...