Python/OpenCVで画像連結!横と縦に繋げてみた

  • このエントリーをはてなブックマークに追加

2つ以上の画像を比較したい時等、Pythonであれば簡単に画像を横と縦に連結させることができます。ここではOpenCVのhconcatとvconcatを使って画像連結をする方法を紹介します。

こんにちは。wat(@watlablog)です。
画像処理プログラミングを進めていると、画像同士の連結をしたくなる時があります!ここでは2つの画像を横や縦に連結する方法を紹介します

画像連結の概要と使用場面

画像連結の方法(図解)

2つの画像「image1.JPG」と「image2.JPG」を仮定して連結する方法を解説していきます。

取り扱う画像は必ずしも同じサイズというわけではありません。以下の図のように、異なるサイズを連結する場合を考えてみましょう。

用意する画像

今回紹介する画像連結プログラムはOpenCVのvconcatやhconcatという関数を使いますが、これらの関数は縦に連結する時は横方向のサイズが、横に連結する時は縦方向のサイズが等しくないとエラーになります。

画像連結プログラムで懸念されるエラー内容

異なるサイズの画像をOpenCVのhconcatで連結させようとした場合のエラー内容を先に紹介しておきます。その内容は以下のようになります。

cv2.error: OpenCV(4.1.0)~error: (-215:Assertion failed) src[i].dims <= 2 && src[i].rows == src[0].rows && src[i].type() == src[0].type() in function 'cv::hconcat'

なんじゃこりゃ???

特にメッセージが英語の文になっているわけでは無く、プログラムコードのような文が羅列されていて、何が言いたいのかよくわかりませんよね。

というのも、OpenCV系のエラーはCライブラリを使っているので、エラーがわかりにくいことで有名のようです(以下Stack Overflowの質疑応答のやりとりを引用させて頂きました)。

PythonのOpenCVはCライブラリのラッパーなので、エラーの原因を探るのはかなり辛いです。ありがちなのは画像のカラーモード。グレースケールだと動いたりすることもあります。 – Kenji Noguchi 16年11月5日 0:38

Stack Overflow:OpenCV Errorが発生します

今回はあえてサイズの異なる画像同士を連結させようとしてエラーを出していますが、知らない人にとってはかなり悩む所ではないでしょうか?

では、サイズの異なる画像同士の連結方法について説明します。

エラーを解決する方法:リサイズする

エラーを解決する方法はずばりリサイズです。どうしてもサイズを変更したくない時は背景に黒一色の画像を用意して小さい方の画像を貼り付けて使用する方法も考えられますが、今回は画像そのもののリサイズで対応する方法を紹介します。

以下の図がエラーを回避しつつサイズの異なる画像を連結する方法です

※横方向に連結する場合を描いています。

サイズの異なる画像同士をリサイズで連結させる方法

原理は簡単で、連結する辺の長さの大きい方に合わせるように小さい方の画像をリサイズするだけです。

連結させる辺だけサイズを変えてしまうと、アスペクト比がおかしくなってしまうので、ここでは変化倍率としてリサイズに使った比を残った辺に対して乗算しています。

画像連結が必要とされる場面

パノラマ画像作成に使用する

単純な連結だけでは全然足りませんが、360°分の写真があれば処理次第でパノラマ画像を作ることができます。

パノラマ画像については以下のPhotoshopのページが参考になります。

外部リンク:Photoshopでのパノラマ画像の作成と編集

画像連結技術はこのようなパノラマ画像に使用されている基本技術の1つでもあります。

Webページの1枚絵を作る

ブログやWeb関連の仕事をやっている人は、時にWebページ全体のイメージ画像が欲しい時があります

客先にプレゼンする時や、ページの画像解析をするのに、いちいちスクロールしてキャプチャした画像1つ1つ区切って行うよりも、1枚の画像として表現した方が効率的ですね。

画像連結技術はただ画像を並べて比較する以外にも様々な目的によって使われる基本的な技術です。

Pythonで画像を連結するコード

サンプル画像

今回使用する2つの画像は「Pythonでフォルダ内の画像を自動一括リサイズする方法」でリサイズした以下の画像を使います。

連結するサンプル画像

2つの画像を「横」に連結するコード:hconcat

以下のコードが2つの画像を横に連結させるコードです。

関数としてimage_hcombinemを作成して使うスタイルです。

少しif文を使いすぎな気もしますが、先ほど図解で説明したリサイズを行うために、1枚目の画像の方が大きい場合と小さい場合の両方に対応させるために致し方なかったのです。

このコードでは関数で連結画像を作って、戻り値として帰ってきた画像を本文で保存するという流れです。

2つの画像を「縦」に連結するコード:vconcat

以下のコードは先ほどとほぼ同じですが、vcancat関数を使って縦方向に連結させています。違いはリサイズ判定のhとwが入れ替わっている所と、hconcatvconcatに変更されている所だけです。

実行結果

横方向連結画像

hconcatを使ったコードの実行結果です。

image1.JPGが適切にリサイズされて連結されています。

横方向連結画像

縦方向連結画像

vconcatを使ったコードの実行結果です。

先ほどと同様にリサイズが適切に行われ、縦方向に連結されました。

まとめ

本記事ではPythonのOpenCVで2つの画像を連結させる時に懸念されるエラーとその回避方法を解説しました。

また、画像連結は意外と色々な場面で使われていることもわかり、最後にPythonコードを横連結、縦連結の2種類紹介しました。

画像連結もPythonなら楽々!これからその応用にも手を出したいですね!
Twitterでも関連情報をつぶやいているので、wat(@watlablog)のフォローお待ちしています!

  • このエントリーをはてなブックマークに追加

SNSでもご購読できます。

コメント

コメントを残す

*