对labelme标注的图片和json文件做resize操作
程序员文章站
2022-03-11 09:22:29
尝试解决的问题项目中要使用实例分割网络将图片中的目标分割出来,但是原图普遍非常大,大部分是 (5000pixels * 6000pixels) 这样的规格,如果直接传到网络中进行训练,计算量会非常大。所以考虑先离线resize好了之后作为数据集再训练网络,而不是在输入网络之间才resize(这样会很浪费时间)。实现代码废话少说,直接上代码即可:代码逻辑大概为先统计文件夹中的是图片的文件格式,例如有 {'jpg', 'JPG', 'png'} 这三种,接着使用 glob 库找到包含这几种后缀格式的所有图...
尝试解决的问题
项目中要使用实例分割网络将图片中的目标分割出来,但是原图普遍非常大,大部分是 (5000pixels * 6000pixels)
这样的规格,如果直接传到网络中进行训练,计算量会非常大。所以考虑先离线resize好了之后作为数据集再训练网络,而不是在输入网络之间才resize(这样会很浪费时间)。
实现代码
废话少说,直接上代码即可:代码逻辑大概为先统计文件夹中的是图片的文件格式,例如有 {'jpg', 'JPG', 'png'}
这三种,接着使用 glob
库找到包含这几种后缀格式的所有图片文件,对这些照片使用 cv2.resize()
函数进行等比例缩放,缩放后保存到目标文件夹去。另外也要对json格式的标注文件中的点坐标进行缩放,直接坐标乘以缩放比例即可。最后值得注意的一点是,json
标注文件中的 ['imageData']
字段也要改成resize之后的图片哦,不然使用labelme
打开后的图片还是原来没有resize前的图,polygons
的位置跟大小是不对的。
import cv2
import os
import glob
import json
import collections
import numpy as np
from labelme import utils
if __name__ == "__main__":
src_dir = './srcDir'
dst_dir = './dstDir'
if not os.path.exists(dst_dir):
os.makedirs(dst_dir)
# 先收集一下文件夹中图片的格式列表,例如 ['.jpg', '.JPG']
exts = dict()
filesnames = os.listdir(src_dir)
for filename in filesnames:
name, ext = filename.split('.')
if ext != 'json':
if exts.__contains__(ext):
exts[ext] += 1
else:
exts[ext] = 1
anno = collections.OrderedDict() # 这个可以保证保存的字典顺序和读取出来的是一样的,直接使用dict()的话顺序会很乱(小细节哦)
for key in exts.keys():
for img_file in glob.glob(os.path.join(src_dir, '*.' + key)):
file_name = os.path.basename(img_file)
print(f"Processing {file_name}")
img = cv2.imread(img_file)
(h, w, c) = img.shape # 统计了一下,所有图片的宽度里面,1344是占比较多的宽度中最小的那个,因此
# 都等比例地将宽resize为1344(这里可以自己修改)
w_new = 1344
h_new = int(h / w * w_new) # 高度等比例缩放
ratio = w_new / w # 标注文件里的坐标乘以这个比例便可以得到新的坐标值
img_resize = cv2.resize(img, (w_new, h_new)) # resize中的目标尺寸参数为(width, height)
cv2.imwrite(os.path.join(dst_dir, file_name), img_resize)
# 接下来处理标注文件json中的标注点的resize
json_file = os.path.join(src_dir, file_name.split('.')[0] + '.json')
save_to = open(os.path.join(dst_dir, file_name.split('.')[0] + '.json'), 'w')
with open(json_file, 'rb') as f:
anno = json.load(f)
for shape in anno["shapes"]:
points = shape["points"]
points = (np.array(points) * ratio).astype(int).tolist()
shape["points"] = points
# 注意下面的img_resize编码加密之前要记得将通道顺序由BGR变回RGB
anno['imageData']=str(utils.img_arr_to_b64(img_resize[..., (2, 1, 0)]), encoding='utf-8')
json.dump(anno, save_to, indent=4)
print("Done")
本文地址:https://blog.csdn.net/gaoyi135/article/details/110466932
上一篇: 接口自动化-yaml文件维护自动化用例