teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

2

画像の説明の追加

2020/10/22 08:19

投稿

Moririn_1881
Moririn_1881

スコア18

title CHANGED
File without changes
body CHANGED
@@ -88,7 +88,10 @@
88
88
  >> print(shift)
89
89
  # (-198.66021205773234, -197.0159913577939)
90
90
  ```
91
+ 下はテンプレート画像を92%に縮小したものです。
91
92
  ![テンプレート画像を92%に縮小したもの](227f03b95803ad5aef31010b78c3d61b.png)
93
+
94
+ 負の値となり、矩形はグラフ外に出て不可視となっています。
92
95
  ![イメージ説明](d62f250685b5b101655e0374a6e691a7.png)
93
96
 
94
97
 

1

実装したコードとその問題点を載せました。

2020/10/22 08:19

投稿

Moririn_1881
Moririn_1881

スコア18

title CHANGED
File without changes
body CHANGED
@@ -29,4 +29,70 @@
29
29
  (ノイズに関してはイラストやの画像ではOKでしたが、[参考ページ](https://bamch0h.hatenablog.com/entry/2020/02/28/015114)の猫ではうまくいきませんでした)
30
30
  「テンプレートマッチング スケール」などと調べても有効そうな情報が得られず、困っております。
31
31
 
32
+ なお想定としては、
33
+ ・スケール変換はおよそ50%~200%
34
+ ・ノイズはpng→jpg変換で生ずる程度のもの
35
+
36
+ と考えております。
32
- どのように解決すればよろしいか、お教えしてくださると助かります。
37
+ どのように解決すればよろしいか、お教えしてくださると助かります。
38
+
39
+ ### **追記(POCの実装)**
40
+ 位相限定相関法を実装した結果、ノイズに対しては十分に耐性を持っていることが確認できました。ありがとうございます。
41
+ 下に実装コードを示します。
42
+
43
+ ```Python
44
+ import cv2
45
+ import numpy as np
46
+
47
+ from matplotlib import pyplot as plt
48
+ import matplotlib.patches as patches
49
+
50
+ img = cv2.imread("ai/ai.png", 0) # 元画像
51
+ template = cv2.imread("ai/ai_part_x92.png", 0) # マッチング対象のテンプレート画像
52
+ im_h, im_w = img.shape # 元画像のサイズ取得
53
+ temp_h, temp_w = template.shape # テンプレート画像のサイズ取得
54
+
55
+ template = cv2.copyMakeBorder(
56
+ template,
57
+ 0,
58
+ im_h - temp_h,
59
+ 0,
60
+ im_w - temp_w,
61
+ cv2.BORDER_CONSTANT,
62
+ (0, 0, 0),
63
+ ) # POCができるようにテンプレート画像をパディング
64
+
65
+ shift, theta_shift = cv2.phaseCorrelate(
66
+ template.astype(np.float32), img.astype(np.float32)
67
+ ) # POCでシフト量を取得
68
+
69
+ rect = patches.Rectangle(
70
+ xy=(shift), width=temp_w, height=temp_h, ec="b", fill=False
71
+ ) # テンプレートと一致する部分を四角形で表示
72
+
73
+ # 図示
74
+ plt.subplot(121), plt.imshow(img, cmap="gray")
75
+ plt.subplot(121).add_patch(rect)
76
+ plt.title("Input Image"), plt.xticks([]), plt.yticks([])
77
+ plt.subplot(122), plt.imshow(template, cmap="gray")
78
+ plt.title("Template Image (92%)"), plt.xticks([]), plt.yticks([])
79
+ plt.show()
80
+
81
+ print(shift) # 最後にシフト量を表示
82
+ ```
83
+ ![イメージ説明](c97943783f0d888d90ce4dc20d66f0b4.png)
84
+ ### 問題点
85
+
86
+ しかしながら、スケーリングの問題に関しては92%ほど縮小したテンプレート画像に対して、下のような出力になってしまい、いわば元画像の左上とパディングされたテンプレート画像の右下が一致してしまっております。
87
+ ```Python
88
+ >> print(shift)
89
+ # (-198.66021205773234, -197.0159913577939)
90
+ ```
91
+ ![テンプレート画像を92%に縮小したもの](227f03b95803ad5aef31010b78c3d61b.png)
92
+ ![イメージ説明](d62f250685b5b101655e0374a6e691a7.png)
93
+
94
+
95
+ >> 位相限定相関法とか,スケール自体も探索対象となっているような方法
96
+
97
+ と伺っていて、多少縮小したものでもうまくいくと思っておりましたが、パディングしたのが悪かったのでしょうか。
98
+ cv2.copyMakeBorder()において、二つの画像が同じサイズである必要があるので、パディングさせていただきました。何か良い対処法がございましたらお教えしてくださると助かります。