Python3 ExifのOrientation属性による画像の回転と縮小(PIL使用)

画像認識システムの落とし穴となる「ExifのOrientation属性」とは?

元記事
The dumb reason your fancy Computer Vision app isn’t working: Exif Orientation

Pythonの画像ライブラリ、ExifのOrientation属性が反映されないものが多いから
AIでの画像認識時は気をつけてねとのこと。

記事中で紹介されているExifのOrientation属性が付与された画像があるリポジトリ。
exif-orientation-examples

ダウンロードしてlabelImgで表示してみます。
Ubuntu 18.04にlabelImgをインストールして、学習用画像のラベル付を行う

左がlabelImg、右側は画像ビューワーで同じ画像を表示しています。
確かにExif情報が反映されていませんね。

a12_01.png



画像の回転リサイズ



指定ディレクトリにある画像すべてのOrientationを反映。
同時に画像のリサイズを行いたい場合はこんな処理になりました。

元画像:images
変換後:convertedに出力


  1. import PIL.Image
  2. import PIL.ImageOps
  3. import numpy as np
  4. import os
  5. def exif_transpose(img):
  6.     if not img:
  7.         return img
  8.     exif_orientation_tag = 274
  9.     # Check for EXIF data (only present on some files)
  10.     if hasattr(img, "_getexif") and isinstance(img._getexif(), dict) and exif_orientation_tag in img._getexif():
  11.         exif_data = img._getexif()
  12.         orientation = exif_data[exif_orientation_tag]
  13.         # Handle EXIF Orientation
  14.         if orientation == 1:
  15.             # Normal image - nothing to do!
  16.             pass
  17.         elif orientation == 2:
  18.             # Mirrored left to right
  19.             img = img.transpose(PIL.Image.FLIP_LEFT_RIGHT)
  20.         elif orientation == 3:
  21.             # Rotated 180 degrees
  22.             img = img.rotate(180)
  23.         elif orientation == 4:
  24.             # Mirrored top to bottom
  25.             img = img.rotate(180).transpose(PIL.Image.FLIP_LEFT_RIGHT)
  26.         elif orientation == 5:
  27.             # Mirrored along top-left diagonal
  28.             img = img.rotate(-90, expand=True).transpose(PIL.Image.FLIP_LEFT_RIGHT)
  29.         elif orientation == 6:
  30.             # Rotated 90 degrees
  31.             img = img.rotate(-90, expand=True)
  32.         elif orientation == 7:
  33.             # Mirrored along top-right diagonal
  34.             img = img.rotate(90, expand=True).transpose(PIL.Image.FLIP_LEFT_RIGHT)
  35.         elif orientation == 8:
  36.             # Rotated 270 degrees
  37.             img = img.rotate(90, expand=True)
  38.     return img
  39. def load_image_file(file, mode='RGB'):
  40.     # Load the image with PIL
  41.     img = PIL.Image.open(file)
  42.     if hasattr(PIL.ImageOps, 'exif_transpose'):
  43.         # Very recent versions of PIL can do exit transpose internally
  44.         img = PIL.ImageOps.exif_transpose(img)
  45.     else:
  46.         # Otherwise, do the exif transpose ourselves
  47.         img = exif_transpose(img)
  48.     img = img.convert(mode)
  49.     return img
  50. def main():
  51.     for file in os.listdir('images'):
  52.         # exif Orientation
  53.         img = load_image_file(os.path.join('images', file))
  54.         # 1/2にリサイズ
  55.         width, height = img.size
  56.         img = img.resize((int(width / 2), int(height / 2)))
  57.         # 結果を保存
  58.         img.save(os.path.join('converted', file))
  59.     
  60. if __name__ == '__main__':
  61.     main()



画像の向き変換と縮小が一括で行えました。

a12_02.png

関連記事

プロフィール

Author:symfo
blog形式だと探しにくいので、まとめサイト作成中です。
Symfoware まとめ

PR




検索フォーム

月別アーカイブ