質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

2154閲覧

python opencv 画像結合について

nekomami

総合スコア10

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2018/05/17 03:56

前提・実現したいこと

フォルダに入る画像(定期的に更新され、画像名も数も異なりますが同じサイズです)を、
横3列で結合したいと思います。
フォルダに入っている画像が6つなら、横3列縦2行、8つなら横3列縦3行、最後はblankの画像を入れて計9つで結合したいです。

リストに画像を入れて、concatで結合するのはどうかと思いましたが、
cv2.hconcat([ ]) の中にリストを入れて結合することはできないのでしょうか。

count = フォルダに入っているファイル数 filelist = ファイル名がリストで入っています num = 0 img = [] while (num < count): img.append(num) img[num] = filelist[num] num += 1

↑これで画像名が入ると思うのですが、下から2行目を

img[num] = cv2.imread(filelist[num])

に書き換えて画像が読み込まれますか、、。
実行してもエラーはでませんが、読み込まれているかどうか
確認する方法がわかりません。
読み込まれているようでしたら、

  image = cv2.hconcat([ この中にimg[0,1,2]を入れたい ])

↑こんなことはできないでしょうか。
hconcat([ の中にいろいろ書き込んでみましたが、エラーばかりです。
主にSyntaxErrorです。
実行できたとして、ここからどうするのか上記目的まで果てしないなと思っておりますが、
勉強がてら少しずつ理解していきたいと思っています。

初心者で不慣れなものですから、尋ねておきながら間違いや漏れがありましたらごめんなさい。
こんな方法でなくても、他に方法があるようでしたら教えていただけると嬉しいです。
どうぞよろしくお願いいたします。

発生している問題・エラーメッセージ

SyntaxError: can't assign to operator

該当のソースコード

ソースコード

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

windows7
python-3.6.4
opencv-3.4.1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

問題を少しずつ解きほぐしましょう。
註:思考の順序に沿って章立てしているので、実際の解決法と順番が前後します。

縦横に連結すること

こちらのコードを借りてみてはいかがでしょうか。

Python

def concat_tile(im_list_2d):
return cv2.vconcat([cv2.hconcat(im_list_h) for im_list_h in im_list_2d])

引用元: Python, OpenCVで画像を縦・横に連結 (hconcat, vconcat, np.tile)

例えばimg0からimg5を、横書きの方向に連結したいなら次のように呼べば良いです。

Python

1result = concat_tile( 2 [[img0, img1, img2], 3 [img3, img4, img5]] 4)

しかし毎回このように書くのは随分面倒ですね。自動化しましょう。

呼び出しに合わせてリストを変形すること

次のようなイディオムが利用できるでしょう。

Python

1>>> print(my_list) 2[0, 1, 2, 3, 4, 5] 3>>> 4>>> my_list_for_arg = [list(row) for row in zip(*[iter(my_list)]*3)] 5>>> print(my_list_for_arg) 6[[0, 1, 2], [3, 4, 5]]

このように書ける理由については、ちょっと煩雑なのでリンクに投げます。
気になるようなら読んでみてください。


さて、この時点で6画像の場合は連結できるはずです。
問題は空きマスが出る8画像のバージョンです。ダミーの画像を用意する必要があります。

結合可能な空画像を生成すること

結合可能にするためには、次の二条件に注意する必要があります。

  • 画像の形状 (shape)
  • 画素値を表現する数値型 (dtype)

モデル画像imgが既にあるとき、次のように真っ黒な画像を生成できます。

Python

1empty = np.zeros(img.shape, dtype=img.dtype)

次の問題は、空画像をどのように扱うか、です。

空画像を画像リストに追加すること

画像数が3の倍数になるまで、空画像をリストimgsに押し込んでやりましょう。

Python

1while len(imgs) % 3 != 0: 2 imgs.append(empty)

ここまでやれば、8画像の場合にも対応できます。

結局どう書けばいいか?

処理の流れは次のとおりです。
0. 画像名を取得し、リストimg_namesを作る。
0. OpenCVを用いて各画像を読み込み、リストimgsを作る。
0. imgs[0]をモデルに、空画像emptyを作っておく。
上記『結合可能な空画像を生成すること』を参照のこと。
0. imgsのリスト長が3の倍数になるまでemptyをimgsに押し込む。
上記『空画像を画像リストに追加すること』を参照のこと。
0. imgsの形状を適切に変形し、concat_tileに渡す。
上記『呼び出しに合わせてリストを変形すること』を参照のこと。
0. 返り値が目的の画像。

その他

画像が読み込まれますか、、。実行してもエラーはでませんが、読み込まれているかどうか確認する方法がわかりません。

OpenCVのPythonバインディングは、imreadに失敗するとNoneを返すというえげつない設計です。
個人的には次のように書いておくことが多いです。

Python

1img = cv2.imread(ファイル名) 2assert img is not None

このように書いておけば、読み込みに失敗したときも早い段階でエラーに出来ます。


hconcat([ の中にいろいろ書き込んでみましたが、エラーばかりです。主にSyntaxErrorです。

...[中略]...

SyntaxError: can't assign to operator

こればっかりはコードを読んでみないとなんとも言えません。
見たことがないわけではないですが...

Python

1>>> b = 3 2>>> a + b = 10 3 File "<stdin>", line 1 4SyntaxError: can't assign to operator

投稿2018/05/17 08:12

編集2018/05/17 09:17
LouiS0616

総合スコア35660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nekomami

2018/05/17 08:36

ありがとうございます。 ご丁寧に回答いただけてうれしいです。 お返事いただいた内容を少しずつ調べて進めて理解していきます。 長文でご親切にお返事いただけると思っておりませんでしたので、 内容はまだ理解できておりませんが、取り急ぎお礼が言いたくてお返事しました。 こちらの利用方法もあまり詳しく理解しないまま質問してしまいましたので 何かアクションしないまま失礼があるのではと思いますが、 お返事いただいた内容にまたつまづくことになるレベルまで理解が達しましたら、 またコメントさせていただきます。(時間がかかりそうですがすみません)
LouiS0616

2018/05/17 09:19

よく練られている質問文だと思いました。 ・各種バージョンが明記されている ・画像のサイズについての言及がある (非常に大事) ・なにを考えてなにを試したか、そしてその結果について言及がある ・実現したいことを具体的に記述しており、あいまいさが少ない
nekomami

2018/05/22 05:49

LouiS0616さん ご連絡遅くなりましてすみません。 先日はありがとうございました。 教えていただいた通り進めまして、画像結合まで至りました。 本当にありがとうございました。 プログラムそのものも初めて触るため、ひとつひとつを調べながらで時間がかかってしまいましたが、目的が達成できて嬉しいです。 ご回答いただきました処理の、1.2.3までは理解できまして、 3の空画像は、作成したjpgを読み込みました。 4.imgsのリスト長が3の倍数になるまでemptyをimgsに押し込む。 5.imgsの形状を適切に変形し、concat_tileに渡す。 ↑この2つは理解できていないまま、使わせてもらいました。  少しずつ勉強します。 6.返り値が目的の画像。 ↑これは、 cv2.imwrite('result.jpg', concat_tile(im_list_2d)) で、書き出されました。 ご親切にしていただきありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問