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

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

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

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

Q&A

1回答

2816閲覧

error: (-215) _img.size().height <= _templ.size().height && _img.size().width <= _templ.size().width

aiai8976

総合スコア112

OpenCV

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

0グッド

1クリップ

投稿2019/09/10 03:46

編集2019/09/10 05:05

前提・実現したいこと

ラズパイで撮影した画像とテンプレ画像をテンプレートマッチングで比較して対象の図形を抽出しようとしています。
テンプレートマッチングは以下のサイトを参考にしています。
https://dronebiz.net/tech/opencv/matching
自分で撮影した画像を二値化して上のサイトと同じようにテンプレートマッチングで比較しようとした時にエラーが発生しました。

  • テンプレ画像のサイズ(171*151)
  • 上記のサイトと同じようにして成功した時の比較画像(1215*685)
  • 今回撮影した画像(3280*2464)

画像サイズの関係がよくわかりません。
何か解決策がありましたら、コメントお願いします。

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

このサイトのエラーと同じで、テンプレ画像のサイズを変更するとできたそうですが、エラーは消えませんでした。
https://www.oipapio.com/question-8578272

error: (-215) _img.size().height <= _templ.size().height && _img.size().width <= _templ.size().width

該当のソースコード

テンプレートマッチング

#!/usr/bin/env python # -*- coding: utf-8 -*- import cv2 import numpy as np import random import sys if __name__ == '__main__': # 対象画像を指定 base_image_path = './sample.png' temp_image_path = './base.png' # 画像をグレースケールで読み込み gray_base_src = cv2.imread(base_image_path, cv2.IMREAD_GRAYSCALE) gray_temp_src = cv2.imread(temp_image_path, cv2.IMREAD_GRAYSCALE) # ラベリング処理 label = cv2.connectedComponentsWithStats(gray_base_src) n = label[0] - 1 data = np.delete(label[2], 0, 0) # マッチング結果書き出し準備 color_src = cv2.cvtColor(gray_base_src, cv2.COLOR_GRAY2BGR) height, width = gray_temp_src.shape[:2] # ラベリング情報を利用して各オブジェクトごとのマッチング結果を画面に表示 for i in range(n): # 各オブジェクトの外接矩形を赤枠で表示 x0 = data[i][0] y0 = data[i][1] x1 = data[i][0] + data[i][2] y1 = data[i][1] + data[i][3] print(data[i][3]) print(data[i][2]) cv2.rectangle(color_src, (x0, y0), (x1, y1), (0, 0, 255)) # 各オブジェクトごとの類似度を求める if(i==4): x2 = x0 - 5 -25 y2 = y0 - 5 -29 x3 = x0 + width + 5 +25 y3 = y0 + height + 5 +29 crop_src = gray_base_src[y2:y3, x2:x3] cv2.imshow("",crop_src) else: x2 = x0 - 5 y2 = y0 - 5 x3 = x0 + width + 5 y3 = y0 + height + 5 crop_src = gray_base_src[y2:y3, x2:x3] #cv2.imshow("",crop_src) c_height, c_width = crop_src.shape[:2] res = cv2.matchTemplate(crop_src, gray_temp_src, cv2.TM_CCOEFF_NORMED) res_num = cv2.minMaxLoc(res)[1] cv2.putText(color_src, str(i + 1) + ") " +str(round(res_num, 3)), (x0, y1 + 15), cv2.FONT_HERSHEY_PLAIN, 1, (0, 255, 255)) # 結果の表示 cv2.imshow("color_src", color_src) cv2.waitKey(0) cv2.destroyAllWindows()

二値化

import cv2 import numpy as np if __name__ == '__main__': temp_image_path = './image_1.jpg' gray_temp_src = cv2.imread(temp_image_path, cv2.IMREAD_GRAYSCALE) ret,img_thresh = cv2.threshold(gray_temp_src, 70, 255, cv2.THRESH_BINARY_INV) height,width = img_thresh.shape[:2] img_thresh = cv2.resize(img_thresh, dsize=None, fx=0.2, fy=0.2) cv2.imshow("img_thresh", img_thresh) cv2.waitKey() cv2.destroyAllWindows()

試したこと

以下のプログラムを追加

print(crop_src.shape, gray_temp_src.shape)

出力

36 (161, 187)(151,177) (149,187)(151, 177) 以下同様のエラー

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

openCV(3.4.4)

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

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

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

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

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

guest

回答1

0

error: (-215) _img.size().height <= _templ.size().height && _img.size().width <= _templ.size().width

テンプレート画像が入力画像より大きいというエラーです。

res = cv2.matchTemplate(crop_src, gray_temp_src, cv2.TM_CCOEFF_NORMED)

の直前で

print(crop_src.shape, gray_temp_src.shape)

で形状を確認し、入力画像 crop_src の幅及び高さがテンプレート画像 gray_temp_src の幅及び高さ以上であることを確認してください。

投稿2019/09/10 03:54

tiitoi

総合スコア21956

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

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

aiai8976

2019/09/10 05:06

コメントありがとうございます。 追加しましたので確認お願いします。 二番目の比較でテンプレ画像の幅の方が大きくなっていました。
tiitoi

2019/09/10 05:13

テンプレートマッチングは検出対象画像上でテンプレート画像を少しずつ動かしながら、マッチする場所を探すアルゴリズムなので、テンプレート画像のほうが大きい場合、実行できません。 下記にテンプレートマッチングの仕組みについて解説があります。 http://pynote.hatenablog.com/entry/opencv-template-matching
tiitoi

2019/09/10 05:17 編集

テンプレートマッチングが使える場合は、検出したい対象物 (テンプレート画像) が入力画像の一部にあるとして、以下の仮定が成り立つ場合のみ利用できます。 検出対象物が写っている場合、全体が写っている事 大きさ、角度がテンプレート画像と同じである事 これらの仮定が成り立たない場合はテンプレートマッチングは利用できません。
aiai8976

2019/09/10 05:26

なぜこのようなことが起きるのかよくわかりません。 (x2:x3,y2:y3)はテンプレ画像よりも10大きい幅を持たせているのに149となっているのはどうしてでしょうか。
tiitoi

2019/09/10 05:48 編集

> (x2:x3,y2:y3)はテンプレ画像よりも10大きい幅を持たせている gray_base_src[y2:y3, x2:x3] とクロップしたとき、クロップ後の幅 w 及び高さ h は w = x3 - x2 h = y3 - y2 print(w, h) です。 この値がテンプレート画像の幅 177、高さ 151 以上でなければならないので、そうなっていないということは「(x2:x3,y2:y3)はテンプレ画像よりも10大きい幅を持たせている」というのが実際はそうなっていないことを意味しています。
tiitoi

2019/09/10 05:54

コードの他の部分を拝見しましたが、入力画像の切り抜きは connectedComponentsWithStats の結果に依存しているため、テンプレート画像より必ず大きいということが保証できないような気がします。
aiai8976

2019/09/10 05:57

なるほど。 それではテンプレ画像よりも高さか幅のどちらかが小さい場合は次のループに回るという処理はできますか?
tiitoi

2019/09/10 06:01

matchTemplate の直前に以下の if 文を入れるとできると思います。 # 入力画像の高さ < テンプレート画像の高さ または 入力画像の幅 < テンプレート画像の幅 の場合 if crop_src.shape[0] < gray_temp_src.shape[0] or crop_src.shape[1] < gray_temp_src.shape[1]: continue
aiai8976

2019/09/10 06:08

ありがとうございます! やってみます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問