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

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

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

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

Python

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

Q&A

解決済

1回答

5891閲覧

ノイズやスケール変換に頑健な画像のテンプレートマッチングに関して

Moririn_1881

総合スコア18

OpenCV

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

Python

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

0グッド

0クリップ

投稿2020/10/21 16:14

編集2020/10/22 08:19

上のイラストやの画像(上)から、その画像一部(下)の位置を探すタスクに取り組んでいます。

イメージ説明
イメージ説明

このページを参考にタスクに取り組み、元画像もテンプレート画像もpngの時にはうまくいくことを確認しました。

Python

1import cv2 2import numpy as np 3from matplotlib import pyplot as plt 4 5img = cv2.imread('cat.png') 6template = cv2.imread('cat_face.png') 7_, w, h = template.shape[::-1] 8 9res = cv2.matchTemplate(img,template,cv2.TM_CCOEFF_NORMED) 10min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) 11top_left = max_loc 12btm_right = (top_left[0] + w, top_left[1] + h) 13 14cv2.rectangle(img,top_left, btm_right, 255, 2) 15 16cv2.imshow("test", img) 17cv2.waitKey(0) 18cv2.destroyAllWindows()

しかしながら、テンプレート画像の大きさが変わったり、jpgにして圧縮ノイズが入るとうまく動いてくれないときがあります。
(ノイズに関してはイラストやの画像ではOKでしたが、参考ページの猫ではうまくいきませんでした)
「テンプレートマッチング スケール」などと調べても有効そうな情報が得られず、困っております。

なお想定としては、
・スケール変換はおよそ50%~200%
・ノイズはpng→jpg変換で生ずる程度のもの

と考えております。
どのように解決すればよろしいか、お教えしてくださると助かります。

追記(POCの実装)

位相限定相関法を実装した結果、ノイズに対しては十分に耐性を持っていることが確認できました。ありがとうございます。
下に実装コードを示します。

Python

1import cv2 2import numpy as np 3 4from matplotlib import pyplot as plt 5import matplotlib.patches as patches 6 7img = cv2.imread("ai/ai.png", 0) # 元画像 8template = cv2.imread("ai/ai_part_x92.png", 0) # マッチング対象のテンプレート画像 9im_h, im_w = img.shape # 元画像のサイズ取得 10temp_h, temp_w = template.shape # テンプレート画像のサイズ取得 11 12template = cv2.copyMakeBorder( 13 template, 14 0, 15 im_h - temp_h, 16 0, 17 im_w - temp_w, 18 cv2.BORDER_CONSTANT, 19 (0, 0, 0), 20) # POCができるようにテンプレート画像をパディング 21 22shift, theta_shift = cv2.phaseCorrelate( 23 template.astype(np.float32), img.astype(np.float32) 24) # POCでシフト量を取得 25 26rect = patches.Rectangle( 27 xy=(shift), width=temp_w, height=temp_h, ec="b", fill=False 28) # テンプレートと一致する部分を四角形で表示 29 30# 図示 31plt.subplot(121), plt.imshow(img, cmap="gray") 32plt.subplot(121).add_patch(rect) 33plt.title("Input Image"), plt.xticks([]), plt.yticks([]) 34plt.subplot(122), plt.imshow(template, cmap="gray") 35plt.title("Template Image (92%)"), plt.xticks([]), plt.yticks([]) 36plt.show() 37 38print(shift) # 最後にシフト量を表示

イメージ説明

問題点

しかしながら、スケーリングの問題に関しては92%ほど縮小したテンプレート画像に対して、下のような出力になってしまい、いわば元画像の左上とパディングされたテンプレート画像の右下が一致してしまっております。

Python

1>> print(shift) 2# (-198.66021205773234, -197.0159913577939)

下はテンプレート画像を92%に縮小したものです。
テンプレート画像を92%に縮小したもの

負の値となり、矩形はグラフ外に出て不可視となっています。
イメージ説明

位相限定相関法とか,スケール自体も探索対象となっているような方法

と伺っていて、多少縮小したものでもうまくいくと思っておりましたが、パディングしたのが悪かったのでしょうか。
cv2.copyMakeBorder()において、二つの画像が同じサイズである必要があるので、パディングさせていただきました。何か良い対処法がございましたらお教えしてくださると助かります。

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

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

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

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

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

fana

2020/10/22 01:13

> テンプレート画像の大きさが変わったり、jpgにして圧縮ノイズが入ると こういう事柄の程度次第の話になるように思います. (具体例に対してその例に即した内容の話を(誰かが)展開することはできるかもしれませんが 程度が未知の「全般的な」話というのは困難ではないだろうか? と.)
Moririn_1881

2020/10/22 06:35

ご質問ありがとうございます。 今回想定しているスケール変換はおよそ50%~200%、ノイズはpng→jpg変換で生ずる程度のものを想定しております。 しかしながら、fana様の位相限定相関法で処理が可能そうなので、そちらで対処したく思います。
fana

2020/10/22 07:07

(スケールの方はともかく, その程度のノイズでうまくいかなくなるというのは想像し難いですが…)
Moririn_1881

2020/10/22 08:24

質問を編集させていただきました。 ノイズの方はおかげさまで位相限定相関法で無事うまく行きましたが、スケールの方には対応ができておりません。 お時間があれば目を通していただけると助かります。
fana

2020/10/22 10:19

位相限定相関法は,話としては{並進,回転,スケール}を扱えるハズなのですが, OpenCVの phaseCorrelate() 関数は,リファレンスを見ると "The function is used to detect translational shifts that occur between two images. " としか説明が書かれておらず,結果も並進情報のみになっているみたいです. この関数では並進しか扱っていないのだと思います.
fana

2020/10/23 01:11

> 回転不変位相限定相関(RIPOC) そのような呼び分け(?)があるとは知りませんでした. ("位相限定相関法"という言葉で log-polarな世界で回転とスケールを探す話を含めたやつを指したつもりでした.Sorry.)
Moririn_1881

2020/10/23 15:43

いえいえ、いろいろ相談に乗ってくださり、理解が深まりました ありがとうございます
guest

回答1

0

ベストアンサー

matchTemplate()は,スケールや回転といった変形の無い世界を前提としているので,(状況次第ですが)他の方法を採ることを模索してください.

  • スケール:

強引に画像をいろんなスケールに拡縮してはmatchTemplate()でマッチングしてみるという手も有り得ますが…
●スケール自体を推測できるならば,そのように手当たり次第にスケールを試さずに済む.
●スケール不変な特徴量を用いるなりする.
●位相限定相関法とか,スケール自体も探索対象となっているような方法を探してきて試す

  • ノイズ:

●大したことないなら,「ノイズ除去処理」を前処理として行って対処.
●↑と意味合いが被るが,画像をぼかしてごまかす(低周波成分に重きを置いて比較する).
●画素単位比較ではなく,モーメントとか色ヒストグラムみたいな「画素の集合」から求められる量を使った比較を試みる

投稿2020/10/22 01:31

fana

総合スコア11996

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問