Ritesh
Ritesh

Reputation: 29

How to build a face detection program using opencv and start a timer to record the time as long as face stays on the screen?

I want to build a face detection python OpenCV program which starts a timer as soon as a face is detected. If the face is removed in front of the webcam, timer sets to 0 and it restarts once a new face is detected.

Till now what I have tried.

import numpy as np
import cv2
import time

face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml')

cap = cv2.VideoCapture(0)

start = "y"
timeLoop = True

while 1:
    ret, img = cap.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray, 1.3, 5)

    for (x,y,w,h) in faces:
        cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
        roi_gray = gray[y:y+h, x:x+w]
        roi_color = img[y:y+h, x:x+w]

        cv2.putText(img, "Number of faces detected: " + str(faces.shape[0]), (0,img.shape[0] -10), cv2.FONT_HERSHEY_TRIPLEX, 0.5,  (0,0,255), 1)

        eyes = eye_cascade.detectMultiScale(roi_gray)
        for (ex,ey,ew,eh) in eyes:
            cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)

    # Variables to keep track and display
    Sec = 0
    Min = 0        
    # Begin Process
    cv2.imshow('img',img)
    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break

    if len(faces) > 0:  
        timeLoop = start  
        while timeLoop:
            Sec += 1
            print(str(Min) + " Mins " + str(Sec) + " Sec ")
            #cv2.putText(img, "Time: " + str(Min) + " Mins " + str(Sec) + " Sec ", (0,img.shape[0] -10), cv2.FONT_HERSHEY_TRIPLEX, 0.5,  (0,0,255), 1)
            time.sleep(1)
            if Sec == 60:
                Sec = 0
                Min += 1
                print(str(Min) + " Minute")

cap.release()
cv2.destroyAllWindows()

This program works for face detection and timer. But once the timer starts, the face detection module get stuck in the loop and doesn't move forward. But the timer works in the background.

How to fix this?

Upvotes: 0

Views: 932

Answers (1)

Jeru Luke
Jeru Luke

Reputation: 21233

I guess you will like this when it works. There were just some minor issues with the loops and placement of the time function.

In your case, you placed a second while loop to initiated the timer. Hence the code kept looping in there. That is why (as @api55 mentioned) the timer was NOT running in the background. Rather upon detection of a face it started a loop and kept counting seconds.

Here is the code:

import numpy as np
import cv2
import time

path = '/Desktop/Stack/face_detection/'

face_cascade = cv2.CascadeClassifier(path + 'haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier(path + 'haarcascade_eye.xml')

cap = cv2.VideoCapture(0)

Sec = 0
Min = 0 

while 1:
    ret, img = cap.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray, 1.3, 5)

    for (x,y,w,h) in faces:
        cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
        roi_gray = gray[y:y+h, x:x+w]
        roi_color = img[y:y+h, x:x+w]

        eyes = eye_cascade.detectMultiScale(roi_gray)
        for (ex,ey,ew,eh) in eyes:
            cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)     

    if len(faces) > 0:  

        Sec += 1
        print(str(Min) + " Mins " + str(Sec) + " Sec ")

        cv2.putText(img, "Time: " + str(Min) + " Mins " + str(Sec) + " Sec ", (0,img.shape[0] -30), cv2.FONT_HERSHEY_TRIPLEX, 0.5,  (0,0,255), 1)
        cv2.putText(img, "Number of faces detected: " + str(faces.shape[0]), (0,img.shape[0] -10), cv2.FONT_HERSHEY_TRIPLEX, 0.5,  (0,0,255), 1)    

        time.sleep(1)
        if Sec == 60:
            Sec = 0
            Min += 1
            print(str(Min) + " Minute")                

    if len(faces) == 0:

        print('No face detected')
        cv2.putText(img, "No face detected ", (0,img.shape[0] -10), cv2.FONT_HERSHEY_TRIPLEX, 0.5,  (0,0,255), 1)        
        Sec = 0
        Min = 0

    cv2.imshow('img',img)
    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break    

cap.release()
cv2.destroyAllWindows()

Hope this is what you expected !!

Upvotes: 1

Related Questions