Search code examples
pythonpython-3.xopencvface-detection

OpenCV face presence/absence periods of time


There is a code that detects faces in video file while displaying it frame by frame:

cap = cv2.VideoCapture(videoPath)
faceCascade = cv2.CascadeClassifier(cascPath)

while (cap.isOpened()):
    # Capture frame-by-frame
    ret, frame = cap.read()
    # Our operations on the frame come here
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    faces = faceCascade.detectMultiScale(
        gray,
        scaleFactor=1.1,
        minNeighbors=5,
        minSize=(30, 30),
        flags=cv2.CASCADE_SCALE_IMAGE
    )

    # Draw a rectangle around the faces
    for (x, y, w, h) in faces:
        cv2.rectangle(frame, (x, y), (x+w, y+h), (233, 153, 22), 2)

    # Display the resulting frame
    cv2.imshow('frame', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()

I need a code that can give you periods of time when a face is detected and periods of time when a face is not detected. Can somebody help me with that? At least some tips how to solve this problem, where to look etc..


Solution

  • Keep track of the timestamp of current frame, previous frame, and the starting frame of the current sequence containing faces.

    Once you no longer detect a face in a frame, append a pair (starting, previous) to a list.

    import time
    
    # ....
    
    def get_timestamp():
        # Make the timestamp whatever you want...
        return time.strftime("%Y%m%d-%H%M%S")
    
    # ....
    
    face_present = []
    ts_start = None
    ts_prev = None
    
    # ....
    
    while (cap.isOpened()):
        ret, frame = cap.read()
        ts = get_timestamp()
    
        # ....
    
        if len(faces) > 0: # Some faces detected
            if ts_start is None: # This is the start of current sequence
                ts_start = ts
        elif (ts_start is not None) and (ts_prev is not None):
            # First frame without face following a sequence with face...
            face_present.append((ts_start, ts_prev))
            ts_start = None
    
        ts_prev = ts
    

    You could make the timestamp whatever you want, could even be a frame number if that's what you're after.

    Same approach can be used to determine the times when face is not present, you only need to change the condition of the first if statement.