Pythonで連番画像の読み込み(str/format/glob)

Pythonで連番画像を読み込む方法の紹介です。画像の読み込み自体はOpenCVのimread関数で行いますが、この関数にはファイル名の文字列を渡す必要があります。今回はPythonで連番ファイルの文字列を生成する方法の解説です。

0.png 1.png 2.png 3.pngというような連番ファイルの場合

この場合が一番簡単かもしれません。Pythonでは数値(整数型)を文字列に変換する関数str()を使えます。for i in range(10)で0~9までの整数をループできるので、次のコードでは0.png〜9.pngを処理することができます。

import cv2
import numpy as np
for i in range(10):
  img = cv2.imread(str(i)+".png",cv2.IMREAD_GRAYSCALE)

000.png 001.png 002.png 003.pngというような0埋め連番ファイルの場合

このように、先頭に0がいくつか付いていて、全てのファイルで桁数が揃っているような名前の付け方をゼロ埋めとか、ゼロパディングされている文字列、というように表現します。ゼロ埋めしていないファイル名だとファイル名でソートしたときに2.pngと10.pngは10.pngの方が前に来てしまいます(先頭文字の2と1を比較したときに1のほうが順位が前だからです)。これを、ゼロ埋めしているとこのようなことがおこらなくなるのでゼロ埋めすることがあります。

ゼロ埋め文字列を生成する方法で一番簡単なのがformat関数を使う方法です。”{0:03d}.png”.format(i)というようにすれば、iを3桁でゼロ埋めした文字列に.pngをつけた文字列を作ることができます。iが4桁以上のときには4桁になります。次のコードでは000.png〜099.pngを処理することができます。

import cv2
import numpy as np
for i in range(100):
  img = cv2.imread({0:03d}.png".format(i), cv2.IMREAD_GRAYSCALE)

format関数の03dを06dとすると6桁揃えになります。また、-3dとすると0ではなくスペースでパディングします。次のコードでは000000.png〜000099.pngを処理することができます。

import cv2
import numpy as np
for i in range(100):
  img = cv2.imread({0:06d}.png".format(i), cv2.IMREAD_GRAYSCALE)

そもそも連番ではないが、特定のディレクトリ内のファイルをすべて処理したい場合

globモジュールを使って、条件にマッチするファイルをすべて処理することができます。例えばimage/フォルダの中にa.png b.png c.png d.jpg e.jpg f.jpgという名前のファイルがあったとします。次のコードでこれら6つのファイルを読み込むことができます。アスタリスク*がワイルドカード文字となり、image/*と指定することでimage/○○というファイルすべてをリストアップすることになります。なお、Python3ではアスタリスク2連続**で子フォルダも再帰的に検索することができるようになりました。

import cv2
import numpy as np
import glob
files = glob.glob("image/*")
for f in files:
  img = cv2.imread(f, cv2.IMREAD_GRAYSCALE)

拡張子を指定することも可能です。すなわち、例えばpngファイルのみを読み込みたいときには次のようにします。image/*.pngと指定することでimage/○○.pngというファイルすべてをリストアップすることになります。

import cv2
import numpy as np
import glob
files = glob.glob("image/*.png")
for f in files:
  img = cv2.imread(f, cv2.IMREAD_GRAYSCALE)