ブログ名

【第4回】簡易体積算出アルゴリズム 幾何学的算出での実装2

マウスクリックからの座標取得

前回でチェスボードの認識と座標情報の取得ができましたので、次はマウスによる物体の頂点のマーキングと抽出です。
以下に、頂点を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. チェスボードの座標とマウスクリックからの座標の統合と相対付
  2. 体積算出

1について、チェスボードからピクセルと実世界の距離を一致させる必要があります。
実際、出力されている行列には規則性のある頂点座標の格納の仕方があり、これを点間距離に変換しなければなりません。
この変換を次回から実施していきます。


次の記事へ

前の記事へ 戻る