見出し画像

自分がよく使う焦点距離をPythonで調べようの回

はじめに

我々写真を嗜むものは常にレンズが欲しいものです。
しかし、撒き餌レンズならまだしも、大三元や望遠単、明るい標準単は高価です。
そこで、今までの写真データから自分がよく使う焦点距離を調べようと思い立ちました。
完成形はこんな感じ。

画像1

環境

Python: 3.7.8
Pillow: 9.0.0
numpy: 1.21.5
matplotlib: 3.5.1
参照画像の格納場所: D:/写真/

Exifから焦点距離情報を得る

Exif情報から焦点距離を抜き出すのにはPillowを使います。
ネット上にたくさん情報がありますので、調べると絞り値やシャッタースピード、レンズ情報等も統計が取れると思います。

今回使うコードは焦点距離のみを格納するように書いてます。
コードと同じディレクトリにtest.jpgという写真データを用意します。
Exifが残ってることを確認してください。

from PIL import Image
from PIL.ExifTags import TAGS
from PIL.MpoImagePlugin import MpoImageFile
import PIL.ExifTags as ExifTags

class ExifImage:

  def __init__(self, fname):
      self.img = Image.open(fname)
      self.exif = {}
      if self.img._getexif():
          for k, v in self.img._getexif().items():
              if k in ExifTags.TAGS:
                  self.exif[ExifTags.TAGS[k]] = v

  def print(self):
      if self.exif:
          for tag_id, value in self.exif.items():
              tag = TAGS.get(tag_id, tag_id)
              if tag == 'FocalLength':
                  print(f'焦点距離:{value}mm')

a = ExifImage("./test.jpg")
a.print()
焦点距離:200mm

こんな感じで出力されたら成功です。

グラフ化

拡張子が".jpg"のファイルのパスをリストに列挙する

リストを参照しながら焦点距離情報を別リストに入れていく

グラフ化

という手順でやっていきます。
解説するような内容でもないのでコードをすべて載せておきます。

from PIL import Image
from PIL.ExifTags import TAGS
from PIL.MpoImagePlugin import MpoImageFile
import PIL.ExifTags as ExifTags

import glob

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns


class ExifImage:

   def __init__(self, fname):
       self.img = Image.open(fname)
       self.exif = {}
       if self.img._getexif():
           for k, v in self.img._getexif().items():
               if k in ExifTags.TAGS:
                   self.exif[ExifTags.TAGS[k]] = v

   def print(self):
       if self.exif:
           for tag_id, value in self.exif.items():
               tag = TAGS.get(tag_id, tag_id)
               if tag == 'FocalLength':
                   #print(f'焦点距離:{value}mm')
                   list_AFL.append(value)

list_ALLpath = []
list_AFL = [] #AFL = Average Focal Length

PATH = "D:/写真/**"

for name in glob.glob(PATH, recursive=True ):
   if "lnk" not in name and "adobe" not in name:
       if ".jpg" in name or ".JPG" in name:
           list_ALLpath.append(name.replace("\\", "/"))
           a = ExifImage(list_ALLpath[-1])
           a.print()

mpl.style.use('ggplot')
l_si_i = [int(s) for s in list_AFL]

plt.hist(x=l_si_i, bins=100, color=(0.3, 0.3, 0.4))
plt.xlabel("Focal Length")
plt.ylabel("freq")
plt.title("Your favorite focal length")
plt.show()

ポイントとしては、globに渡すパスをD:/写真/**とすることで、D:/写真 以下の全ディレクトリを掘り下げて検索してくれます。
高速化のためなるべく下のディレクトリを指定すべきですが、ある程度深いところに画像データがあっても見つけてきてくれます。
あとは先ほどのprint(f'焦点距離:{value}mm')は高速化のためコメント化しました。

おわり

よい写真ライフを

この記事が気に入ったらサポートをしてみませんか?