Pythonでいろいろやってみる

Pythonを使った画像処理や機械学習などの簡単なプログラムを載せています。

まちまちなサイズの複数の画像をきれいに並べて一枚の画像にまとめる

サイズがまちまちな複数の画像をきれいに並べて一枚の画像にし、画像の一覧を作成します。
フォルダ内の画像を2枚ずつ高さを揃えて並べ、それを繰り返すことで、フォルダ内の全ての画像を幅の決まった一枚の画像にします。

環境
  • windows10 home
  • Anaconda 3/ jupyter notebook 5.6.0
  • Python 3.7.0
  • OpenCV 4.0.0
準備

画像ファイルはフリー写真素材ぱくたそから7枚の画像をダウンロードさせていただき、jupyter notebookファイル(***.ipynb)と同じディレクトリにフォルダ'images'を作りその中に保存しました。
サイズ、アスペクト比(縦横比)がまちまちな画像です。

f:id:T_A_T:20200526193516p:plain

コード

処理の流れは
①画像フォルダからファイル名を読み出しリストにする
②画像を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枚の画像にまとめられます。

f:id:T_A_T:20200526193701p:plain

以下のサイトを参考にさせていただきました

Pythonの文法メモ > 【OpenCV】画像読み出しとサイズ・画素情報取得、切り抜き、貼り付け、チャネル操作
Pythonの文法メモ > 【OpenCV】画像の連結
Pythonの文法メモ > 【OpenCV】画像サイズを変更するresize

ブログランキングに参加しています

にほんブログ村 IT技術ブログへ
にほんブログ村