Ryan Ponsell
Ryan Ponsell

Reputation: 55

Print Message when face detected OpenCV

I want to print a message when a face is detected in my live video feed. I have been somewhat successful by tying the Print Message to the for loop that draws the rectangle around the detected face.

The problem that occurs now is that the message prints for every frame detected. I want the message to print once per second. When I try using time.sleep(1) in its current location, it makes the feed choppy, showing only 1 frame per second.

Where and how should I place the print message code so that the video feed and face detection are not affected?

import cv2 as cv
import numpy as np
import time

# Open Webcam
cap = cv.VideoCapture(0)

# Define ret and size as frame info from webcame
ret, size = cap.read()

# Define rows, cols, and '_' as the return from size.shape
# rows, cols, _ = size.shape

# Print results
# print('Rows', rows)
# print('Cols', cols)

# Face Detection haar_cascade
haar_cascade = cv.CascadeClassifier('haar_face.xml')

# Check if the webcam is opened correctly
if not cap.isOpened():
    raise IOError("Cannot open webcam")

# Do the following when webcam is open
while True:
    ret, frame = cap.read()
    frame = cv.resize(frame, None, fx=1, fy=1, interpolation=cv.INTER_AREA)

    # Divide Frame into Regions of Interest (ROI)
    ROI1 = frame[0:180, 0:320]
    ROI2 = frame[0:180, 320:640]
    ROI3 = frame[180:360, 0:320]
    ROI4 = frame[180:360, 320:640]

    # Detect faces in each ROI
    faces_rect1 = haar_cascade.detectMultiScale(ROI1, scaleFactor=1.1, minNeighbors=5)
    faces_rect2 = haar_cascade.detectMultiScale(ROI2, scaleFactor=1.1, minNeighbors=5)
    faces_rect3 = haar_cascade.detectMultiScale(ROI3, scaleFactor=1.1, minNeighbors=5)
    faces_rect4 = haar_cascade.detectMultiScale(ROI4, scaleFactor=1.1, minNeighbors=5)
    
    # Draw rectangles around detected faces
    for (x, y, w, h) in faces_rect1:
        cv.rectangle(ROI1, (x, y), (x+w,y+h), (0,255,0), thickness=2)
        print('I SEE YOU IN 1')
        time.sleep(1)

    for (x, y, w, h) in faces_rect2:
        cv.rectangle(ROI2, (x, y), (x+w,y+h), (0,255,0), thickness=2)
        print('I SEE YOU IN 2')
        time.sleep(1)

    for (x, y, w, h) in faces_rect3:
        cv.rectangle(ROI3, (x, y), (x+w,y+h), (0,255,0), thickness=2)
        print('I SEE YOU IN 3')
        time.sleep(1)

    for (x, y, w, h) in faces_rect4:
        cv.rectangle(ROI4, (x, y), (x+w,y+h), (0,255,0), thickness=2)
        print('I SEE YOU IN 4')
        time.sleep(1)

    # Show all video feeds
    cv.imshow('Feed', frame)
    cv.imshow('ROI1', ROI1)
    cv.imshow('ROI2', ROI2)
    cv.imshow('ROI3', ROI3)
    cv.imshow('ROI4', ROI4)
    
    # Press ESC to break
    c = cv.waitKey(1)
    if c == 27:
        break

cap.release()
cv.destroyAllWindows()

Upvotes: 0

Views: 368

Answers (1)

zardosht
zardosht

Reputation: 3591

Instead of stopping the thread, you can measure elapsed time and print the message when 1 second is elapsed.

For example for the first loop:

t1 = time.time()   # start time

while True:
    # ... 
    # ...
    # Draw rectangles around detected faces
    for (x, y, w, h) in faces_rect1:
        cv.rectangle(ROI1, (x, y), (x+w,y+h), (0,255,0), thickness=2)
        t2 = time.time()
        if (t2 - t1) > 1:
            print('I SEE YOU IN 1') 
            t1 = time.time()   # reset start time

Upvotes: 2

Related Questions