マウスクリックからの座標取得
前回でチェスボードの認識と座標情報の取得ができましたので、次はマウスによる物体の頂点のマーキングと抽出です。
以下に、頂点を7点マーキングして各頂点の座標を出力するプログラムを示します。
マウスが移動した際に座標も変化するため、x線とy線を更新しています。
detect_corner_obj.py import numpy as np import cv2 import csv class PointList(): def __init__(self, npoints): self.npoints = npoints self.ptlist = np.empty((npoints, 2), dtype=int) self.pos = 0 def add(self, x, y): if self.pos < self.npoints: self.ptlist[self.pos, :] = [x, y] self.pos += 1 return self.pos def onMouse(event, x, y, flag, params): wname, img, ptlist, img_name = params if event == cv2.EVENT_MOUSEMOVE: # マウスが移動したときにx線とy線を更新する img2 = np.copy(img) h, w = img2.shape[0], img2.shape[1] cv2.line(img2, (x, 0), (x, h - 1), (255, 0, 0)) cv2.line(img2, (0, y), (w - 1, y), (255, 0, 0)) cv2.imshow(wname, img2) if event == cv2.EVENT_LBUTTONDOWN: # レフトボタンをクリックしたとき、ptlist配列にx,y座標を格納する if ptlist.add(x, y) <= ptlist.npoints: print('[%d] ( %d, %d )' % (ptlist.pos - 1, x, y)) cv2.circle(img, (x, y), 3, (0, 0, 255), 3) cv2.imshow(wname, img) if ptlist.pos >= ptlist.npoints: print('All points have selected. Press ESC-key.') if(ptlist.pos == ptlist.npoints): with open(img_name[0:8]+'_corner_dot_obj.csv', 'w', newline="") as f: writer = csv.writer(f) writer.writerows(ptlist.ptlist) if __name__ == '__main__': img_name = "IMG_7124.jpg" img = cv2.imread(img_name) wname = "MouseEvent" cv2.namedWindow(wname, cv2.WINDOW_NORMAL) npoints = 7 ptlist = PointList(npoints) cv2.setMouseCallback(wname, onMouse, [wname, img, ptlist, img_name]) cv2.imshow(wname, img) cv2.waitKey() cv2.destroyAllWindows()
次回の予定
- チェスボードの座標とマウスクリックからの座標の統合と相対付
- 体積算出
1について、チェスボードからピクセルと実世界の距離を一致させる必要があります。
実際、出力されている行列には規則性のある頂点座標の格納の仕方があり、これを点間距離に変換しなければなりません。
この変換を次回から実施していきます。