【问题标题】:IndexError: list index out of range while attempting to automatically recognize faces using face_recongitionIndexError:在尝试使用 face_recongition 自动识别人脸时列出超出范围的索引
【发布时间】:2019-12-17 20:11:58
【问题描述】:

我试图在视频中保存未知面孔并根据它们出现的第一帧识别它们,例如,如果未知面孔出现在第 14 帧上,它应该被识别为“新的 14”,但我不断收到出现新面孔时出现错误“IndexError: list index out of range”。 所以这是我的代码和回溯。

import face_recognition
import cv2

input_movie = cv2.VideoCapture("video.mp4")
length = int(input_movie.get(cv2.CAP_PROP_FRAME_COUNT))

# Create an output movie file (make sure resolution/frame rate matches input video!)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
output_movie = cv2.VideoWriter('output.avi', fourcc, 29.97, (640, 360))


newimage = face_recognition.load_image_file("anchor.png")
new_face_encoding = face_recognition.face_encodings(newimage)[0]

known_faces = [
    new_face_encoding,

]

# Initialize some variables
face_locations = []
face_encodings = []
face_names = []
frame_number = 0


def recog(frame_number, known_faces, face_names):
    toenc = []

    torec = face_recognition.load_image_file(r"New\Unknown%s.jpg" %str(frame_number))

    #if not len(torec):
     #   print("cannot find image")
    #torec = face_recognition.load_image_file(r"New\Unknown%s.jpg" %str(frame_number))
    toenc.append((face_recognition.face_encodings(torec))[0])
    if not len(toenc):
        print("can't be encoded")
    known_faces.append(toenc.pop())
    face_names.append("new %s" %str(frame_number))      

# Load some sample pictures and learn how to recognize them.

while True:
    # Grab a single frame of video
    ret, frame = input_movie.read()
    frame_number += 1

    # Quit when the input video file ends
    if not ret:
        break

    # Convert the image from BGR color (which OpenCV uses) to RGB color (which face_recognition uses)
    rgb_frame = frame[:, :, ::-1]

    # Find all the faces and face encodings in the current frame of video
    face_locations = face_recognition.face_locations(rgb_frame)
    face_encodings = face_recognition.face_encodings(rgb_frame, face_locations)

    #face_names = []
    for face_encoding in face_encodings:
        # See if the face is a match for the known face(s)
        match = face_recognition.compare_faces(known_faces, face_encoding)


        # If you had more than 2 faces, you could make this logic a lot prettier
        # but I kept it simple for the demo
        name = "Unknown"

        face_names.append(name)

    # Label the results
    for (top, right, bottom, left), name in zip(face_locations, face_names):
        if not name:
            continue

        # Draw a box around the face
        unface = cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)
        if name == "Unknown":
            res = frame[top:bottom, left:right]
            cv2.imwrite(r"New\Unknown%s.jpg" %str(frame_number), res)
            recog(frame_number, known_faces, face_names)

        cv2.rectangle(frame, (left, bottom - 25), (right, bottom), (0, 0, 255), cv2.FILLED)
        font = cv2.FONT_HERSHEY_DUPLEX
        cv2.putText(frame, name, (left + 6, bottom - 6), font, 0.5, (255, 255, 255), 1)

    # Write the resulting image to the output video file
    print("Processing frame {} / {}".format(frame_number, length))
    #output_movie.write(frame)
    cv2.imshow("frame", frame)
    if( cv2.waitKey(27) & 0xFF == ord('q')):
        break

# All done!
input_movie.release()
cv2.destroyAllWindows()

输出

In [1]: runfile('D:/project_new/facerec_from_video_file.py', wdir='D:/project_new')
Processing frame 1 / 3291
Processing frame 2 / 3291
Processing frame 3 / 3291
Processing frame 4 / 3291
Processing frame 5 / 3291
Processing frame 6 / 3291
Processing frame 7 / 3291
Processing frame 8 / 3291
Processing frame 9 / 3291
Processing frame 10 / 3291
Processing frame 11 / 3291
Processing frame 12 / 3291
Traceback (most recent call last):

  File "<ipython-input-1-4b2c69ca71f8>", line 1, in <module>
    runfile('D:/project_new/facerec_from_video_file.py', wdir='D:/project_new')

  File "C:\Users\saber\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 827, in runfile
    execfile(filename, namespace)

  File "C:\Users\saber\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 110, in execfile
    exec(compile(f.read(), filename, 'exec'), namespace)

  File "D:/project_new/facerec_from_video_file.py", line 81, in <module>
    recog(frame_number, known_faces, face_names)

  File "D:/project_new/facerec_from_video_file.py", line 35, in recog
    toenc.append((face_recognition.face_encodings(torec))[0])

IndexError: list index out of range

【问题讨论】:

  • 我们可能需要查看您定义face_recognition.face_encodings() 的位置。我很好奇它的回报是多少。
  • 这是face_recognition库中预定义的方法
  • 嗯...检查您的文档以获取 face_recognition.face_encodings()。我想知道如果没有匹配项,它是否返回一个空集合,因为您的代码似乎假定返回的集合 has 中的项目。

标签: python opencv face-recognition


【解决方案1】:

我不是百分百肯定这反映了你的情况,但我对 face_recognition 库的经验是它不能总是编码某些面孔。这通常发生在侧脸,或者如果他们的视角过于扭曲,或者即使有太多的头发遮住了脸。

个人,I would suggest adding an exception to handle this

encodings = face_recognition.face_encodings(known_image)
if len(encodings) > 0:
    biden_encoding = encodings[0]
else:
   print("No faces found in the image!")
   quit()

【讨论】:

    猜你喜欢
    • 2021-10-18
    • 2016-05-23
    • 2017-04-20
    • 2021-08-09
    • 2018-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-31
    相关资源
    最近更新 更多