user7179815
user7179815

Reputation:

how to speed up video capture from webcam in opencv?

I need real time video capture i've tried reducing resolution, setting a static fps and none worked why am i getting a slow video feed although it says my fps is 30 i don't really know where exactly is the problem it's really diving me mad.

Code:

import cv2
import os
import face_recognition
import pickle
from cv2.cv2 import CAP_DSHOW

known_faces_dir = "known_faces"
video = cv2.VideoCapture(0)

accuracy = 0.6
frame_thikness = 3
font_size = 2
MODEL = "cnn"

print("loading  known faces")
known_faces = []
known_names = []
unknown_faces = []
for name in os.listdir(known_faces_dir):
    for filename in os.listdir(f"{known_faces_dir}/{name}"):
        image = face_recognition.load_image_file(f"{known_faces_dir}/{name}/{filename}")
        encodings = face_recognition.face_encodings(image)[0]
        # encodings = pickle.load(open(f"{name}/{filename}","rb"))
        known_faces.append(encodings)
        known_names.append(name)

print("treating unknow faces")
while True :

    # print(filename)
    # image = face_recognition.load_image_file(f"{unknown_faces_dir}/{filename}")
    ret, image = video.read()
    print(video.get(cv2.CAP_PROP_FPS))

    locations = face_recognition.face_locations(image, model=MODEL)
    encodings = face_recognition.face_encodings(image, locations)
    # image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
    for face_location, face_encodings in zip(locations, encodings):
        results = face_recognition.compare_faces(known_faces, face_encodings, tolerance=0.54)
        if True in results:
            match = known_names[results.index(True)]
            print("Face Found" f"{match}")

            top_l = (face_location[3], face_location[0])
            bottom_r = (face_location[1], face_location[2])
            color = [0, 255, 0]
            cv2.rectangle(image, top_l, bottom_r, color, frame_thikness)

            top_l = (face_location[3], face_location[2])
            bottom_r = (face_location[1], face_location[2] + 22)
            cv2.rectangle(image, top_l, bottom_r, color, cv2.FILLED)
            cv2.putText(image, str(match), (face_location[3]+10, face_location[2]+15), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (200, 200, 200), 2)

    cv2.imshow("", image)
    if cv2.waitKey(1)&0xFF == ord("e"):
        break

    # cv2.waitKey(10200)
video.release()
cv2.destroyWindow(filename)

Upvotes: 0

Views: 1497

Answers (2)

Xander
Xander

Reputation: 428

It is highly likely that the inferencing of your model is taking more than 33ms (1000ms / 30 FPS) and thus limiting your FPS. Try to remove your face recognition model from the loop and see if it still is slow.

If that solves your problem, your CPU or GPU is the limiting factor depending on how you run the model.

Upvotes: 0

Mario Abbruscato
Mario Abbruscato

Reputation: 819

Try this and look at elapsed time to compute fps. Then add other process.
Work with gray images from the beginning is a good idea. if faces images are in color save it in gray and use only gray images. Avoid the process repeats same things if not necessary.

import numpy as np
import cv2
import time 

cap = cv2.VideoCapture(0)

start_time = time.time()
end_time = start_time
elapsed_time = 0

font = cv2.FONT_HERSHEY_SIMPLEX
  
org = (50, 50)
fontScale = 1  
color = (255, 0, 0)
thickness = 2
   
while(True):

    start_time = time.time()
    
    # Capture frame-by-frame
    ret, frame = cap.read()

    # Our operations on the frame come here
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    # Display the resulting frame

    cv2.putText(gray, str(1 / elapsed_time) + "fps", org, font, 
                   fontScale, color, thickness, cv2.LINE_AA)
    
    cv2.imshow('frame',gray)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

    end_time = time.time()
    elapsed_time = end_time - start_time


# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()

Upvotes: 1

Related Questions