maskrcnn数据集对图片进行大小重置固定宽度1080
重置图片、json内容(标注点、图像高度、宽度、图像信息等)
import cv2
import os
import glob
import json
import collections
import numpy as np
from labelme import utils # pip install labelme
def reziseIMG():
latitude = 2 # 超出边缘的像素宽容度,这里是2像素
src_dir = '原图片、原json文件所在文件夹'
dst_dir = '目标文件夹'
overmarked_dir = '将不符合的复制一份到该文件夹方便查看;也可以后面修改宽容度处理这一批查看结果'
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
failed = False # 用于标记该图片标注失败
# 处理标注文件json中的标注点
json_file = os.path.join(src_dir, file_name.split('.')[0] + '.json')
with open(json_file, 'rb') as f:
anno = json.load(f)
for shape in anno["shapes"]: # 对每个标注框
points = shape["points"] # 取标注框的点序列
points_array = np.array(points) # 转化为数组
failed = False # 重置标记
# 检查每个标注点是否超出图像
for point in points_array:
if point[0] >= w or point[1] >= h:
if point[0] >= w+latitude or point[1] >= h+latitude:
print(img_file, "相差过远", point, w, h)
failed = True # 有标注点超出图像范围
break
else:
print(img_file, "可修正", point, w, h)
if point[0] >= w and point[0] - w <= latitude:
point[0] = w - 0.0001 # 对于差一点点的,归到边缘
if point[1] >= h and point[1] - h <= latitude:
point[1] = h - 0.0001 # 对于差一点点的,归到边缘
else:
continue
if not failed:
# 等比例缩放图片
w_new = 1080 # 设定宽度
h_new = int(h / w * w_new) # 高度等比例缩放
ratio = w_new / w # 标注文件里的坐标乘以这个比例便可以得到新的坐标值
points = (points_array * ratio).astype(int).tolist() # 等比缩放点坐标
shape["points"] = points
else:
break
if not failed:
# 注意下面的img_resize编码加密之前要记得将通道顺序由BGR变回RGB
img_resize = cv2.resize(img, (w_new, h_new)) # resize中的目标尺寸参数为(width, height)
# 更新图像信息
anno['imageData'] = str(utils.img_arr_to_b64(img_resize[..., (2, 1, 0)]), encoding='utf-8')
# 更新图像高度、宽度
anno['imageHeight'] = h_new
anno['imageWidth'] = w_new
# 保存json文件
save_to = open(os.path.join(dst_dir, file_name.split('.')[0] + '.json'), 'w') # 待生成对应标注json路径
json.dump(anno, save_to, indent=4)
if not failed:
# 保存图片
cv2.imwrite(os.path.join(dst_dir, file_name), img_resize)
print(file_name, "还有救")
else:
# 对于标注超出图像的进行另存 overmarked_dir
import shutil
shutil.copyfile(img_file, os.path.join(overmarked_dir, file_name))
shutil.copyfile(json_file, os.path.join(overmarked_dir, file_name.split('.')[0] + '.json'))
print(file_name, "没救了")
print("Done")
if __name__ == "__main__":
try:
reziseIMG()
except Exception as e:
import traceback
traceback.print_exc()