Ask Your Question
0

Face detection and time - video

asked 2020-04-03 10:16:34 -0600

NikosOpenCV gravatar image

updated 2020-11-28 16:32:44 -0600

crackwitz gravatar image

I have an issue with time and face detection. When I 'am inside for loop ,the time sticks a little bit.Code:

import cv2
from datetime import datetime

cap = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc(*'XVID')  
out = cv2.VideoWriter('face_detection.avi' , fourcc , 10.0 , (640 , 480))

while True:
    ret,frame = cap.read()
    font = cv2.FONT_HERSHEY_SIMPLEX
    date_time = str(datetime.today().strftime("%d-%m-%Y")) + '                ' + str(datetime.now().strftime("%H:%M:%S"))  # show date and time
    video = cv2.putText(frame,date_time,(30,400),font,1,(0,0,255),2,cv2.LINE_AA)
    faces = cv2.CascadeClassifier('haarcascade_frontalface_default.xml').detectMultiScale(frame, 1.1, 4)
    for(x,y,w,h) in faces:
        cv2.rectangle(frame , (x,y) , (x+w , y+h) , (255,0,0) , 3)

    cv2.imshow('Face Detection' , frame)
    out.write(frame)

    if(cv2.waitKey(1) == ord('q')):
        break
cap.release()
out.release()
cv2.destroyAllWindows()
edit retag flag offensive close merge delete

Comments

1

cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

this has to go before the loop. please do not reload a ~1mb xml file per frame (and then throw it away !)

berak gravatar imageberak ( 2020-04-03 10:43:51 -0600 )edit

Still doesn't work... seconds passes faster than normal... I tested many times. Why is this happening?(maybe of the for-loop inside while-loop??)

NikosOpenCV gravatar imageNikosOpenCV ( 2020-04-03 13:36:41 -0600 )edit

Here is tutorial link: Detect face

supra56 gravatar imagesupra56 ( 2020-04-03 21:05:33 -0600 )edit

My problem is the time ,not detection The seconds passes faster than normal(maybe because of the for-loop inside while loop) Does anyone knows how to fix it?

NikosOpenCV gravatar imageNikosOpenCV ( 2020-04-04 17:23:50 -0600 )edit

sorry, but it's unclear what you mean now

berak gravatar imageberak ( 2020-04-05 03:04:28 -0600 )edit

2 answers

Sort by ยป oldest newest most voted
-1

answered 2020-04-05 11:32:37 -0600

supra56 gravatar image
Code:
#!/usr/bin/env python37
#Raspberry pi 3B/3B+, 4B, Buster, OpenCV 4.2.0
#Date: 5th Apriol, 2020

import numpy as np
import cv2
from datetime import datetime

face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
fourcc = cv2.VideoWriter_fourcc(*'XVID')  
out = cv2.VideoWriter('face_detection.avi', fourcc, 10.0, (640, 480))
font = cv2.FONT_HERSHEY_SIMPLEX

cap = cv2.VideoCapture(0)

while cap.isOpened():
    date_time = str(datetime.today().strftime("%d-%m-%Y")
                    + '                '
                    + str(datetime.now().strftime("%H:%M:%S")))

    ret, frame = cap.read()
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray, 1.3, 5)
    for (x,y,w,h) in faces:
        cv2.rectangle(frame, (x, y),(x+w, y+h),(255, 0, 0), 2)

    out.write(frame)
    cv2.putText(frame, date_time, (30, 400), font, 1,
                (0, 0, 255), 2, cv2.LINE_AA)

    cv2.imshow('img', frame)
    k = cv2.waitKey(1)  
    if k is 27:
        break

cap.release()
cv2.destroyAllWindows()

In line 32, I change == to is operator for python 3.7 or later. You may used == if its doesn't work.

edit flag offensive delete link more

Comments

I noticed that you declared video ...video = cv2.putText.

supra56 gravatar imagesupra56 ( 2020-04-05 11:35:20 -0600 )edit

comparing numbers with the "is" operator is not recommended. the "is" operator tests identity, which is useful for objects and testing None. for testing equality of numbers, "==" is the correct operator.

crackwitz gravatar imagecrackwitz ( 2020-11-28 15:12:41 -0600 )edit
-1

answered 2020-11-28 15:00:08 -0600

crackwitz gravatar image

updated 2020-11-28 15:03:22 -0600

the video plays faster than realtime because that's a useful behavior to rapidly work through data.

if you want it to "play" at 1x speed, you'll need to insert some waiting. you can pass such a delay to waitKey() in milliseconds.

you could simply pass in 1000 / cap.get(cv.CAP_PROP_FPS) but that won't account for processing time and your video will play slower than realtime.

that's why you should do the following:

# ... open capture...
tstart = time.perf_counter() # in seconds
# ... loop starts...
    pts = cap.get(cv.CAP_PROP_POS_MSEC) # in milliseconds
    # ... cap.read()...
    # ... your processing and imshow()...
    time_left = pts - 1000 * (time.perf_counter() - tstart) # in milliseconds
    cv.waitKey(int(max(1, time_left)))

that is also not perfect. waitKey will return sooner if you press a key, which makes the video play faster. it will maintain the correct pace though. how it works: the 'pts' is the presentation timestamp of the frame you are reading. after all processing for the frame is done, we calculate how much time has elapsed, and how much is left before this frame is due for presentation. we then give that time remaining to waitKey()

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2020-04-03 10:16:34 -0600

Seen: 807 times

Last updated: Nov 28 '20