-1

Hy guys based on then last question that I asked in which I haven't gotten a correct answer.

I want to write a program with face_recognition library. Its purpose is to save an image clip of a new face to a folder, updates the folder so as not to save the same face twice. I want the program to save an image to folder whenever it encounters a new face in the input video. But for now it doesn't seem to work. Sometimes it saves the whole clip of the same face to the folder which is not what I want. Can anyone help me with this code. I modified this code from a tutorial from #Murtaza I saw on youtube.

I still get this error

Traceback (most recent call last):
  File "C:/Users/CHIJINDU/AppData/Roaming/JetBrains/PyCharmEdu2020.1/scratches/KRecUnknownFace2.py", line 26, in <module>
    encodelistKnown = find_encodings(images)
  File "C:/Users/CHIJINDU/AppData/Roaming/JetBrains/PyCharmEdu2020.1/scratches/KRecUnknownFace2.py", line 21, in find_encodings
    encode = face_recognition.face_encodings(img)[0]
IndexError: list index out of range

This is the improved code below.

import face_recognition
import cv2
import os
import numpy as np


path = r"C:\Users\CHIJINDU\Desktop\KArtIntel"
images = []
class_names= []
myList = os.listdir(path)
for cl in myList:
    curImg= cv2.imread(f'{path}\{cl}')
    images.append(curImg)
    class_names.append(os.path.splitext(cl)[0])
print(class_names)

def find_encodings(images):
    encodelist = []
    for img in images:
        img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
        encode = face_recognition.face_encodings(img)[0]
        #encode= face_recognition.face_encodings(img)[0]
        encodelist.append(encode)
    return encodelist

encodelistKnown = find_encodings(images)
print(len(encodelistKnown))

cap = cv2.VideoCapture(r"C:\Users\CHIJINDU\Desktop\Elastic.mp4")

while True:
    success, img = cap.read()
    imgS = cv2.resize(img, (0,0), None, 0.25,0.25)
    imgS =cv2.cvtColor(imgS, cv2.COLOR_BGR2RGB)

    faceCurFrame= face_recognition.face_locations(imgS)
    encodesCurFrame= face_recognition.face_encodings(imgS, faceCurFrame)

    for encodeFace, faceloc in zip(encodesCurFrame, faceCurFrame):
        matches =  face_recognition.compare_faces(encodelistKnown,encodeFace)
        faceDis = face_recognition.face_distance(encodelistKnown,encodeFace)
        matchIndex= np.argmin(faceDis)

        i=0
        if encodesCurFrame not in encodelistKnown:
            newImg= cv2.imwrite(r'C:\Users\CHIJINDU\Desktop\KArtIntel\KUDOS-J14{index}.jpg'.format(index=i), img)
            images.append((newImg))
            #fps = int(video_capture.get(cv2.CAP_PROP_FPS))
            #print(fps)
            i+=1

    # Display the resulting image
    cv2.imshow('Video', img)

    # Hit 'q' on the keyboard to quit!
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# Release handle to the webcam
cap.release()
cv2.destroyAllWindows()
Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36
KUDOS
  • 1
  • 2
  • Please supply the expected [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) (MRE). We should be able to copy and paste a contiguous block of your code, execute that file, and reproduce your problem along with tracing output for the problem points. This lets us test our suggestions against your test data and desired output. Show where the intermediate results differ from what you expected. – Prune May 13 '21 at 18:04
  • We expect you to perform basic diagnosis to include with your post. At the very least, print the suspected values at the point of error and trace them back to their sources. The error message is clear: there is no element 0 in the returned object, which means that it's an empty sequence. – Prune May 13 '21 at 18:05
  • 1
    According to [the documentation on the `face_encodings` function](https://face-recognition.readthedocs.io/en/latest/face_recognition.html#face_recognition.api.face_encodings), it returns "`the 128-dimension face encoding for each face in the image`". Your code is always trying to access the first face encoding, via `[0]`, meaning that your code will throw the exception you're getting if no faces were detected. You didn't specify if this is happening for all images or just some, but regardless, your code doesn't handle that case when it probably should. – Random Davis May 13 '21 at 18:06

1 Answers1

1

Random Davis is right on....i changed the portion of code to include failover and ti worked. try also with the attached file to see the different behavior with a very easy to find face

import face_recognition
import cv2
import os
import numpy as np



path = r"C:\\Users\\shawn.ramirez\\Pictures\\Scans"
images = []
class_names= []
myList = os.listdir(path)
for cl in myList:
    curImg= cv2.imread(f'{path}\{cl}')
    images.append(curImg)
    class_names.append(os.path.splitext(cl)[0])
print(class_names)

def find_encodings(images):
    encodelist = []
    for img in images:
        img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
        try:
            encode = face_recognition.face_encodings(img)[0]
            #encode= face_recognition.face_encodings(img)[0]
            encodelist.append(encode)
            return encodelist
        except:
            error = []
            print("found no faces")
            return error

encodelistKnown = find_encodings(images)
print(len(encodelistKnown))

cap = cv2.VideoCapture(r"C:\\Users\\shawn.ramirez\\Pictures\\Camera Roll\\sample.mp4")

while True:
    success, img = cap.read()
    imgS = cv2.resize(img, (0,0), None, 0.25,0.25)
    imgS =cv2.cvtColor(imgS, cv2.COLOR_BGR2RGB)

    faceCurFrame= face_recognition.face_locations(imgS)
    encodesCurFrame= face_recognition.face_encodings(imgS, faceCurFrame)

    for encodeFace, faceloc in zip(encodesCurFrame, faceCurFrame):
        matches =  face_recognition.compare_faces(encodelistKnown,encodeFace)
        faceDis = face_recognition.face_distance(encodelistKnown,encodeFace)
        matchIndex= np.argmin(faceDis)

        i=0
        if encodesCurFrame not in encodelistKnown:
            newImg= cv2.imwrite(r'C:\Users\CHIJINDU\Desktop\KArtIntel\KUDOS-J14{index}.jpg'.format(index=i), img)
            images.append((newImg))
            #fps = int(video_capture.get(cv2.CAP_PROP_FPS))
            #print(fps)
            i+=1

    # Display the resulting image
    cv2.imshow('Video', img)

    # Hit 'q' on the keyboard to quit!
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# Release handle to the webcam
cap.release()
cv2.destroyAllWindows()

enter image description here

Shawn Ramirez
  • 796
  • 1
  • 5
  • 10
  • I edited my code like you did and I got this error again. `Traceback (most recent call last): File "C:/Users/CHIJINDU/AppData/Roaming/JetBrains/PyCharmEdu2020.1/scratches/KRecUnknownFace2.py", line 50, in if encodesCurFrame not in encodelistKnown: ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()`. What did I do wrong – KUDOS May 13 '21 at 18:57
  • Chances are your error is further down now...you'll have to handle an empty list being returned for: find_encodings() – Shawn Ramirez May 13 '21 at 18:59
  • Shawn Please can you show me how? – KUDOS May 13 '21 at 19:03