Pythonで面倒が「画像結合」を自動化|複数の画像をくっつけて1つのファイルにする方法

こんにちは、kinocodeです。
仕事で資料作成などをする際に、複数の画像を1つに結合して使いたい時があると思います。
こんな時、皆さんはどのようにしていますか?
例えばエクセルに隣り合わせで画像を貼り付け、pdfで書き出すといった方法を思いつくかもしれません。
ただこのようなアナログな方法は、継ぎ目がずれたりと使い勝手があまりよくありませんよね。

前回画像のデータ形式を変換するのに使用した、OpenCVというライブラリを覚えているでしょうか。
OpenCVを使えば、画像の結合も簡単に行うことができます。
今回はこのやり方について詳しく解説します。
それでは始めていきましょう。

Pythonで面倒が「画像結合」を自動化|複数の画像をくっつけて1つのファイルにする方法
!pip install opencv-python
Requirement already satisfied: opencv-python in /opt/anaconda3/lib/python3.8/site-packages (4.5.1.48)
Requirement already satisfied: numpy>=1.17.3 in /opt/anaconda3/lib/python3.8/site-packages (from opencv-python) (1.19.2)

初めに、OpenCVをインストールします。
!、pip、install、opencv-pythonでインストールできます。
実行します。

import cv2

次に、今回使用するcv2というモジュールをimportします。
モジュールがたくさん集まったのが、パッケージ、パッケージがたくさん集まったものがライブラリです。
実行します。

#画像データを変数に代入する
img_01 = cv2.imread('./kinocode_01.png')
img_02 = cv2.imread('./kinocode_02.png')

今回は私のブログのスクリーンショット2枚を結合してみたいと思います。
画像ファイル名はそれぞれkinocode_01.png、kinocode_02.pngです。
この画像ファイルはブログに公開していますので、必要な方はそちらからダウンロードしてください。

まず結合したい画像ファイルを変数に代入します。
2つの画像を代入する変数をそれぞれimg_01、img_02とします。
cv2のimread関数で画像を読み込み、各変数に代入します。
なお、imread関数は、pngだけでなく、jpegやtiffなどのデータ形式にも対応しており、同じ方法で画像を読み込むことができます。
対応しているデータ形式の種類は、公式リファレンスをご確認ください。

それでは実行します。

#画像データを入れるリスト作成
v_list = []

続いて結合する画像ファイルを収納するためのリストを作成します。
変数v_listに空のリストを渡しましょう。
実行します。 

#画像データをリストに追加
v_list.append(img_01)
v_list.append(img_02)

結合する画像データimg_01、img_02を、作成した空のリストv_listに追加していきます。
リストへのデータ追加は、appendメソッドを使用して行います。
実行します。

#画像データを縦に結合する処理(vはvartical(縦)の頭文字)
image_v = cv2.vconcat(v_list)

ここからは画像データの結合に入っていきます。
あらかじめ画像の結合に使用する関数について説明します。
縦結合にはcv2のvconcat関数を、横結合にはhconcat関数を使用します。
関数名の"v"と"h"は、英語のverticalとhorizontalの頭文字で、画像の結合方向を表しています。
使い方は簡単で、引数に結合したい複数の画像を指定すればOKです。
それではvconcat関数を使用して画像を縦結合し、変数image_vに代入します。
vconcat関数の引数には、先ほど2枚の画像を収納したv_listを指定します。

実行します。

#結合した画像のファイル名を指定する
image_v_name = '縦結合.png'

#結合した画像データの書き出し
cv2.imwrite(image_v_name, image_v)
True

続いて結合した画像データを書き出します。
あらかじめ書き出すときの画像ファイル名を変数image_v_nameに代入します。
画像ファイル名は分かりやすいように縦結合.pngとしました。

それでは書き出していきましょう。
画像の書き出しはcv2のimwrite関数で行うことができます。
第一引数に画像ファイル名image_v_nameを渡し、第二引数に先ほど結合したimage_vを渡しましょう。
なおimread関数同様、imwrite関数も様々な画像ファイルのデータ形式に対応しています。
詳しくは公式リファレンスにてご確認ください。

では実行します。
Trueが返ってくれば成功です。

画像を書き出した現在jupyterlabのファイルを開いている階層を確認してみましょう。
縦結合.pngという画像ファイルが作成されていることが確認できました。

#画像を横に結合する処理(hはhorizontal(水平)の頭文字)
image_v = cv2.hconcat(v_list)
image_v_name = '横結合.jpeg'
cv2.imwrite(image_v_name, image_v)
True

同じやり方で画像ファイルを横結合してみましょう。
また今度は結合した画像ファイルをpngではなく、jpegファイルとして書き出してみます。

コードは先ほど作成したものを流用し、次の2点だけ変更します。
1点目は画像の結合に使用する関数の変更で、vconcat関数からhconcat関数に変更します。
2点目は書き出すときのファイル名の変更で、縦結合.pngから横結合.jpegに変更します。
imwrite関数は第一引数に指定したファイル名に合わせて、画像のデータ形式を変換して書き出してくれます。
そのためこれで画像ファイルを横結合し、jpegファイルとして書き出す準備が整いました。

それでは実行します。

現在jupyterlabのファイルを開いている階層を再度確認してみましょう。
横結合.jpegが作成されたことが確認できました。

お疲れ様でした。
それでは、次のレッスンでお会いしましょう。

レッスンで使用したファイルはこちら

■保存方法
Mac:右クリック⇒「リンク先を別名で保存」
Windows:右クリック⇒「名前を付けてリンク先を保存」

image_join.ipynb

kinocode_01.png

kinocode_02.png