You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenCV+Python视频ROI运动追踪报absdiff尺寸不匹配错误

问题根因

你遇到的尺寸不匹配错误根源是帧更新逻辑存在漏洞:

  • 你仅在进入检测循环前,对初始获取的两帧做了ROI区域裁剪
  • 循环运行时,末尾执行frame1 = frame2后,通过cap.read()新读取的frame2是摄像头输出的完整全尺寸帧,没有做对应ROI裁剪
  • 下一轮循环调用cv2.absdiff()时,传入的一个是裁剪后的小尺寸ROI帧,一个是全尺寸原始帧,两者尺寸、通道数不匹配,直接触发OpenCV的运算报错。

额外隐藏风险:现有代码没有判断cap.read()的读帧返回状态,如果摄像头临时断连、读帧失败返回None,后续的裁剪、运算操作也会直接抛出异常。

修复方法

每次读取新的摄像头帧后,都按照选定的ROI坐标做相同规则的裁剪,同时增加读帧有效性判断即可。
修复后的可运行代码如下:

import cv2 

cap = cv2.VideoCapture(0)

# 读取初始两帧
ret, frame1 = cap.read()
if not ret:
    raise RuntimeError("无法读取摄像头帧,请检查设备连接")
ret, frame2 = cap.read()
if not ret:
    raise RuntimeError("无法读取摄像头帧,请检查设备连接")

# 选定ROI区域
r = cv2.selectROI(frame1)
x, y, w, h = int(r[0]), int(r[1]), int(r[2]), int(r[3])
# 对初始两帧做ROI裁剪
frame1 = frame1[y:y+h, x:x+w]
frame2 = frame2[y:y+h, x:x+w]

while cap.isOpened():
    # 帧差运算
    diff = cv2.absdiff(frame1, frame2)
    gray = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY)
    blur = cv2.GaussianBlur(gray, (5, 5), 0)
    _, thresh = cv2.threshold(blur, 20, 255, cv2.THRESH_BINARY)
    dilated = cv2.dilate(thresh, None, iterations=3)
    contours, _ = cv2.findContours(dilated, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

    for contour in contours:
        (cx, cy, cw, ch) = cv2.boundingRect(contour)
        if cv2.contourArea(contour) < 1000:
            continue
        cv2.rectangle(frame1, (cx, cy), (cx+cw, cy+ch), (0, 255, 0), 2)
        cv2.putText(frame1, "Status: {}".format("Motion detected!"), (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 3, cv2.LINE_AA)
        print('Motion Detection. Object area - ', cv2.contourArea(contour))
    
    cv2.imshow("ROI Motion Detection", frame1)
    
    # 更新帧:新读的帧必须做相同ROI裁剪
    frame1 = frame2
    ret, frame2 = cap.read()
    # 增加读帧判断
    if not ret:
        break
    frame2 = frame2[y:y+h, x:x+w]

    if cv2.waitKey(1) == 27:
        break

cap.release()
cv2.destroyAllWindows()
额外说明
  • 原代码里导入了imutils但全程没有使用,修复时直接移除了冗余导入
  • 原代码里的轮廓变量сontours首字符是西里尔字母с,不是标准英文字母c,部分编码环境下可能触发变量名识别错误,修复时统一换成了标准英文字母命名的变量
  • 原代码里绘制矩形、文字的坐标都是基于ROI裁剪后的局部坐标系,不需要额外做坐标转换,完全可以正常在ROI窗口里标注运动目标。

内容的提问来源于stack exchange,提问作者Mikhail

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 15:00:53