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

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

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

この記事の信頼性と私のプロフィール

この記事は、Youtubeにて日本最大級のプログラミング教育のチャンネルを運営しているキノコードが執筆、監修しています。
私自身は、2012年からプログラミング学習を始め、2019年以降はプログラミング教育に携わってきた専門家です。
他にも、私には下記のような実績や専門性があります。

  • キノコードは毎月10名以上、合計100名以上ののプログラミング学習者と1対1でお悩みを聞き、アドバイスをしています
  • キノコード自身は、プログラミングスクールに通ったり、本や有料の動画で勉強してきた経験もあります
  • キノコードは、プログラミング学習サービス「キノクエスト」を運営しています
  • またの出版、プログラミング雑誌への寄稿の実績があります

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

キノクエストでアカウントの新規登録に進み、メール認証を完了します。

ログインした状態(プラン選択画面が表示されます)で下記のボタンをクリックいただくか、ファイルダウンロードページのURL:https://kinoquest.jp/main/file_download/を直接アドレスバーに入力ください。

!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が作成されたことが確認できました。

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