python+opencv实现移动侦测(帧差法)

  • Post category:Python

下面是详细讲解“Python+OpenCV实现移动侦测(帧差法)”的完整攻略。

1. 什么是移动侦测

移动侦测是指通过对视频或像序列进行分析,检测出其中的运动目标。在视频监控、智能交通等领域中,移动侦测是一项重要的技术。

2. 帧差法原理

帧差法是一种简单有效的移动侦测算法,其原理是通过比较相邻帧之间的像素值差异,来检测出运动目标。具体实现过程如下:

  1. 读取视频帧。
  2. 将当前帧与前一帧进行差分,得到差分图像。
  3. 对差分图像进行二值化处理,得到前景掩模。
  4. 对前景掩模进行形态学操作,去除噪声和小的区域。
  5. 在前景掩模中检测出运动目标的轮廓。

3. 实现移动侦测

以下是用Python+OpenCV实现移动侦测的步骤。

3.1 导入库

import cv2
import numpy as np

3.2 读取视频

cap = cv2.VideoCapture('test.mp4')

3.3 初始化变量

ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (21, 21), 0)
background = gray

3.4 实现帧差法

while True:
    ret, frame = cap.read()
    if not ret:
        break
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (21, 21), 0)
    diff = cv2.absdiff(background, gray)
    thresh = cv2.threshold(diff, 25, 255, cv2.THRESH_BINARY)[1]
    thresh = cv2.dilate(thresh, None, iterations=2)
    contours, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    for contour in contours:
        if cv2.contourArea(contour) < 1000:
            continue
        (x, y, w, h) = cv2.boundingRect(contour)
        cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
    cv2.imshow('frame', frame)
    key = cv2.waitKey(1) & 0xFF
    if key == ord('q'):
        break
    if key == ord('r'):
        background = gray
cap.release()
cv2.destroyAllWindows()

4. 示例说明

以下是两个示例说明,分别是使用帧差法实现移动侦测和使用帧差法实现移动侦测并保存检测结果。

4.1 使用帧差法实现移动侦测

以下是一个使用帧差法实现移动侦测的示例。

import cv2
import numpy as np

cap = cv2.VideoCapture('test.mp4')

ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (21, 21), 0)
background = gray

while True:
    ret, frame = cap.read()
    if not ret:
        break
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (21, 21), 0)
    diff = cv2.absdiff(background, gray)
    thresh = cv2.threshold(diff, 25, 255, cv2.THRESH_BINARY)[1]
    thresh = cv2.dilate(thresh, None, iterations=2)
    contours, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    for contour in contours:
        if cv2.contourArea(contour) < 1000:
            continue
        (x, y, w, h) = cv2.boundingRect(contour)
        cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
    cv2.imshow('frame', frame)
    key = cv2.waitKey(1) & 0xFF
    if key == ord('q'):
        break
    if key == ord('r'):
        background = gray

cap.release()
cv2.destroyAllWindows()

4.2 使用帧差法实现移动侦测并保存检测结果

以下是一个使用帧差法实现移动侦测并保存检测结果的示例。

import cv2
import numpy as np

cap = cv2.VideoCapture('test.mp4')

ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (21, 21), 0)
background = gray

fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi', fourcc, 20.0, (640, 480))

while True:
    ret, frame = cap.read()
    if not ret:
        break
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (21, 21), 0)
    diff = cv2.absdiff(background, gray)
    thresh = cv2.threshold(diff, 25, 255, cv2.THRESH_BINARY)[1]
    thresh = cv2.dilate(thresh, None, iterations=2)
    contours, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    for contour in contours:
        if cv2.contourArea(contour) < 1000:
            continue
        (x, y, w, h) = cv2.boundingRect(contour)
        cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
    out.write(frame)
    cv2.imshow('frame', frame)
    key = cv2.waitKey(1) & 0xFF
    if key == ord('q'):
        break
    if key == ord('r'):
        background = gray

cap.release()
out.release()
cv2.destroyAllWindows()

5. 总结

帧差法是一种简单有效的移动侦测算法,可以用Python+Open实现。本教程介绍了帧差法的原理和实现步骤,并提供了相应的示例。其中,示例一是使用帧差法实现移动侦测,示例二是使用帧差法实现移动侦测并保存检测结果。