Tengo un video, https://www.youtube.com/watch?v=ldnrxndwycc. Estoy tratando de contar el número de personas desconocidas en este video, con las siguientes restricciones:

  1. El conteo desconocido aumentará en el nuevo detecto de cara única. y almacena la cara que codifica a una lista (Facelist).
  2. Supongamos que 1st Frame contiene 2 personas y el segundo cuadro contiene 4 personas. El código se comparará, nuevas caras (codificación de la cara nueva) con caras antiguas (codificaciones de la cara, que está presente en la matriz). y contar el número de caras nuevas que no está en la lista de la cara, y agrega este recuento a las caras desconocidas totales. Si se encuentra nueva cara, agrega la cara que codifica a la lista.
  3. En nuevo marco, si no hay codificación de cara, coincide con el elemento de Facelist, entonces borra el Facelist. Y agrega las nuevas codificaciones de la cara en la lista de la cara. El recuento desconocido aumentará de acuerdo con el número de personas nuevas.

Problema:

  1. Cuando una persona sonríe, o gira la cara de la parte delantera hacia la izquierda (o de la derecha hacia la derecha). Detecta la cara como una cara nueva, y aumenta el conteo desconocido

  2. No está detectando la cara nueva correctamente después de varios marcos.

Probado en Python3, Opencv2, Face_Recognition Python Biblioteca. Plataforma 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 Jugar este video En 0.02 seg, la persona debe ser tratada como personas desconocidas, y aumenta el recuento por uno. Pero no lo hace. Aumenta cuando la persona está sonriendo.

2
Pabitra Roy 1 jul. 2019 a las 13:07

1 respuesta

La mejor respuesta

Esto no es problema de la versión de Python. El problema que quieres resolver es muy desafiante. El problema se encuentra en la parte de detección y asociación. Primero, es posible que no tenga detección, segundo, el objeto detectado puede no estar asociado al siguiente cuadro.

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

Si la distancia es demasiado grande o demasiado pequeña entre el objetivo. Habrá fallado de asociación y asociación falsa. En este caso, lo más probable es que tenga que mejorar la precisión de la asociación de características faciales al obtener una función de codificación de función de mejor distancia.

Pareja que puedes hacer con un esfuerzo mínimo para mejorar el resultado.

Primera,

En lugar de

Frame1 -> Detectar -> Asociado

Frame2 -> Detectar -> Asociado

Frame3 -> Detectar -> Asociado

. ...

Tratar

Frame1 -> Detectar -> Seguimiento

Marco 2 -> Detectar -> Seguimiento -> Asociado

Frame3 -> Detectar -> Seguimiento -> Asociado

El seguimiento puede ser cualquier método, como KCT o TLD Tracker. Originalmente se implementa como rastreador individual y hay trabajo que los expande en múltiples rastreadores de destino. Puedes encontrarlos en el GitHub.

enter image description here

Como se muestra en la imagen, incluso tiene varias personas, habría menos asociado o asociado falso.

Segunda,

La otra cosa que puede intentar es usar la detección / seguimiento / asociación de esqueleto para la escena, francamente, no puedo diferenciar realmente entre el chico izquierdo y derecho. Especialmente cuando no se enfrentan directamente a la cámara, podría haber múltiples casos de detección / seguimiento / asociación fallidos.

enter image description here

Sin embargo, nos encontramos con este tipo de pregunta de postura / detección / asociación con frecuencia en la detección de esqueletos donde las personas pueden moverse, bailar y cambiar poses todo el tiempo. Hay muchos paquetes de seguimiento de detección de esqueleto de código abierto en el GitHub.

enter image description here

Depende de la cantidad de esfuerzo que desee poner en esto, podría haber muchas otras soluciones.

2
Community 20 jun. 2020 a las 09:12