实现随鼠标移动的任意点数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
相关产品推荐
相关产品推荐

