どうもこんにちは!
最近プログラミング熱が上がってきました、みやしんです!
この記事ではpythonで写真や画像の大きさ(画素数)を変更したり、一部を切り抜いたりする方法をご紹介したいと思います。
特に画像分類や物体検出のディープラーニングを行うときのデータセット作成で必要となってくるテクニックと思いますので、皆さん是非チャレンジしてみてください。
では早速、やっていきましょう!
フォルダー構成
今回は下記のようなフォルダー構成で画像を加工していきます。

Pathlibでフォルダーパスを扱う
python3.4以降でpathlibというライブラリが導入されています。
まずはメインクラスのPathをインポートします。
from pathlib import Path
今回、カレントフォルダを「PictureProcess」とした時に、下記のようにフォルダを指定します。
input_folder = Path('input') #inputフォルダー
output_folder = Path('output') #outputフォルダー
Pillowを使った画像処理の基本
PillowはPythonの画像処理ライブラリです。Pillowでは下記のような編集ができます。
- 画像フォーマットの変換
- 画像の拡大や縮小
- 画像の切り取り
- 画像の色調整
- 画像への文字の書き込み 等
今回は、画像の拡大や縮小、画像の切り取りを行います。
まずは、下記のようにPILモジュールからImageクラスをインポートします。
from PIL import Image
例えば、画像ファイルを開くときは、
img = Image.open('ファイル名')
のように記述します。
それでは順にコードを確認していきたいと思います。
サンプルコード説明
必要なライブラリ(Path, Image)をインポートします。
from pathlib import Path from PIL import Image
各変数を定義します。
# 最終的に調整したい画像のサイズ:box_size = 320 (縦横のpixel数)
box_size = 320
# inputする画像を入れるフォルダのパス
input_folder = Path('input')
# outputされた(サイズ調整された)画像が保存されるフォルダのパス
output_folder = Path('output')
# outputフォルダーを作成。exist_ok = Trueとすると既存のフォルダーを対象としてもエラーにならない。(dirはディレクトリの略、ディレクトリ=フォルダー)
output_folder.mkdir(exist_ok=True)
画像の大きさを調整する。
# .glob()でフォルダー内のファイル名を返す。('*.jpg')でjpgのファイルを指定。
for f in input_folder.glob('*.jpg'):
# jpgファイルを開く
img = Image.open(f)
# img.sizeで幅と高さタプル
width, height = img.size
# 最終的な画像サイズ(box_size=320)が画像短辺の何倍か比率を算出
ratio = box_size / min(img.size)
# img.resize(幅, 高さ)で画像の大きさを変更する。幅と高さはintにキャスト(変換)しないとエラーになる。
resized_img = img.resize((int(width * ratio), int(height * ratio)))
ここまでの処理で下記のように画像のサイズを変えています。(input画像が320pixより大きい場合は縮小します)

続いて、長方形の画像を320×320の大きさに切り抜きます。
# width > heightの場合
if width > height:
# resized_img.size[0]は幅、resized_img.size[1]は高さ
# 画像を切り抜く大きさを求める
strip_size = resized_img.size[0] - box_size
# img.crop((left, top, right, bottom))で画像を切り抜く
cropped_img = resized_img.crop((
strip_size / 2,
0,
resized_img.size[0] - strip_size / 2,
resized_img.size[1]
))
# width =< heightの場合
else:
# resized_img.size[0]は幅、resized_img.size[1]は高さ
# 画像を切り抜く大きさを求める
strip_size = resized_img.size[1] - box_size
# img.crop((left, top, right, bottom))で画像を切り抜く
cropped_img = resized_img.crop((
0,
strip_size / 2,
resized_img.size[0],
resized_img.size[1] - strip_size / 2
))

最後にファイルに保存します。
# output_folder.joinpath()でoutput_folderのパスにjoinpath()のカッコ内のパスを連結。
# f.nameでファイル名
save_path = output_folder.joinpath(f.name)
# .saveで保存する
cropped_img.save(save_path)
# img.close()で画像ファイルを閉じる
img.close()
サンプルコード
サンプルコードの載せますので、コピペして使ってください^^
from pathlib import Path
from PIL import Image
# 最終的に調整したい画像のサイズ:box_size = 320 (縦横のpixel数)
box_size = 320
# inputする画像を入れるフォルダのパス
input_folder = Path('input')
# outputされた(サイズ調整された)画像が保存されるフォルダのパス
output_folder = Path('output')
# outputフォルダーを作成。exist_ok = Trueとすると既存のフォルダーを対象としてもエラーにならない。(dirはディレクトリの略、ディレクトリ=フォルダー)
output_folder.mkdir(exist_ok=True)
# .glob()でフォルダー内のファイル名を返す。('*.jpg')でjpgのファイルを指定。
for f in input_folder.glob('*.jpg'):
# jpgファイルを開く
img = Image.open(f)
# img.sizeで幅と高さタプル
width, height = img.size
# 最終的な画像サイズ(box_size=320)が画像短辺の何倍か比率を算出
ratio = box_size / min(img.size)
# img.resize(幅, 高さ)で画像の大きさを変更する。幅と高さはintにキャスト(変換)しないとエラーになる。
resized_img = img.resize((int(width * ratio), int(height * ratio)))
# width > heightの場合
if width > height:
# resized_img.size[0]は幅、resized_img.size[1]は高さ
# 画像を切り抜く大きさを求める
strip_size = resized_img.size[0] - box_size
# img.crop((left, top, right, bottom))で画像を切り抜く
cropped_img = resized_img.crop((
strip_size / 2,
0,
resized_img.size[0] - strip_size / 2,
resized_img.size[1]
))
# width =< heightの場合
else:
# resized_img.size[0]は幅、resized_img.size[1]は高さ
# 画像を切り抜く大きさを求める
strip_size = resized_img.size[1] - box_size
# img.crop((left, top, right, bottom))で画像を切り抜く
cropped_img = resized_img.crop((
0,
strip_size / 2,
resized_img.size[0],
resized_img.size[1] - strip_size / 2
))
# output_folder.joinpath()でoutput_folderのパスにjoinpath()のカッコ内のパスを連結。
# f.nameでファイル名
save_path = output_folder.joinpath(f.name)
# .saveで保存する
cropped_img.save(save_path)
# img.close()で画像ファイルを閉じる
img.close()
【更に実力UP!】自分が買って良かったオススメ本
僕が買ってみて良かったオススメ本をご紹介します。
<おススメな点>
- コードがしっかり記載してあって、そのままコードを使える
- 説明が分かりやすく初心者から使える
- 機能を分解してあって使い回しがきく
- 画像、csvやEXCELの操作、Webスクレイピングなど、すぐ使えるものばかり
- 作業の自動化を目的に書かれているので普段の仕事に活きる
<おススメな人>
- python初心者から中級者
- 普段の作業を効率化したい人
- pythonを勉強し始めたばかりで、何かに役立てたいと思っている人
実際にPythonを使えるようになってくると、どんどん楽しくなってきます!
合わせて読みたい
Matplotlibを使った図形の描画方法なんかも参考になると思います!ご興味のある方はこちらをご参照ください。
物体検出も面白いです!
yoloの物体検出モデルをファインチューニングしたい方はこちらをどうぞ
その他にもプログラミングやIT関係の情報に興味のある方はこちらをご参考にしてみてください。

以上になります。最後まで読んでくださりありがとうございました。






コメント