1. 项目概述
作为一名长期奋战在计算机视觉一线的开发者,我深知ROI(Region of Interest)坐标提取这个看似简单的任务有多么令人抓狂。每次需要从图像中截取特定区域时,要么得用截图工具反复测量像素位置,要么在代码里不断调整参数、运行、查看效果——这种低效的重复劳动简直是对生命的浪费。
为了解决这个痛点,我基于PySide6开发了一个轻量级的图像标记工具。它的核心功能是:
- 支持加载任意图像并保持原始像素坐标
- 提供矩形和多边形两种标注方式
- 自动输出标注区域的原始坐标
- 生成的坐标可直接用于OpenCV的ROI操作或AI模型输入
这个工具最大的价值在于:它彻底消除了"肉眼测距"的误差,让ROI提取变得精准而高效。实测下来,原本需要反复调试的工作现在只需简单标注就能完成,生产力提升至少3倍。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术选型与架构设计
2.1 为什么选择PySide6?
在GUI框架的选择上,我对比了Tkinter、PyQt和PySide6三个主流选项:
| 框架 | 优点 | 缺点 | 最终选择理由 |
|---|---|---|---|
| Tkinter | Python内置,无需安装 | 界面老旧,功能有限 | 排除 - 绘图性能不足 |
| PyQt | 功能强大,文档丰富 | 商业授权复杂 | 排除 - 授权问题 |
| PySide6 | Qt官方绑定,MIT授权 | 相对较新 | 选择 - 兼顾性能和授权 |
PySide6继承了Qt强大的图形能力,特别是它的QGraphicsView框架非常适合实现图像缩放和标注功能。更重要的是,PySide6采用宽松的MIT许可证,完全不用担心商业项目的授权风险。
2.2 核心架构解析
工具的核心类结构如下:
python复制class ImageWidget(QLabel):
"""核心绘图组件,负责图像显示和标注交互"""
def __init__(self):
# 初始化图像、缩放参数、标注数据等
self.scale_factor = 1.0 # 当前缩放比例
self.annotations = [] # 存储所有标注
self.current_tool = None # 当前使用的工具
class MainWindow(QMainWindow):
"""主窗口,负责UI布局和功能整合"""
def __init__(self):
self.image_widget = ImageWidget() # 核心绘图区域
self.scroll_area = QScrollArea() # 支持大图像滚动
self.setup_buttons() # 初始化功能按钮
这种分层设计使得:
- ImageWidget专注于图像处理和用户交互
- MainWindow负责整体界面和功能调度
- 两者通过信号-槽机制解耦,便于后续扩展
3. 关键功能实现细节
3.1 图像缩放与坐标映射
工具最核心的技术难点在于:如何在缩放后的图像上准确获取原始坐标。这需要解决两个问题:
- 视觉缩放实现:
python复制def zoom(self, delta, center_pos=None):
# 计算新旧缩放比例
old_scale = self.scale_factor
self.scale_factor *= 1.15 if delta > 0 else 1/1.15
# 限制缩放范围
self.scale_factor = max(self.min_scale, min(self.scale_factor, self.max_scale))
# 以鼠标为中心缩放
if center_pos:
self.offset_x = center_pos.x() - (center_pos.x() - self.offset_x) * se
