使用方法:拷贝至python代码,放于图片上一层目录,运行。代码为按图像比例调节。通过设置横宽,高度会自动调节,目标横宽设置为代码第七行width
图片自动旋转原因是手机拍摄时记录了拍摄方向,信息记录在图片的exif内,resize后便自动调整了方向,通过读取exif信息,反向操作实现resize后方向不变。
这个代码是在pascalvoc格式标注图片后,已经生成xml文件后调整图片大小,若xml文件与图片置于相同文件夹下,在调整图片大小后也会对应改变xml文件中的标注信息
# -*- coding: UTF-8 -*-
import os
from PIL import Image
import exifread
import sys
import xml.etree.ElementTree as ET
import math
width_aim =550 # 调整后图片的目标尺寸
# width_aim = int(input("请输入您要调整到的图片宽度:"))
if __name__ == "__main__":
wd = os.getcwd() # 获取当前文件目录
dir_list = os.listdir(wd)
dir_pic = []
for item in dir_list:
if os.path.isdir(item):
# dir.append(item)
dir_path = os.path.join(wd, item)
dir_list_temp = os.listdir(dir_path)
for item2 in dir_list_temp:
if os.path.isfile(dir_path.replace('\\', '/') + '/' + item2):
try:
if item2.split('.')[1] == 'jpg' or item2.split('.')[1] == 'JPG':
dir_pic.append(dir_path + '/' + item2) # 此处搜集完所有图片文件路径名称放在dir中
except:
pass
for item in dir_pic:
# *****hahaha, 这一小段是整来耍的
sys.stdout.write('\r' + '/')
sys.stdout.flush()
sys.stdout.write('\r' + '|')
sys.stdout.flush()
sys.stdout.write('\r' + '\\')
sys.stdout.flush()
# print('\r'+'你的输出详情', flush=True)
f = open(item, 'rb')
tags = exifread.process_file(f)
need_ori_L = 0
need_ori_R = 0
need_ori_180 = 0
if 'Image Orientation' in tags.keys():
if 'Rotated' in str(tags['Image Orientation']):
if 'Rotated 90 CW' in str(tags['Image Orientation']): # right, top
need_ori_L = 1
elif 'Rotated 90 CCW' in str(tags['Image Orientation']): # left, bottom
need_ori_R = 1
elif 'Rotated 180' in str(tags['Image Orientation']): #
need_ori_180 = 1
# 还有Horizontal(normal)为正常情况
# 还有些情况未考虑到, 比如镜像等, 由于数量少,就偷个懒暂时忽略了
f.close()
# 有的图片中exif信息有orientation会影响图片方向, 下面代码用于解决该问题
img = Image.open(item)
if need_ori_L == 1:
img = img.transpose(Image.ROTATE_270)
elif need_ori_R == 1:
img = img.transpose(Image.ROTATE_90)
elif need_ori_180 == 1:
img = img.transpose(Image.ROTATE_180)
w, h = img.size
h_temp = int(h * (width_aim / w))
image = img.resize((width_aim, h_temp))
image.save(item)
# 对应调整图片xml文件中size
# 调整xml文件
try:
updateTree = ET.parse(item.split('.')[0] + '.xml')
# updateTree = ET.parse('C:/Users/DELL/Desktop/garbage-detec/images/IMG_20210327_105059.xml')
root = updateTree.getroot()
size = root.find('size')
width = size.find('width')
height = size.find('height')
width_original = int(width.text)
height_original = int(height.text)
width_changed = width_aim
height_changed = int(height_original * (width_changed / width_original))
width.text = str(width_changed)
height.text = str(height_changed)
# objects = root.getElementsByTagName("object")
objects = []
for item2 in root:
if item2.tag =='object':
objects.append(item2)
for object in objects:
bndbox = object.find('bndbox')
xmin = bndbox.find('xmin')
ymin = bndbox.find('ymin')
xmax = bndbox.find('xmax')
ymax = bndbox.find('ymax')
xmin.text = str(math.ceil((width_changed / width_original) * int(xmin.text)))
ymin.text = str(math.ceil((height_changed / height_original) * int(ymin.text)))
xmax.text = str(math.ceil((width_changed / width_original) * int(xmax.text)))
ymax.text = str(math.ceil((height_changed / height_original) * int(ymax.text)))
updateTree.write(item.split('.')[0] + '.xml', encoding = "UTF-8")
except:
pass