0

I have a code for a face detector, and here is how it works:

If the face detector doesn't detect a face (doesn't return a value), it will simply print a word, for instance "Hello World".

But what I need is that if the face detector doesn't detect a face (doesn't return a value) for longer than 3 seconds, then it would print the word. So I don't want it to print the word immediately after not detecting a face (no value has been returned).

I've tried doing a time.sleep(3) but that basically delays the whole code.

# "detector" is a library used for the face detecting.
faces = detector(gray)

# If it doesn't detect a face, it will print a word.
if not faces:
    print("Hello World")

# A for-loop that prints the coordinates of the face.
for face in faces:
    x, y = face.left(), face.top()
    x1, y1 = face.right(), face.bottom()
    rectangle = cv2.rectangle(frame, (x, y), (x1, y1), (0, 255, 0), 2)
    print(rectangle)
Shackman
  • 51
  • 9
  • If you don't want to delay the code for three seconds, then what do you want to do? Check `faces` multiple times during the 3 seconds? – walnut Sep 02 '19 at 16:24
  • 1
    @uneven_mark I don't want to delay the whole code. What I want is that if there was no face detected for more than 3 seconds, then a word will be printed. But if a face was detected under 3 seconds, the word should not be printed. – Shackman Sep 02 '19 at 16:28
  • @programing_nerd Yes, but what does `detected during 3 seconds` mean here? Does `detector` give you the faces detected at the time point of the call or the faces since the last call? Or does it call a callback when a face is detected? – walnut Sep 02 '19 at 16:31
  • 1
    @uneven_mark "detected under 3 seconds" means that I get a value returned under 3 seconds instead of nothing/NULL. – Shackman Sep 02 '19 at 16:39
  • @programing_nerd What does `detector(gray)` return, *exactly*? – walnut Sep 02 '19 at 16:43
  • likely an object that has the coordinates of face / faces @uneven_mark – Axiumin_ Sep 02 '19 at 16:49
  • You want it to *time-out* after 3 seconds if it doesn't return something? – wwii Sep 02 '19 at 16:50
  • @uneven_mark Exactly what Axium said. – Shackman Sep 02 '19 at 16:51
  • 1
    @Axium Sure, but does it block? Does it return the currently visibible faces only, or does it collect them between calls? The answer changes depending on these questions. In particular if it is non-blocking, only showing current faces, OP needs to determine a sampling rate appropriate for the problem. – walnut Sep 02 '19 at 16:53
  • @wwii No, I want it to print the word if no value was returned in under 3 seconds. – Shackman Sep 02 '19 at 16:53
  • Is [Timeout on a function call](https://stackoverflow.com/questions/492519/timeout-on-a-function-call) similar? – wwii Sep 02 '19 at 16:55
  • @uneven It doesn't block, and yes, it returns all the visible faces. By the way, I am not using it on pictures, but I am using the web cam on my laptop, therefore a value sometimes could be NULL. – Shackman Sep 02 '19 at 16:57
  • @wwii Not really... but thanks. – Shackman Sep 02 '19 at 17:04

2 Answers2

0

Going from the comments, I assume you want something like this:

sample_period = 1/30     # 30 frames per second

faces = None
end_time = time.time() + 3

while time.time() < end_time:
    faces = detector()
    if faces:
        break
    time.sleep(sample_period)

if faces:
    # Found a face!
else:
    # Times up!

It is not completely exact, but should be ok on your time scales. You need to determine the value that you think is appropiate for sample_period.

walnut
  • 21,629
  • 4
  • 23
  • 59
0

First, import the time module (unless you already have). This will help us check the time. Next, create a variable called last_time_detected = time.time(). Add a 'else' statement to your if not faces: statement and add this line: last_time_detected = time.time(). That would look like this:

else:
    last_time_detected = time.time()

This variable indicates the last time a face has been detected, as suggested by the name. After that, in your if not faces: statement, add this to check if it has reached more than 3 seconds:

if((time.time - last_time_detected) > 3):
    #do whatever you want
    print("Hello World")

In summary, what this does is it resets the "timer" every time a face is detected (starts off with the current time just in case a face is never detected). If the time between now and last_time_detected is over 3 seconds, then we run the statement.

The code should essentially become this:

# "detector" is a library used for the face detecting.
faces = detector(gray)
last_time_detected = time.time()

# If it doesn't detect a face, it will print a word.
if not faces:
    print("Hello World")
    if((time.time() - last_time_detected) > 3):
        #do whatever you want
        print("Hello World")
else:
    last_time_detected = time.time()

# A for-loop that prints the coordinates of the face.
for face in faces:
    x, y = face.left(), face.top()
    x1, y1 = face.right(), face.bottom()
    rectangle = cv2.rectangle(frame, (x, y), (x1, y1), (0, 255, 0), 2)
    print(rectangle)
Axiumin_
  • 2,107
  • 2
  • 15
  • 24
  • Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackoverflow.com/rooms/198910/discussion-on-answer-by-axium-how-can-i-set-a-timer-for-a-command). – Samuel Liew Sep 04 '19 at 00:28