首页 > 解决方案 > Python opencv人脸识别视频不流畅

问题描述

我使用 python opencv 创建人脸识别。问题是视频不流畅。它总是混蛋。因此,我使用if count%(10*fps)在 10 帧后获取人脸识别过程图像,而不是处理每一帧。它使视频更流畅,但不会在图像中显示矩形和文本。如何解决?

KNOWN_FACES_DIR = 'known_faces'
TOLERANCE = 0.5
FRAME_THICKNESS = 3
FONT_THICKNESS = 2
MODEL = 'hog'  # default: 'hog', other one can be 'cnn' - CUDA accelerated (if available) deep-learning pretrained model

video = cv2.VideoCapture(0)
fps = int(video.get(cv2.CAP_PROP_FPS))

print('Loading known faces...')
known_faces = []
known_names = []

for name in os.listdir(KNOWN_FACES_DIR):

    for filename in os.listdir(f'{KNOWN_FACES_DIR}/{name}'):

        # Load an image
        image = face_recognition.load_image_file(f'{KNOWN_FACES_DIR}/{name}/{filename}')
        encoding = face_recognition.face_encodings(image)[0]

        # Append encodings and name
        known_faces.append(encoding)
        known_names.append(name)
        

def check_face(known_faces, known_names):
    
    count = 0
    
    while True:
        
        ret, image = video.read()
        
        if count%(10*fps) == 0:       ########## Process after 10 frame ################
            locations = face_recognition.face_locations(image, model=MODEL)
            encodings = face_recognition.face_encodings(image, locations)
        
            for face_encoding, face_location in zip(encodings, locations):
        
                results = face_recognition.compare_faces(known_faces, face_encoding, TOLERANCE)
                match = None
                
                if True in results:  # If at least one is true, get a name of first of found labels
                    match = known_names[results.index(True)]
                    print(f"Match found: {match}")
        
                    # Each location contains positions in order: top, right, bottom, left
                    top_left = (face_location[3], face_location[0])
                    bottom_right = (face_location[1], face_location[2])
            
                    # Get color by name using our fancy function
                    color = [0,255,0]
            
                    # Paint frame
                    cv2.rectangle(image, top_left, bottom_right, color, FRAME_THICKNESS)
            
                    # Now we need smaller, filled grame below for a name
                    # This time we use bottom in both corners - to start from bottom and move 50 pixels down
                    top_left = (face_location[3], face_location[2])
                    bottom_right = (face_location[1], face_location[2] + 22)
            
                    # Paint frame
                    cv2.rectangle(image, top_left, bottom_right, color, cv2.FILLED)
            
                    # Wite a name
                    cv2.putText(image, match, (face_location[3] + 10, face_location[2] + 15), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (200, 200, 200), FONT_THICKNESS)
    
        count+=1                    
    
        
        # Show image
        cv2.imshow("", image)
        if cv2.waitKey(1) & 0xFF == ord("q"):
            cv2.destroyAllWindows()
            break


check_face(known_faces, known_names)

标签: pythonopencv

解决方案


您需要制作 2 个线程:

  1. 首先使用边界框和文本快速显示和更新您的图像
  2. 第二个线程更新神经网络的结果并放入第一个线程

作为示例,您可以使用此代码并将此处用于检测的部分放入 th2

import cv2
import threading
import time

cap = cv2.VideoCapture(0)


ret, frame = cap.read()
exit = False
top_lef=(0,0)
bottom_right=(0,0)

def th1():
    global ret, frame, exit,top_lef,bottom_right

    while True:
        ret, frame = cap.read()
    ## here put code to show image and rectangle
    
    cv2.rectangle(frame, top_left, bottom_right, color, cv2.FILLED)
        cv2.imshow('frame', frame)
        cv2.waitKey(30)

        if exit:
            break

def th2():
    global ret, frame, exit,top_lef,bottom_right
    while True:
    
    ### put here the code to make face recogition


    #top_left, bottom_right =  face prediction result
    
        if cv2.getWindowProperty('frame',cv2.WND_PROP_VISIBLE) < 1:
            exit = True
            break

t1 = threading.Thread(target=th1)
t1.start()
t2 = threading.Thread(target=th2)
t2.start()

推荐阅读