まちまちなサイズの複数の画像をきれいに並べて一枚の画像にまとめる
サイズがまちまちな複数の画像をきれいに並べて一枚の画像にし、画像の一覧を作成します。
フォルダ内の画像を2枚ずつ高さを揃えて並べ、それを繰り返すことで、フォルダ内の全ての画像を幅の決まった一枚の画像にします。
環境
準備
画像ファイルはフリー写真素材ぱくたそから7枚の画像をダウンロードさせていただき、jupyter notebookファイル(***.ipynb)と同じディレクトリにフォルダ'images'を作りその中に保存しました。
サイズ、アスペクト比(縦横比)がまちまちな画像です。
コード
処理の流れは
①画像フォルダからファイル名を読み出しリストにする
②画像を2枚ずつ開いて同じ高さかつ設定した幅になるようにリサイズする
③リサイズした2枚の画像を横に並べて白画像に貼る
④2枚の画像を貼った白画像を縦に貼る
⑤画像が無くなるまで繰り返す
となります。
画像枚数が奇数の場合は最後に一枚余るので、 ダミーの白画像を生成してそれと2枚組にしています。
import cv2 import numpy as np import os dir_path = 'images/' # 画像フォルダのパス files = os.listdir(dir_path) # フォルダ内のファイルをリストに width = 400 # まとめる画像の幅 padding = 4 # 画像の間の余白 # 画像結合用白画像の生成 img = np.zeros((int(padding/2), width, 3), np.uint8) img[:, :, :] = 255 imgbottom = img for i in range(0, len(files), 2): # 2つおきにファイル数まで繰り返し # 1枚目の読み出し img1 = cv2.imread(dir_path + files[i]) h1, w1, ch = img1.shape if i+1 == len(files): # 画像の数が奇数の場合の処理 img2 = np.zeros((int(width/2), int(width/2), 3), np.uint8) img2[:, :, :] = 255 h2, w2, ch = img2.shape else: # 2枚目の読み出し img2 = cv2.imread(dir_path + files[i+1]) h2, w2, ch = img2.shape # 1枚目、2枚目の画像の縮小率 r1 = (width - padding*3) * h2 / (h2*w1 + h1*w2) r2 = (width - padding*3) * h1 / (h2*w1 + h1*w2) # 1枚目、2枚目の画像の縮小後の高さと幅 h1r = int(h1*r1) w1r = int(w1*r1) h2r = int(h2*r2) w2r = int(w2*r2) # 画像のリサイズ img1r = cv2.resize(img1, (w1r, h1r)) img2r = cv2.resize(img2, (w2r, h2r)) # 張り合わせ用白画像 img12 = np.zeros((h1r+padding, width, 3), np.uint8) img12[:, :, :] = 255 # 白画像にリサイズ画像を貼る img12[int(padding/2):int(padding/2)+h1r, padding:padding+w1r, :] = img1r img12[int(padding/2):int(padding/2)+h2r, padding*2+w1r:padding*2+w1r+w2r, :] = img2r # 2枚の画像を貼った画像をimgに結合 img = cv2.vconcat([img, img12]) img = cv2.vconcat([img, imgbottom]) cv2.imwrite('images.png', img)
実行結果
7枚の画像が2枚ずつ4列に並べた幅400ピクセルの1枚の画像にまとめられます。
以下のサイトを参考にさせていただきました
Pythonの文法メモ > 【OpenCV】画像読み出しとサイズ・画素情報取得、切り抜き、貼り付け、チャネル操作
Pythonの文法メモ > 【OpenCV】画像の連結
Pythonの文法メモ > 【OpenCV】画像サイズを変更するresize