Pythonで画像分析を行う際、Exif情報の確認は重要です。Exif情報には、撮影日時、カメラのモデル、設定など、画像自体の内容以外に様々なメタデータが含まれています。これらの情報は、画像の品質評価や画像処理におけるパラメータ調整などに役立ちます。この記事では、Pythonの画像処理ライブラリであるPillowを用いて、Exif情報を取得・活用する方法を解説します。
Exif情報とは
Exif (Exchangeable image file format) は、デジタルカメラやスマートフォンで撮影された写真に埋め込まれるメタデータの規格です。主にJPEG形式で利用されますが、TIFF形式などでも使われます。
Pillowのインストール
Pillowは、Pythonの標準ライブラリではありません。以下のコマンドでインストールします。
pip install Pillow
Exif情報の取得の基本的な方法
基本的な処理として、写真の「撮影日時」と「撮影したカメラのモデル」を取得します。
Image.open(image_path)で画像のパスの指定し、画像ファイルを開きます。img._getexif()が画像のExif情報を取得する処理です。Exif情報が存在しない場合はNoneを返します。Exif情報のタグは数値で表されています。TAGS辞書を使って、数値のタグIDを人間が読めるタグ名(文字列)に変換します。
サンプルコード
from PIL import Image from PIL.ExifTags import TAGS, GPSTAGS def get_all_exif(image_path): """Exif情報を取得し、GPS情報があれば変換""" with Image.open(image_path) as img: exif_data = img._getexif() if exif_data is None: return {} exif = {} for tag_id, value in exif_data.items(): tag = TAGS.get(tag_id, tag_id) exif[tag] = value # GPS情報を処理 if 'GPSInfo' in exif: gps_info = {} for tag_id, gps_value in exif['GPSInfo'].items(): tag = GPSTAGS.get(tag_id, tag_id) gps_info[tag] = gps_value exif['GPSInfo'] = gps_info return exif # 使用例 image_path = "your_image.jpg" # 画像ファイルのパスを指定 exif_data = get_all_exif(image_path) # Exif情報の表示(一部) if exif_data: print(f"撮影日時: {exif_data.get('DateTimeOriginal')}") print(f"カメラモデル: {exif_data.get('Model')}") else: print("Exif情報が見つかりませんでした。")
応用: GPS情報の詳細取得
GPS情報はGPSInfoの中に、さらに辞書として格納されています。以下の関数で、GPS情報をより扱いやすい形に変換できます。
get_gps_info:GPSInfoの中身を取り出し、タグ名を変換した辞書を返します。convert_to_degrees: 緯度経度の情報を度分秒(DMS)形式から度(Decimal)形式に変換します。GPSLatitudeRef,GPSLongitudeRef: 北緯/南緯、東経/西経を区別するためのタグです。
サンプルコード
from PIL.ExifTags import GPSTAGS def get_gps_info(exif_data): """ExifデータからGPS情報を取得し、辞書形式で返す""" if 'GPSInfo' not in exif_data: return None gps_info = {} for tag_id, value in exif_data['GPSInfo'].items(): tag = GPSTAGS.get(tag_id, tag_id) gps_info[tag] = value return gps_info def convert_to_degrees(value): """度分秒(DMS)形式から度(Decimal)形式に変換""" d = float(value[0]) m = float(value[1]) s = float(value[2]) return d + (m / 60.0) + (s / 3600.0) # 使用例 (get_all_exifで取得したexif_dataを渡す) gps_info = get_gps_info(exif_data) if gps_info: latitude = gps_info.get('GPSLatitude') longitude = gps_info.get('GPSLongitude') if latitude and longitude: lat_deg = convert_to_degrees(latitude) lon_deg = convert_to_degrees(longitude) # 緯度・経度の符号を考慮 lat_ref = gps_info.get('GPSLatitudeRef') lon_ref = gps_info.get('GPSLongitudeRef') if lat_ref == 'S': lat_deg = -lat_deg if lon_ref == 'W': lon_deg = -lon_deg print(f"緯度: {lat_deg:.6f}") print(f"経度: {lon_deg:.6f}")
Exifタグ一覧
以下に、主なExifタグとその説明をまとめます。
| カテゴリ | タグ名 (タグID) | 説明 |
|---|---|---|
| 基本情報 | ImageWidth | 画像の幅 (ピクセル単位) |
| ImageLength | 画像の高さ (ピクセル単位) | |
| BitsPerSample | 各色成分のビット数 | |
| Compression | 圧縮形式 (1: 非圧縮, 6: JPEG圧縮 など) | |
| PhotometricInterpretation | ピクセルデータの解釈方法 (RGB, YCbCr など) | |
| ImageDescription | 画像の説明 | |
| Make | カメラのメーカー名 | |
| Model | カメラのモデル名 | |
| Orientation | 画像の向き (1: 通常, 3: 180度回転, 6: 反時計回りに90度回転, 8: 時計回りに90度回転 など) | |
| XResolution | 画像の水平方向の解像度 (DPI) | |
| YResolution | 画像の垂直方向の解像度 (DPI) | |
| ResolutionUnit | 解像度の単位 (2: インチ, 3: センチメートル) | |
| Software | 画像処理に使用したソフトウェア名 | |
| DateTime | ファイルの更新日時 | |
| Artist | 撮影者名 | |
| Copyright | 著作権情報 | |
| 撮影設定 | ExposureTime | 露出時間 (シャッタースピード、秒単位) |
| FNumber | F値 (絞り値) | |
| ExposureProgram | 露出プログラム (1: マニュアル, 2: プログラムAE, 3: 絞り優先AE, 4: シャッター優先AE など) | |
| ISOSpeedRatings | ISO感度 | |
| ExifVersion | Exifバージョン | |
| DateTimeOriginal | オリジナルの撮影日時 | |
| DateTimeDigitized | デジタル化された日時 | |
| ShutterSpeedValue | シャッタースピード値 (APEX値) | |
| ApertureValue | 絞り値 (APEX値) | |
| BrightnessValue | 明るさの値 (APEX値) | |
| ExposureBiasValue | 露出補正値 (APEX値) | |
| MaxApertureValue | 最大絞り値 (APEX値) | |
| MeteringMode | 測光モード (0: 不明, 1: 平均, 2: 中央重点平均, 3: スポット, 5: マルチスポット など) | |
| LightSource | 光源 (0: 不明, 1: 昼光, 2: 蛍光灯, 3: タングステン, 10: フラッシュ など) | |
| Flash | フラッシュ (0x0: 発光禁止, 0x1: 発光, 0x18: ストロボ発光禁止 など) | |
| FocalLength | レンズの焦点距離 (mm単位) | |
| ColorSpace | 色空間 (1: sRGB, FFFF.H: Uncalibrated) | |
| ExposureMode | 露出モード (0: 自動露出, 1: マニュアル露出, 2: 自動ブラケット) | |
| WhiteBalance | ホワイトバランス (0: 自動, 1: マニュアル) | |
| SceneCaptureType | シーンキャプチャタイプ (0: 標準, 1: 風景, 2: ポートレート, 3: 夜景) | |
| GPS情報 | GPSInfo | GPS情報 (辞書形式、get_gps_info関数で処理) |
| その他(メーカー固有) | MakerNote | メーカー固有のタグ。 |
補足
- Exif情報の取得:
exif_data.get('タグ名')の形式でExif情報を取得します。 - GPSInfo: GPS情報は辞書形式で格納されており、さらに
GPSTAGSを用いてタグIDをタグ名に変換する必要があります。 - MakerNote: メーカー固有の情報を格納するタグで詳細な解析にはメーカーごとの仕様情報が必要になる場合があります。
注意点
Exif情報を保存しない設定で写真を撮影することも可能なため、すべての写真・画像に必ずExif情報が保存されているわけではありません。Exif情報は、専用のソフトウェアやツールを使って、後から変更・削除することが可能です。書き換えられている可能性もあり、必ずしも正しい情報とは限りません。
まとめ
本記事では、PythonとPillowライブラリを用いてExif情報を取得・活用する方法を解説しました。Exif情報を活用することで、撮影状況を詳細に把握し、分析に役立てることができます。Pillowは非常に多機能なライブラリでExif情報の取得以外にもさまざまなことが可能です。Pillowについては、下記の記事で紹介しています。
[PR]