質問: Core.minMaxLoc(resultMat); if (mmlr.maxVal > 0.1) { println("Val: " + mmlr.maxVal); stroke(255, 0, 0); strokeWeight(3); noFill(); rect((int)mmlr.maxLoc.x + 100, (int)mmlr.maxLoc.y, templateMat.cols(), templateMat.rows()); } ``` ### 参考動画 1 2
回答: テンプレートマッチングが使える条件 * 検出対象の大きさが固定 * 検出対象が回転していない > > また、テンプレートマッチングだと認識できる位置が、テンプレート画像内での位置になってしまうかと思うのですがいかがでしょうか。。。 > > > 元画像の座標系での位置で検出できます。 テンプレートマッチングの仕組み 模様が形状で判断できる場合 findContours() で輪郭を抽出する方法がよいと思います。 追記 輪郭抽出ベースだと以下のような感じになります。 形状が丸、四角、三角、円など単純な形であれば、輪郭抽出ベースのやり方をおすすめします。 !イメージ説明 ``` import cv2 import matplotlib.pyplot as plt import numpy as np # 画像を読み込む。 img = cv2.imread('sample.png') img = cv2.flip(img, 1) # 輪郭抽出する。 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) _, contours, _ = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 輪郭を近似する。 approx_contours = ] for cnt in contours: # 輪郭の周囲の長さを計算する。 arclen = cv2.arcLength(cnt, True) # 輪郭を近似する。 approx_cnt = cv2.approxPolyDP(cnt, epsilon=0.005 * arclen, closed=True) approx_contours.append(approx_cnt) # 判定する。 for cnt in approx_contours: num_points = len(cnt) cv2.drawContours(img, [cnt], -1, (0, 0, 255), 3) if num_points == 3: cv2.drawContours(img, [cnt], -1, (255, 0, 0), 3) print('三角形') elif num_points == 4: cv2.drawContours(img, [cnt], -1, (0, 255, 0), 3) print('四角形') else: cv2.drawContours(img, [cnt], -1, (0, 255, 255), 3) print('その他') # 画像を表示する。 fig, axes = plt.subplots(figsize=(6, 6)) axes.imshow(img) axes.axis('off') plt.show() ``` ![イメージ説明 結果 三角形が赤 四角形が緑 それ以外が水色 で検出されています。位置ももちろん、取得できます。 追記 ``` import cv2 device_id = 0 cap = cv2.VideoCapture(device_id) while True: # 1フレームずつ取得する。 ret, frame = cap.read() if not ret: break # 映像取得に失敗 result = detect(frame) # フレームから図形を検出する。 # 検出結果を使ってなにかする。 cv2.imshow('Frame', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break # q キーを押したら終了する。 cap.release() cv2.destroyAllWindows() ```