PIL通过exif旋转图像

一些图片是带有exif信息的,某些软件在读取图片时会通过exif信息对图片进行旋转,如果图片是训练集,并且带有标注框,那我们需要以相同的方向显示图片以及对应的标注框

假设图像的方向exif标记设置为3。我要做的是根据这个标签旋转这个图像,然后以这种方式保存它。这样,一个不解释exif的软件仍将以良好的方向显示它。但是,如果旋转后保存的图片exif标记方向仍然设置为3,那么解释exif的软件将再次旋转已旋转的图像。所以需要把这个标签设置为1(也就是说:没有方向)或者删除它

下面代码是如何通过exif信息判断图片的方向:

from PIL import Image

img = Image.open(temp_dir + filename)
if hasattr(img, '_getexif'):
    exif = img._getexif()
    for orientation in ExifTags.TAGS.keys():
        if ExifTags.TAGS[orientation]=='Orientation':
            break
    if exif is not None and orientation in exif.keys():
        orientation = exif[orientation]
        if orientation is 6: img = img.rotate(-90, expand=True)
        elif orientation is 8: img = img.rotate(90, expand=True)
        elif orientation is 3: img = img.rotate(180, expand=True)
        elif orientation is 2: img = img.transpose(Image.FLIP_LEFT_RIGHT)
        elif orientation is 5: img = img.rotate(-90, expand=True).transpose(Image.FLIP_LEFT_RIGHT)
        elif orientation is 7: img = img.rotate(90, expand=True).transpose(Image.FLIP_LEFT_RIGHT)
        elif orientation is 4: img = img.rotate(180, expand=True).transpose(Image.FLIP_LEFT_RIGHT)

#save the result
img.save(temp_dir + filename)

检查方向,将方向修改为1(没有方向)

import pexif
img = pexif.JpegFile.fromFile(temp_dir + filename)

try:
  #Get the orientation if it exists
  orientation = img.exif.primary.Orientation[0]
  img.exif.primary.Orientation = [1]
  img.writeFile(temp_dir + filename)
except:
    pass

使用Image读取图片可以使用中文路径,但是图片带有方向信息就容易出问题,导致标注框会和图片的方向不一致,因此需要将图片和标注框进行相应选择。

另外还有另一种解决办法,使用opencv读取读片,不会存在标注框和图片的方向不一致的问题,但是cv.imread对无法读取中文路径的图片,使用下面的方法可以加解决:

img = cv2.imdecode(np.fromfile(path, dtype=np.uint8), cv2.IMREAD_UNCHANGED)

有一个地方需要注意,tensorflow读取图片通常会使用下面的函数

tf.gfile.FastGFile(imagePath, 'rb').read()

但是,使用这个函数是和Image.open()函数一样存在同样的问题,需要读取exif信息来旋转图片的,如果不进行旋转,那么有可能导致图片和label是相差90度 的,训练模型的loss会很大,甚至导致模型不收敛

这个坑非常隐蔽,不仔细查看还真发现不了,下面介绍如何解决这个问题:

# method 1
import cv2
img = cv2.imread(img_path)
img_str = cv2.imencode('.jpg', img)[1].tostring()

# method 2
from scipy.ndimage import imread
imgbytes = imread(img_path)
img_str = imgbytes.tostring()

上面两种方式可以避免图片和label的方向不一致的问题,我使用的是上面的第一种方式代替tf.gfile.FastGFile,在此记录一下,避免以后采坑

crop rotated image可以参考:https://jdhao.github.io/2019/02/23/crop_rotated_rectangle_opencv/

参考:https://www.coder.work/article/360757

           https://developer.here.com/blog/getting-started-with-geocoding-exif-image-metadata-in-python3

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值