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

实现随鼠标移动的任意点数Bounding Box,解决重复绘制问题

问题解决:避免重复绘制Bounding Box并实现任意数量点的跟随移动

问题根源

每次鼠标事件触发时,你都在同一个clone图像上绘制多边形,而clone仅在初始化时复制了一次原始图像。后续的绘制会直接叠加在之前的内容上,这就导致了重复包围盒的出现。

修复方案

1. 重置绘制底图

每次绘制前,重新从原始图像复制干净的副本,确保每次绘制都基于空白的原始图,不会叠加历史绘制内容。

2. 区分鼠标事件类型

只在鼠标移动(cv2.EVENT_MOUSEMOVE)时更新包围盒坐标并绘制,避免不必要的重复触发。

3. 支持任意数量点的包围盒

添加左键点击添加固定点的逻辑,鼠标移动时让最后一个点跟随鼠标,形成动态多边形;右键可清空所有点重新绘制。

以下是修改后的完整代码:

import cv2
import numpy as np

class BoundingBoxWidget(object):
    def __init__(self):
        self.original_image = cv2.imread('parking_lot.png')
        self.clone = self.original_image.copy()
        cv2.namedWindow('image')
        cv2.setMouseCallback('image', self.handle_mouse_events)

        # 存储多边形的固定顶点
        self.fixed_points = []
        # 存储当前跟随鼠标的临时顶点
        self.temp_point = None

    def handle_mouse_events(self, event, x, y, flags, parameters):
        # 左键点击添加固定顶点
        if event == cv2.EVENT_LBUTTONDOWN:
            self.fixed_points.append((x, y))
            if len(self.fixed_points) >= 2:
                self.redraw()
        # 鼠标移动时更新临时顶点并重新绘制
        elif event == cv2.EVENT_MOUSEMOVE:
            self.temp_point = (x, y)
            self.redraw()
        # 右键点击清空所有顶点,重置画布
        elif event == cv2.EVENT_RBUTTONDOWN:
            self.fixed_points = []
            self.temp_point = None
            self.clone = self.original_image.copy()
            cv2.imshow("image", self.clone)

    def redraw(self):
        # 每次绘制前重置为原始图像副本
        self.clone = self.original_image.copy()
        # 组合固定顶点和临时顶点
        all_points = self.fixed_points.copy()
        if self.temp_point is not None and len(all_points) > 0:
            all_points.append(self.temp_point)
        
        # 至少2个点才绘制多边形
        if len(all_points) >= 2:
            points = np.array(all_points, np.int32)
            points = points.reshape((-1, 1, 2))
            # 绘制未闭合的轮廓线(蓝色)
            cv2.polylines(self.clone, [points], False, (255, 0, 0), 2)
            # 点数量≥3时,绘制闭合的包围盒(绿色)
            if len(all_points) >= 3:
                cv2.polylines(self.clone, [points], True, (0, 255, 0), 1)
        
        cv2.imshow("image", self.clone)

    def show_image(self):
        return self.clone

def main():
    boundingbox_widget = BoundingBoxWidget()

    while True:
        cv2.imshow('image', boundingbox_widget.show_image())
        key = cv2.waitKey(1)

        # 按'q'退出程序
        if key == ord('q'):
            cv2.destroyAllWindows()
            break

if __name__ == '__main__':
    main()

代码说明

  • 添加固定顶点:鼠标左键点击图像,添加多边形的固定顶点。
  • 动态跟随:鼠标移动时,最后一个顶点会跟随鼠标位置,实时更新多边形形状。
  • 闭合包围盒:当固定顶点数量≥3时,会显示绿色的闭合轮廓线。
  • 清空重置:鼠标右键点击可清空所有已添加的顶点,重新开始绘制。
  • 无重复绘制:每次绘制前都会重置图像副本,彻底解决历史内容叠加的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 10:57:33