質問: img[mark_area['top_y']:mark_area['bottom_y'],mark_area['top_x']:mark_area['bottom_x']] cv2.imwrite('res.png',img) ``` ### 試したこと 範囲を指定し、切り取る行を書き込まなければ、指定した画像をそのままグレースケールし、切り出しシンボルが認識されているようなレスポンスは受け取れました。 ### 補足情報(FW/ツールのバージョンなど) ![イメージ説明](https://teratail-v2.storage.googleapis.com/uploads/contributed_images/5b00185a1805a72ee1bc427bb3da36a7.jpeg)![イメージ説明](https://teratail-v2.storage.googleapis.com/uploads/contributed_images/c2f2aa4e66eb2862146967bdd46176db.jpeg)
回答: テンプレートマッチングの仕組み上、姿形は同じでもスケールが異なるとマッチングできません。 OpenCV - テンプレートマッチングの仕組み及び方法について 今回の場合、検出したいテンプレート画像 marker.jpg と検出対象画像 sample.jpg に写っているマークの大きさが一致していません。 スケールをあわせるための処理が書いてあるようですが、これを行っても大きさが合っていないため、そのあとのテンプレートマッチングで失敗しています。 この dpi の値はどのように求めたものなのでしょうか? ``` marker_dpi = 72 # 画面解像度(マーカーサイズ) scan_dpi = 300 # スキャン画像の解像度 w, h = marker.shape::-1] marker = cv2.resize(marker, (int(h*scan_dpi/marker_dpi), int(w*scan_dpi/marker_dpi))) ``` > > locの内容はどのようにして確認できますか? > > > 「loc を print して確認してください」といったのは、もしテンプレートマッチングに成功していれば、loc になんらかの値が入っているからです。 実際に loc を print して出力を確認してみると、以下のように空の配列になっていることがわかり、よってテンプレートマッチングに失敗していると判断できます。 ``` print(locs) # (array([], dtype=int64), array([], dtype=int64)) ``` 追記 ``` import cv2 import numpy as np template = cv2.imread("marker.jpg", cv2.IMREAD_GRAYSCALE) # テンプレート画像 img = cv2.imread("sample.jpg", cv2.IMREAD_GRAYSCALE) # 検出対象画像 # テンプレートマッチングを行う。 ret = cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED) # 類似度が閾値以上の箇所を調べる。 threshold = 0.8 tl_Y, tl_X = np.where(ret >= threshold) h, w = template.shape[:2] # テンプレート画像の大きさ br_X, br_Y = tl_X + w, tl_Y + h # 検出枠の右下の座標 # すべての検出箇所の外接矩形で切り出す。 cropped = img[tl_X.min() : br_Y.max(), tl_X.min() : br_X.max()] # 切り出した画像を保存する。 cv2.imwrite("results.png", cropped) ``` ![イメージ説明 検出に使用したテンプレート画像 !イメージ説明 切り出し結果