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

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

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

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

Q&A

解決済

1回答

4251閲覧

カラー画像でのテンプレートマッチング

bibienvy

総合スコア5

Python

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

0グッド

0クリップ

投稿2020/09/28 08:34

下記サイトでは、元画像とテンプレート画像をグレースケール化してマッチングを行っていました。

「ミッキーをテンプレートマッチングで検出する(python)」

記載されていたコードが以下になります。

#coding:utf-8 import cv2 import numpy as np #画像をグレースケールで読み込む fname_img1='test1.png' fname_img2='test2.png' img = cv2.imread(fname_img1, 0) temp = cv2.imread(fname_img2, 0) #マッチングテンプレートを実行 match_result = cv2.matchTemplate(img, temp, cv2.TM_CCOEFF_NORMED) #類似度の設定(0~1) threshold = 0.9 #検出結果から検出領域の位置を取得 loc=np.where(match_result >= threshold) #検出領域を四角で囲んで保存 w, h = temp.shape[::-1] for top_left in zip(*loc[::-1]): bottom_right = (top_left[0] + w, top_left[1] + h) #保存 result = cv2.imread(fname_img1) #height = img.shape[0] #width = img.shape[1] #result = cv2.resize(img , (int(width*1.0), int(height*1.0))) cv2.rectangle(result,top_left, bottom_right, (255, 0, 0), 10) cv2.imwrite("result.png", result)

この通りにやって確かにテンプレートマッチングはできたのですが、カラー画像でテンプレートマッチングを行いたいと考え
img = cv2.imread(fname_img1, 0)
temp = cv2.imread(fname_img2, 0)
の第二引数である0を1に打ち直し、カラー画像に変えた所、以下のエラーを吐きました。

ValueError Traceback (most recent call last) <ipython-input-15-cc4b51740b5c> in <module>() 22 23 #検出領域を四角で囲んで保存 ---> 24 w, h = temp.shape[::-1] 25 for top_left in zip(*loc[::-1]): 26 bottom_right = (top_left[0] + w, top_left[1] + h) ValueError: too many values to unpack (expected 2)

これはshapeという関数を使用した際に返り値が2つ以上だった為に起きたエラーだと考えています。
一度arrayとして変数として受け取るのが良いと、調べたらわかったのですが、どのようにコードを改良すればよいのかいまいちわからないです。ご教示お願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

カラー画像になったことで、temp.shape が (H, W) から (H, W, C) になったため、w, h = temp.shape[::-1] というタプル展開は数が合わなくてできないというエラーです。
以下のように修正すればいいと思います。

python

1import cv2 2import numpy as np 3 4img = cv2.imread("sample1.jpg") # 入力画像 5temp = cv2.imread("template.jpg") # テンプレート画像 6 7# マッチングテンプレートを実行 8match_result = cv2.matchTemplate(img, temp, cv2.TM_CCOEFF_NORMED) 9 10# 類似度の設定(0~1) 11threshold = 0.9 12 13# 検出結果から検出領域の位置を取得 14loc = np.where(match_result >= threshold) 15 16# 検出領域を四角で囲んで保存 17h, w = temp.shape[:2] 18for y, x in zip(*loc): 19 cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 10) 20 21cv2.imwrite("ret.png", img)

追記

temp.shape[::-1]の[::-1]の意味がよくわからないです。スライスだと考えているのですが合っていますでしょうか?

リストやタプルを逆順にするスライス指定です。

python

1a = (480, 640, 3) 2print(a[::-1]) # (3, 640, 480)

また、[:2]と修正した時に何が変わったのでしょうか?

元のコードだと、temp.shape の値は (H, W) となっていて、w, h = temp.shape[::-1] で逆順にして代入していましたが、カラー画像にしたことで temp.shape の値が (H, W, C) となったことでタプルの要素数が代入先と合わなくなりエラーになっていました。
これを temp.shape[:2] とスライスすることで、(H, W) となり、代入先と数をあわせました。

あと、アスタリスクはlocというタプル内にあるデータをまとめて取得する物と考えていますが合っていますでしょうか?

以下の記事を参照ください。

Python3.xのアスタリスク逆引き - Qiita

投稿2020/09/28 17:20

編集2020/09/29 06:52
tiitoi

総合スコア21956

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

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

bibienvy

2020/09/29 05:22

無事に解決しました!ありがとうございます! ですが、もう一つだけ伺いたいことがあります。 temp.shape[::-1]の[::-1]の意味がよくわからないです。スライスだと考えているのですが合っていますでしょうか? また、[:2]と修正した時に何が変わったのでしょうか? あと、アスタリスクはlocというタプル内にあるデータをまとめて取得する物と考えていますが合っていますでしょうか?
tiitoi

2020/09/29 06:55

追記しました
bibienvy

2020/09/29 07:24

とても分かりやすい説明、本当にありがとうございました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問