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

使用OpenCV cv2鼠标绘制矩形时出现重叠重复矩形问题排查

问题:OpenCV鼠标绘制矩形出现多个重叠矩形

在Python中使用OpenCV通过鼠标绘制矩形时,每次绘制都会出现多个相互重叠的矩形,而非单个矩形。以下是原始代码:

import cv2
import numpy as np

drawing  = False
ix,iy = -1, -1
img = cv2.imread('drawing_over_image/dog.jpg')
def draw(event, x, y, flags, params):

    global ix, iy, drawing

    if event == cv2.EVENT_LBUTTONDOWN:
        ix,iy = x,y
        drawing = True

    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing:
            if ix < x and iy < y:
                cv2.rectangle(img=img, pt1=(ix,iy), pt2=(x,y), color=[255,0,0], thickness=1)
    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        cv2.rectangle(img=img, pt1=(ix,iy), pt2=(x,y), color=[255,0,0], thickness=1)


if __name__ == "__main__":
    
    while True:
        cv2.imshow(winname='image', mat=img)
        cv2.setMouseCallback('image', draw)

        if cv2.waitKey(1) == 27:
            cv2.destroyAllWindows()
            break
问题原因

原始代码在鼠标移动过程中,每次都会直接在**原始图像img**上绘制矩形,导致鼠标拖动时的每一个位置都会留下矩形痕迹,最终出现重叠的多个矩形。同时代码限制了只能从左上到右下绘制,忽略了其他方向的拖动场景。

解决方案
  • 保存原始图像的副本img_copy,作为每次绘制的基准
  • 鼠标移动时,先将img_copy复制到显示用的图像上,再绘制当前的临时矩形,确保拖动过程中只显示一个矩形
  • 移除方向限制,支持任意方向拖动绘制矩形
  • 鼠标松开时,将最终的矩形绘制到原始副本上,保存绘制结果
修正后的代码
import cv2
import numpy as np

drawing = False
ix, iy = -1, -1
# 读取原始图像并创建副本
img = cv2.imread('drawing_over_image/dog.jpg')
img_copy = img.copy()

def draw(event, x, y, flags, params):
    global ix, iy, drawing, img

    if event == cv2.EVENT_LBUTTONDOWN:
        ix, iy = x, y
        drawing = True
    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing:
            # 每次移动时恢复原始图像副本
            img = img_copy.copy()
            # 计算矩形对角点,支持任意方向拖动
            cv2.rectangle(img, (min(ix, x), min(iy, y)), (max(ix, x), max(iy, y)), (255, 0, 0), 1)
    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        # 松开鼠标后将最终矩形绘制到原始副本
        cv2.rectangle(img_copy, (min(ix, x), min(iy, y)), (max(ix, x), max(iy, y)), (255, 0, 0), 1)
        # 更新显示图像
        img = img_copy.copy()

if __name__ == "__main__":
    while True:
        cv2.imshow('image', img)
        cv2.setMouseCallback('image', draw)
        # 按ESC键退出
        if cv2.waitKey(1) == 27:
            cv2.destroyAllWindows()
            break

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 09:55:24