要約
cv2かmatplotlibで画像を表示して、2点クリックするごとに線を引いて、その結果の線分のリストを得たかった。
グローバル変数を使いたくなかったので苦労した.
今回はcv2で書いたがmatplotlibでCallBack関数を使用する際もおそらく同じ
画像はQを押すと閉じれます。
関数名にバリバリ日本語を使っているが後で自分が見やすいようにこうしています。
英語で書いてもわかりやすい関数名などつけられないので許して
環境
jupyter notebook
Python 3.6.0 on win32
コード
#画像をQで閉じる
import numpy as np
import cv2
import matplotlib as plt
class mouse_event_handler:
def __init__(self):
self.points = []
def mouse_event(self, event, x, y, flags, param, img):
if event == cv2.EVENT_LBUTTONUP:
self.points += [[x,y]]
line_number, buf = divmod(len(self.points),2)
is_even = (buf == 0)
if is_even:
p1 = self.points[(line_number-1)*2]
p2 = self.points[(line_number-1)*2+1]
cv2.line(img,p1,p2,(255,0,0),3)
def 画像を表示してクリックで線を引いた結果のリストを受け取る関数(img):
m = mouse_event_handler()
cv2.imshow('img',img)
cv2.namedWindow("img", cv2.WINDOW_NORMAL)
cv2.setMouseCallback ("img", \
lambda event, x, y, flags, param: \
m.mouse_event(event, x, y, flags, param, img))
#event, x, y, flags, paramはcv2で定義されているもの
#クリックされた際にコールバック関数としてm.mouse_evnetが呼び出されるがその際に渡される5つの引数
#(正確にはm.mouse_eventではなくlambda関数)
#引数imgは参考サイト通りに設定した
while (True):
cv2.imshow("img", dummy_img)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
cv2.destroyAllWindows()
return m.points
dummy_img = 255*np.ones((1000,1000,3))
print(画像を表示してクリックで線を引いた結果のリストを受け取る関数(dummy_img))
参考
PythonとOpenCVで画像処理④【マウスイベント】
(stack over flow) Returning values from callback(s) in Python
Pythonでcallbackに引数を使う方法と注意点