pillow(PIL)图片resize方向后会自动旋转问题

使用方法:拷贝至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

猜你喜欢

转载自blog.csdn.net/ohhardtoname/article/details/115290862