目次
概要
ディレクトリ内の画像をすべてリサイズしたいといった、あるディレクトリ内のファイルに同じ処理を行いたいというケースに使えるコードを紹介します。
ディレクトリ内の特定の拡張子のファイルを列挙する
あるディレクトリ内の特定の拡張子のファイルを列挙するコードを記載します。
In [1]:
from pathlib import Path
def get_paths(input_dir, exts=None):
paths = sorted([x for x in input_dir.iterdir()])
if exts:
paths = list(filter(lambda x: x.suffix in exts, paths))
return paths
# ディレクトリ内の指定した拡張子のファイルをすべて取得する。
input_dir = Path(r"/data/samples")
for path in get_paths(input_dir, exts=[".jpg", ".jpeg", ".png"]):
print(path)
指定ディレクトリ内の画像をリサイズして、別のディレクトリに保存する
先程のコードを利用して、あるディレクトリ内のすべての画像をリサイズして、別のディレクトリに保存するコードになります。
In [2]:
import cv2
from pathlib import Path
def get_paths(input_dir, exts=None):
paths = sorted([x for x in input_dir.iterdir()])
if exts:
paths = list(filter(lambda x: x.suffix in exts, paths))
return paths
# ディレクトリ内の指定した拡張子のファイルをすべて取得する。
input_dir = Path(r"/data/samples")
# 出力先のディレクトリを作成する。
output_dir = Path(r"output")
output_dir.mkdir(exist_ok=True)
for path in get_paths(input_dir, exts=[".jpg", ".jpeg", ".png"]):
# 画像を読み込む。
img = cv2.imread(str(path))
# リサイズする。
dst = cv2.resize(img, (300, 300))
# 結果を保存する。
save_path = output_dir / path.name
cv2.imwrite(str(save_path), dst)
指定したディレクトリ内のファイルを再帰的に取得する
あるディレクトリの直下にあるファイルだけでなく、入れ子になったディレクトリ構造のすべてのファイルを再帰的に取得する場合は ` を
img_dir.glob(“*/“)` に変えます。
In [3]:
from pathlib import Path
def get_paths(input_dir, exts=None):
paths = sorted([x for x in input_dir.glob("**/*")])
if exts:
paths = list(filter(lambda x: x.suffix in exts, paths))
return paths
# ディレクトリ内の指定した拡張子のファイルをすべて取得する。
input_dir = Path(r"sample")
for path in get_paths(input_dir, exts=[".jpg", ".jpeg", ".png"]):
print(path)
concurrent.futures を使った処理の並列化
各々のファイルに対して行う処理が独立している場合、並列化することで処理時間を短縮できます。
並列化には concurrent.futures
を利用します。
Python – concurrent.futures を使った並列化の方法について – pystyle
In [4]:
from concurrent import futures
from pathlib import Path
import cv2
def get_paths(input_dir, exts=None):
paths = sorted([x for x in input_dir.iterdir()])
if exts:
paths = list(filter(lambda x: x.suffix in exts, paths))
return paths
# ディレクトリ内の指定した拡張子のファイルをすべて取得する。
input_dir = Path(r"/data/samples")
# 処理対象のファイル一覧を取得する。
input_paths = get_paths(input_dir, exts=[".jpg", ".jpeg", ".png"])
# 出力先のディレクトリを作成する。
output_dir = Path(r"output")
output_dir.mkdir(exist_ok=True)
def process(path):
"""処理内容を関数にまとめる
"""
# 画像を読み込む。
img = cv2.imread(str(path))
# リサイズする。
dst = cv2.resize(img, (300, 300))
# 結果を保存する。
save_path = output_dir / path.name
return cv2.imwrite(str(save_path), dst)
with futures.ThreadPoolExecutor() as executor:
rets = executor.map(process, input_paths[:10])
# 結果を受け取る。
print([x for x in rets])
[True, True, True, True, True, True, True, True, True, True]
複数の引数を渡したい場合は、ThreadPoolExecutor.map()
の代わりに ThreadPoolExecutor.submit()
をお使いください。この記事で解説しています。
コメント