在计算机视觉项目中,数据标注的质量直接影响模型训练效果。最近我在处理一个RGBT(红外与可见光双模态)目标检测项目时,发现需要一种直观的方式来验证标注文件与图像的匹配情况。于是用Python开发了这个可视化工具,它能将红外与可见光图像并排显示,同时绘制YOLO格式的标注框,方便我们快速检查标注质量。
这个工具特别适合以下场景:
核心功能包括:
工具的核心是正确处理三种数据源的对应关系:
python复制# 关键路径处理逻辑
txt_list = sorted(glob.glob(os.path.join(txt_dir, '*.txt')))
basename = os.path.splitext(os.path.basename(txt_path))[0]
t_path = os.path.join(thermal_dir, basename + '.jpg')
v_path = os.path.join(visible_dir, basename + '.jpg')
这里有几个需要注意的实现细节:
实际项目中经常遇到文件缺失或命名不一致的情况,这种健壮性检查非常必要。
YOLO格式的标注文件(.txt)每行表示一个目标,格式为:
code复制<class_id> <x_center> <y_center> <width> <height>
我们需要将其转换为图像上的实际坐标:
python复制def load_yolo(txt_path, img_w, img_h):
boxes = []
with open(txt_path, 'r', encoding='utf-8') as f:
for line in f:
parts = line.strip().split()
cls = int(parts[0])
xc, yc, bw, bh = map(float, parts[1:5])
x1 = int((xc - bw/2) * img_w) # 左上角x
y1 = int((yc - bh/2) * img_h) # 左上角y
x2 = int((xc + bw/2) * img_w) # 右下角x
y2 = int((yc + bh/2) * img_h) # 右下角y
boxes.append((cls, x1, y1, x2, y2))
return boxes
关键转换点:
为了便于对比,我们将红外和可见光图像水平拼接:
python复制combo = cv2.hconcat([t_vis, v_vis])
这里有几个优化点:
标注框的绘制需要考虑可读性和美观性:
python复制def draw(img, boxes):
for cls, x1, y1, x2, y2 in boxes:
color = color_table[cls % len(color_table)] # 按类别循环取色
cv2.rectangle(img, (x1, y1), (x2, y2), color, 2)
label = names[cls] if cls < len(names) else f'id{cls}'
cv2.putText(img, label, (x1, y1-4),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
return img
绘制时的注意事项:
为了方便浏览大型数据集,实现了简单的键盘控制:
python复制key = cv2.waitKey(0) & 0xFF
if key == 27: # ESC键退出
break
elif key in (83, 2): # 右箭头/数字键盘2
idx = (idx + 1) % len(txt_list)
elif key in (81, 0): # 左箭头/数字键盘0
idx = (idx - 1) % len(txt_list)
设计考虑:
窗口标题栏显示丰富的信息:
python复制title = f'{basename} | 目标数:{len(boxes)} | [{idx+1}/{len(txt_list)}]'
cv2.setWindowTitle('RGBT图像对 (左:红外 右:可见光)', title)
这些信息帮助用户:
在使用过程中可能会遇到以下问题:
图像不显示或显示不全
标注框位置偏移
类别显示错误
处理大型数据集时的优化建议:
预加载文件列表
python复制# 提前获取所有有效文件对
valid_pairs = []
for txt_path in txt_list:
basename = os.path.splitext(os.path.basename(txt_path))[0]
t_path = os.path.join(thermal_dir, basename + '.jpg')
v_path = os.path.join(visible_dir, basename + '.jpg')
if all(map(os.path.isfile, [t_path, v_path])):
valid_pairs.append((txt_path, t_path, v_path))
图像缓存策略
多线程加载
根据实际需求可以考虑添加:
标注修正功能
统计信息展示
导出检查结果
使用前需要修改以下配置项:
python复制# ----------------- 配置区域 -----------------
txt_dir = r'path\to\labels\visible' # 标签文件目录
thermal_dir = r'path\to\images\infrared' # 红外图像目录
visible_dir = r'path\to\images\visible' # 可见光图像目录
names = ['person', 'car', 'bicycle'] # 类别名称列表
# -------------------------------------------
配置注意事项:
颜色方案调整
python复制# 修改color_table定制标注框颜色
color_table = [
(255, 0, 0), # 红色
(0, 255, 0), # 绿色
(0, 0, 255), # 蓝色
(255, 255, 0), # 青色
(0, 255, 255) # 黄色
]
显示样式调整
python复制# 修改绘制参数
thickness = 2 # 框线粗细
font_scale = 0.6 # 字体大小
font = cv2.FONT_HERSHEY_SIMPLEX # 字体样式
快捷键自定义
python复制# 修改键盘控制逻辑
if key == ord('q'): # 按q退出
break
elif key == ord('n'): # 按n下一张
idx = (idx + 1) % len(txt_list)
这个工具可以轻松适配其他YOLO格式的数据集:
单模态数据集
python复制# 只需配置一个图像目录
image_dir = r'path\to\images'
img_path = os.path.join(image_dir, basename + '.jpg')
多类别数据集
python复制# 扩展names列表即可
names = ['bus', 'car', 'cyclist', 'drone', 'pedestrian', 'plane', 'ship']
不同标注格式
python复制# 修改load_yolo函数解析其他格式
def load_coco(txt_path, img_w, img_h):
# 实现COCO格式解析
pass
在实际使用这个工具检查RGBT-Tiny数据集时,我发现它能快速暴露几类常见问题:红外与可见光图像不对齐、标注框偏移、漏标目标等。特别是在夜间场景中,红外图像中的行人非常清晰,而可见光图像中几乎不可见,这时就能明显看出标注质量是否一致。