Macでマウスを使ってimage上に矩形領域を描画する(2021.7.7)

Summary

Macでマウスを使って矩形領域を指定して画面キャプチャする(2021.7.7)のはできるようになったので、今回は静止画像を表示し、その上にマウスを使って矩形領域を指定して、その領域だけをキャプチャする。

cv2.setMouseCallback()でマウスイベントを取得して描画

マウスイベントの取得

マウスイベントの取得の方法は、基本的にMacでマウスを使って矩形領域を指定して画面キャプチャする(2021.7.7)と同じで、call back関数を定義し、その関数でevent, x, y, flags, paramを引数として受け取るようにする。

cv2.namedWindow('Type [q] to quit capturing')
cv2.setMouseCallback('Type [q] to quit capturing', draw_circle)

cv2.namedWindow()で設定した名前の文字列と同一文字列で対象のwindowを特定できるようにしてcall back関数を指定する。
この対応が誤っていると、

 (-27:Null pointer) NULL window handler in function 'cvSetMouseCallback'.

などとおこられます。

### 表示した画像にマウス操作でインポーズ描画する

whileループ中で、毎回元画像からコピーして再描画することで軌跡を消去する。
draw_circleの中では、クリックイベントが発生するごとにポジションをpt0に保存する。
一度マウスがクリックされたなら、画面内のどこか(最新のpt0の場所)に赤丸を書き続ける。

def draw_circle(event, x, y, flags, param):
    global circle_clicked, pt0
    print(x, y, event, flags, param, cv2.EVENT_LBUTTONDOWN, circle_clicked)
    if event == cv2.EVENT_LBUTTONDOWN:
        print("Draw!!! (%d, %d), %s" % (x, y, circle_clicked))
        # pt0 shall be updeted for every Left click
        pt0 = (x, y)
        if circle_clicked == False:
            circle_clicked = True
           
while True:
    # Clear image for drowing new cirle and rectancle
    frame = image.copy()

    if topLeft_clicked == True and botRight_clicked == False:
        cv2.rectangle(frame, pt1, pt2, (0, 255, 0), 1)
        cv2.circle(frame, center=pt1, radius=5, color=(0,0,255), thickness=-1)
    elif topLeft_clicked == True and botRight_clicked == True:
        cv2.rectangle(frame, pt1, pt2, (0, 0, 255), 2)

    # show the frame
    cv2.imshow('Type [q] to quit capturing', frame)

マウスクリックで矩形領域を指定する

マウスで左上と右下の座標を取得し長方形をインポーズ描画する

カメラ画像の取得したい矩形領域の左上と右下の2点でマウス左クリックすると、領域を選択できる。その状態でsキーを押すと領域を切り出して画像として保存する。
選択された領域と切り出された画像が一致していないのは、キーを押す操作をしているあいだに手持ちの被写体がずれているからです。