基于OpenCV与帧差法的动态物体检测实现

山间有风
山间有风
发布时间:2026-10-14 | 4人浏览过
原创

本文介绍利用OpenCV实现动态物体检测的方法。通过对比连续两帧图像的灰度差异,计算绝对值差并二值化,进而提取运动物体的轮廓。代码包含实时绘制外接矩形、显示时间戳及状态判断逻辑,并指出环境光线剧烈变化可能影响检测准确性的局限性。

动态物体检测原理概述

在超市监控场景中,当有物体经过时,屏幕边缘常会出现绿色边框进行标记,这种视觉效果十分直观。为了探究其实现原理,我们尝试使用OpenCV库来复现类似的动态物体检测功能。

本方案采用的核心思路是帧差法,即通过比较当前画面与上一帧画面的差异来识别动态物体。具体而言,程序会计算两帧图像之间的变化,并据此框选出发生运动的区域。此外,为了明确当前窗口内是否存在运动物体,我们需要引入状态判断机制。同时,为了方便后续回溯,程序会打印出检测发生时的具体时间信息。

当程序检测到移动物体时,会捕捉其轮廓并添加一个外接矩形框,同时返回该矩形的左上角坐标(x, y)。如果未返回有效坐标,则表明当前没有物体运动。通过获取这些坐标值,我们可以判断是否有物体在移动,并同步打印出当时的本地时间,以便定位事件发生时刻。

OpenCV实现代码详解

以下是实现该功能的完整源代码:


import cv2
import time
import numpy as np

def videos():
    cap = cv2.VideoCapture(1)
    #不设置是默认640*480,我们这里设置出来
    cap.set(3, 640)
    cap.set(4, 480)

    img_num = 0
    k = np.ones((3, 3), np.uint8)

    while True:
        success, img = cap.read()
        localtime = time.asctime(time.localtime(time.time()))

        if not img_num:
            # 这里是由于第一帧图片没有前一帧
            previous = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        gray_diff = cv2.absdiff(gray, previous)  # 计算绝对值差
        # previous 是上一帧图片的灰度图

        thresh = cv2.threshold(gray_diff, 40, 255, cv2.THRESH_BINARY)[1]
        mask = cv2.medianBlur(thresh, 3)

        close = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, k)

        cnts = cv2.findContours(close,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)[0]
        for c in cnts:
            area = cv2.contourArea(c)
            if area > 50:
                x, y, w, h = cv2.boundingRect(c)
                cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)

                if x>0:
                    print("动",localtime)

        cv2.putText(img, localtime, (30, 30), cv2.FONT_HERSHEY_COMPLEX, 0.7, (0, 0, 255), 2)
        cv2.imshow("x", close)
        cv2.imshow("Result", img)
        img_num += 1

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

videos()

静态画面示例:


动态画面示例:

当有物体经过监控窗口时,控制台会打印出对应的时间戳。这一功能使得我们在事后查看录制的视频时,能够快速定位到动态事件发生的片段。


 

时间戳显示与注意事项

为了提升可视化的便利性,我在视频窗口的左上角添加了实时显示的时间和日期信息。

**注意!** 必须将以下代码行: localtime = time.asctime(time.localtime(time.time())) 放置在主循环内部。如果仅在主循环外调用,它只会返回程序启动瞬间的本地时间,导致后续时间显示不更新。此外,不应使用time.sleep()来控制时间变化或帧率,因为这会严重干扰视频的正常播放帧率。

方法局限性与改进方向

该方法存在一个明显的局限性:当环境光线发生剧烈变化时,计算出的轮廓会出现异常波动,导致程序误判整个屏幕都在运动。针对这一光照敏感性问题的改进,仍有待进一步优化。

至此,关于使用OpenCV检测动态物体的实现方案已介绍完毕。如需了解更多相关技术细节,建议搜索本站往期文章或继续浏览后续内容。感谢大家的支持!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表