samkhan13
samkhan13

Reputation: 3385

python, opencv: duration of time an object is detected on webcam

i am able to track an object in each frame returned by my webcam. i want to note when the object was detected for the first time and the duration till it was continuously detected thereafter. the webcam is on for an indefinite period i.e. till it is closed by user input.

since the set of code for detecting the object is within a while loop that is needed to read the next frame from cv2.VideoCapture() i am not able to come up with an efficient, pythonic way for doing what i want.

right now i am appending a list with the tuple (timestamp,flag) for each frame. timestamp is the value from python's time.time() and flag is a boolean to indicate if the object is detected. i then sum up all values of timestamp where flag is 'Yes'. but this doesn't quite give me what i want. can you suggest a more appropriate way?

*i wish there was a generic function in opencv like cv2.detectionDuration() :P

--EDIT--

Here is a code for tracking frontal face:

import cv2
import time

faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_alt.xml')
capture = cv2.VideoCapture(0)
keyPressed = -1
faceFound = []

print 'press esc to quit'

while(keyPressed != 27):
    ret, camImage = capture.read()
    cv2.imshow('camImage', camImage)

    try:
        faceRegion = faceCascade.detectMultiScale(camImage)
        timestamp = time.time()
        flag = 1
        faceFound.append((timestamp,flag)) 
    except TypeError:
        timestamp = time.time()
        flag = 0
        faceFound.append((timestamp,flag))
        print 'check if front face is visible to camera'
        pass

    keyPressed = cv2.waitKey(1)
cv2.destroyAllWindows()

timeDelta = 0
for tup in faceFound:
    if tup[1] == 1:
        timeDelta += tup[0]
print timeDelta

also, could you help me obtain a better format for timeDelta so that it can be displayed as day:hour:min:sec:microsec. is there a better alternative to time.time() for my current requirements?

Upvotes: 3

Views: 5937

Answers (2)

S Andrew
S Andrew

Reputation: 7268

What you are trying to do is known as dwell time in which we calculate the time of the detected object inside the frame. In order to achieve this you need have some kind of tracking inside you inferencing. Basically the tracker will assign an object id to your detected object and then that object id remains same till the object is detected. Based on that object id you can start a timer and keep on counting it until the object is detected. In opencv you can go with CentroidTracking algorithm

Have a look at this video, this might give you basic idea: https://www.youtube.com/watch?v=JbNeFMKXybw&list=PLWw98q-Xe7iH8UHARl8RGk8MRj1raY4Eh&index=7

Upvotes: 2

aliep
aliep

Reputation: 1802

[time_first, time_last, got_first] 

if got_first is false and face is detected, you assign time_first to now() and got_first to true.

when the face is not detected, you assign time_last to now() and got_first to false.

import cv2
import time

faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_alt.xml')
capture = cv2.VideoCapture(0)
keyPressed = -1
faceFound = []
ts = [0,0,False]

print 'press esc to quit'

while(keyPressed != 27):
    ret, camImage = capture.read()
    cv2.imshow('camImage', camImage)

    try:
        faceRegion = faceCascade.detectMultiScale(camImage)
        if ts[2] == False:
            ts[0] = time.time()
            ts[2] = True
    except TypeError:
        if ts[2] == True:
            ts[1] = time.time()
            ts[2] = False
            faceFound.append([ts[0], ts[1]])
        print 'check if front face is visible to camera'
        pass

    keyPressed = cv2.waitKey(1)
cv2.destroyAllWindows()

for list in faceFound:
    print list[1] - list[0]

although I think there's a problem with your code, cause no face gets detected. you can print faceRegion and see that, it's an empty tuple.

Upvotes: 3

Related Questions