【Opencv/Python】マウス操作を詳しく解説する

Pythonでマウスイベントを詳しく解説

こんにちは,けい( Twitter )です.

今回は,PythonでOpencvを使ったマウスイベントについてまとめていきたいと思います.

人工知能K

Opencvってマウス操作も組み込むことができるノカ??

メタエレ

Opencvには標準でマウス操作をプログラムすることができるんだ!

ボクも自分のこと,マウス操作シタイ...

円を描く

サンプルコード

まず,画像上に円を描くコードを解説します.

今回はすべて,この画像を用いることとします.

ちなみに,この画像は中国の大連の動物園で撮った写真です.

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread("ファイル名")

######################
### FUNCTIOM #########
######################
def draw_circle(event, x, y, flags, param):
    if event == cv2.EVENT_LBUTTONDOWN:
        cv2.circle(img,(x,y),20,(0,255,0), 3)
cv2.namedWindow(winname="win1")
cv2.setMouseCallback("win1", draw_circle)


#################################
### SHOWING IMAGE ###############
#################################
while True:
    cv2.imshow("win1", img)
    if cv2.waitKey(10) == 27:
        break
cv2.destroyAllWindows()

結果がこのようになります.5回マウスで左クリックしました.

解説

cv2.imread()には,お好きな画像を選択してください.

def draw_circle(event, x, y, flags, param):
    if event == cv2.EVENT_LBUTTONDOWN:
        cv2.circle(img,(x,y),20,(0,255,0), 3)
cv2.namedWindow(winname="win1")
cv2.setMouseCallback("win1", draw_circle)

上記のコードがマウスイベントを支配しているコードです.

cv2.namedWindowで,ウィンドウをつくっておき,そのウィンドウにsetMouseCallbackでマウスイベントに呼び出すウィンドウと関数を選択します.

呼び出す関数として,draw_circleという関数を作ります.引数としてevent,x,y,flags,paramを与えます.eventはマウスで操作がなされたときの具体的なアクションです.例えば,マウスの左クリックや右クリックなどが該当します.x,yはマウスが操作されたときの座標を表します.

cv2.circleはopencvの関数で,実際的にはこの命令で円を描いています.

while True:以下は,お決まりの流れです.

塗りつぶしの円を描く

今度は,円を塗りつぶしで表示させる方法です.これは,以下の1行のコードに直すだけです.

cv2.circle(img,(x,y),20,(0,255,0), -1)

最後の-1は,線の太さを表すところですが,-1を入れると円の半径を変えずに塗りつぶすことができます.

四角形を描く

サンプルコード

続いて,四角形を描画していきます.

円の描画のときとほとんど同じなので,今回はマウスの他のイベントも入れていきたいと思います.

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread("ファイル名")

######################
### FUNCTIOM #########
######################
w = 5
h = 5

def draw_rectangle(event, x, y, flags, param):
    if event == cv2.EVENT_LBUTTONDOWN:
        cv2.rectangle(img,(x-w,y-h),(x+w,y+h),(255,0,0),thickness=2)
        
    elif event == cv2.EVENT_RBUTTONDOWN:
        cv2.rectangle(img,(x-w,y-h),(x+w,y+h),(0,0,255),thickness=2)

cv2.namedWindow(winname="win1")

cv2.setMouseCallback("win1", draw_rectangle)


#################################
### SHOWING IMAGE ###############
#################################
while True:
    cv2.imshow("win1", img)
    if cv2.waitKey(10) == 27:
        break
cv2.destroyAllWindows()

結果は以下のようになりました.左クリックで青色,右クリックで赤色の四角形を描画できます.

解説

円を描画するときと変化した部分はFUNCTIONの部分です.

今回は,左クリックと右クリックでアクションを起こしたいので,if文でeventの値によって条件分岐します.

cv2.rectangleによって,四角形を描画します.引数は順に,描画するnumpy配列,四角形の左上の座標,四角形の右下の座標,色(b.g.r),thicknessで線の太さを与えています.

先ほどと同様に,thickness=-1とすると,四角形で塗りつぶすことができます.

マウスでドラッグして四角形を描画

ソースコード

続いて,マウスでドラッグした分だけの大きさの四角形を描画していきます.

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread("ファイル名")


######################
### FUNCTIOM #########
######################
drawing = False
ix = -1
iy = -1

def draw_rectangle(event, x, y, flags, param):
    global ix,iy,drawing

    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        ix, iy = x, y
        
    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing == True:
            cv2.rectangle(img,(ix,iy),(x,y),(0,0,255),-1)
            
    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        cv2.rectangle(img,(ix,iy),(x,y),(0,0,255),-1)

cv2.namedWindow(winname="win1")

cv2.setMouseCallback("win1", draw_rectangle)


#################################
### SHOWING IMAGE ###############
#################################
while True:
    cv2.imshow("win1", img)
    if cv2.waitKey(10) == 27:
        break
cv2.destroyAllWindows()

実行結果は以下のようになります.マウスでドラッグして離すと,四角形を描画できます.

解説

変数として,drawing,ix,iyを作ります.

drawingは四角形を描画するか否かを決める変数です.

cv2.EVENT_MOUSEMOVEは,マウスが動いたときに反応するので,ドラッグしてなくても反応します.そこで,左クリックがされたときにTrueにし,左クリックが終わった時にFalseにする変数を作ることで,四角形を描いても良いかを判断します.

ix,iyはクリックがされたときの初期座標を記録する変数です.

まとめ

マウスのイベントについて,何個かまとめてみました.

これからも,学習とアウトプットを継続していきたいと思います.