问题描述
在我们使用 labelimg 这样的工具进行标注后,可能存在再次 resize 图片的需要,这个时候对标注框的调整就较为繁琐。
其实在 stackoverflow 这个问题 下面的答案已经针对这种需求给了比较全面的说明,感兴趣的朋友可以看看。我在本文中给出了我自己临时的一个解决方案,供参考。
解决方案
撸了一个小脚本如下
import re
import cv2
def resize_labelimg_pic(src_img_file, tar_img_file, src_ann_file, tar_ann_file, w_new):
'''
resize 已标注图片并更新标注文件
:param src_img_file: 原始图片地址
:param tar_img_file: 更新后图片地址
:param src_ann_file: 原始标注文件地址
:param tar_ann_file: 更新后标注文件地址
:param w_new: resize 后的图片宽度
'''
# 获取原始图片尺寸
img = cv2.imread(src_img_file)
h, w, _ = img.shape
# 计算缩放比例
ratio = w_new / w
# 计算目标图片尺寸并保存
h_new = int(h * ratio)
# 更新标注文件(直接基于正则替换)
with open(src_ann_file, "r") as f:
text = f.read()
text = re.sub("<width>.*</width>", f"<width>{w_new}</width>", text)
text = re.sub("<height>.*</height>", f"<height>{h_new}</height>", text)
for tab in ["xmin", "xmax", "ymin", "ymax"]:
text = re.sub(f"(?<=<{tab}>)(.*?)(?=</{tab}>)",
lambda match: str(int(int(match.group())*ratio)), text)
# 输出结果
tar_img = cv2.resize(img, (w_new, h_new))
cv2.imwrite(tar_img_file, tar_img)
with open(tar_ann_file, "w") as f:
f.write(text)