如何检测物体是否静止OpenCV

How to detect if object is stationary OpenCV

我正在尝试在检测到的物体停止移动 5 秒时打印一条消息。

我可以检测人脸以及帧之间是否发生运动。当检测到人脸但未检测到动作 5 秒时,我可以使用什么方法组合这些并打印消息?

我一直在尝试使用类似于 time.time() 方法的方法,该方法在检测到人脸时每秒打印一次消息,但我无法完全弄清楚正确的逻辑来检查移动检测代码未触发。

import cv2 as cv
import time

# Open Webcam
cap = cv.VideoCapture(0)

# Define ret and size as frame info from webcam
# 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")

# Start Time
t1 = time.time()

# Do the following when webcam is open
while True:
    ret, frame = cap.read()
    ret, frame1 = cap.read()
    ret, frame2 = 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)
        t2 = time.time()
        if (t2 - t1) > 1:
            print('I SEE YOU IN 1')
            t1 = time.time() # reset start time
    
    for (x, y, w, h) in faces_rect2:
        cv.rectangle(ROI2, (x, y), (x+w,y+h), (0,255,0), thickness=2)
        t2 = time.time()
        if (t2 - t1) > 1:
            print('I SEE YOU IN 2')
            t1 = time.time() # reset start time
        
    for (x, y, w, h) in faces_rect3:
        cv.rectangle(ROI3, (x, y), (x+w,y+h), (0,255,0), thickness=2)
        t2 = time.time()
        if (t2 - t1) > 1:
            print('I SEE YOU IN 3')
            t1 = time.time() # reset start time
        
    for (x, y, w, h) in faces_rect4:
        cv.rectangle(ROI4, (x, y), (x+w,y+h), (0,255,0), thickness=2)
        t2 = time.time()
        if (t2 - t1) > 1:
            print('I SEE YOU IN 4')
            t1 = time.time() # reset start time
        
    # Show all video feeds
    cv.imshow('ROI1', ROI1)
    cv.imshow('ROI2', ROI2)
    cv.imshow('ROI3', ROI3)
    cv.imshow('ROI4', ROI4)

    # Detect Motion
    # Modify frames to detect contours
    diff = cv.absdiff(frame1, frame2)
    gray = cv.cvtColor(diff, cv.COLOR_BGR2GRAY)
    blur = cv.GaussianBlur(gray, (5,5), 0)
    _, thresh = cv.threshold(blur, 20, 255, cv.THRESH_BINARY)
    dilated = cv.dilate(thresh, None, iterations=3)
    # Find contours
    contours, _ = cv.findContours(dilated, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)

    # Draw rectangles around detected contours
    for contour in contours:
        (x, y, w, h) = cv.boundingRect(contour)
        if cv.contourArea(contour) < 1000:
            continue
        cv.rectangle(frame1, (x, y), (x+w, y+h), (0,255,0), thickness=2)
        cv.putText(frame1, 'Status: {}'.format('Movement'), (10,20), cv.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), thickness=3)
        
    # cv.drawContours(frame1, contours, -1, (0,255,0), thickness=2)

    # Show Motion Detected Feed
    cv.imshow('Motion Feed', frame1)
  
    # Press ESC to break
    c = cv.waitKey(1)
    if c == 27:
        break

cap.release()
cv.destroyAllWindows()

这就是我实现目标的方式:

# Draw rectangles around detected contours
    for contour in contours:
        (x, y, w, h) = cv.boundingRect(contour)
        if cv.contourArea(contour) < 1000:
            continue
        cv.rectangle(frame1, (x, y), (x+w, y+h), (0,255,0), thickness=2)
        cv.putText(frame1, 'Status: {}'.format('Movement'), (10,20), cv.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), thickness=3)
        t3 = time.time()

在运动检测代码中,我添加了t3来重置以后使用的定时器。

# 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()
        t4 = time.time()
        
        if msgcnt1 == []:
            print('I SEE YOU IN 1')
            msgcnt1.append('x')
        if (t4 - t3) > 5:
            print('No motion detected')
            t3 = time.time() # reset start time

t4 时间从检测到人脸开始。由于 t3 会在检测到运动时重新启动,因此如果 t4 - t3 达到 5 并打印消息,则检测到的面部被认为是静止的。