[OpenCV] 02-4. Mouse as a Paint-Brush
🐍Python/OpenCV

[OpenCV] 02-4. Mouse as a Paint-Brush

728x90
반응형

<2-4. Mouse as a Paint-Brush>


OpenCV에서의 마우스 이벤트 다루는 법을 배울 것이다.

  • cv2.setMouseCallback() 을 배워 볼 것이다.

Simple Demo

더블 클릭하면 이미지 위에 원이 생기는 간단한 기능을 만들어보자.

먼저, 마우스 이벤트가 발생할 때, 마우스 callback 기능을 만든다. 마우스 이벤트는 좌버튼 아래로, 좌버튼 위로, 좌 버튼 더블 클릭등으로 마우스와 관련된 것이면 된다. 모든 마우스 이벤트에 대해 좌표 (x,y)를 주는 것이다. 이 이벤트와 위치를 가지고, 원하는 모든 것을 할 수 있다. 모든 이벤트를 나열하려면 다음 코드를 실행하면 된다.

import cv2
events = [i for i in dir(cv2) if 'EVENT' in i]
print(events)

위 코드를 실행한 결과는 다음과 같다.

[‘EVENT_FLAG_ALTKEY’, ‘EVENT_FLAG_CTRLKEY’, ‘EVENT_FLAG_LBUTTON’, ‘EVENT_FLAG_MBUTTON’, ‘EVENT_FLAG_RBUTTON’, ‘EVENT_FLAG_SHIFTKEY’, ‘EVENT_LBUTTONDBLCLK’, ‘EVENT_LBUTTONDOWN’, ‘EVENT_LBUTTONUP’, ‘EVENT_MBUTTONDBLCLK’, ‘EVENT_MBUTTONDOWN’, ‘EVENT_MBUTTONUP’, ‘EVENT_MOUSEHWHEEL’, ‘EVENT_MOUSEMOVE’, ‘EVENT_MOUSEWHEEL’, ‘EVENT_RBUTTONDBLCLK’, ‘EVENT_RBUTTONDOWN’, ‘EVENT_RBUTTONUP’]

마우스 callback 기능 생성시 어디에서나 동일한 특정 형식이 있다. 어떤 기능을 하는지만이 차이점이다. 우리의 마우스 callback 기능은 더블 클릭 한 곳에 원을 그리는 그 한가지 일을 한다. 아래 코드를 보자.

# Mouse Callback Function
def draw_circle(event,x,y,flags,param):
    if event == cv2.EVENT_LBUTTONDBLCLK:
        cv2.circle(img,(x,y),100,(255,0,0),-1)


# 검정 이미지 생성
img = np.zeros((512,512,3),np.uint8)
cv2.namedWindow('image')
cv2.setMouseCallback('image',draw_circle)

while(1):
    cv2.imshow('image',img)
    if cv2.waitKey(20) & 0xFF == 27:
        break
cv2.destroyAllWindows()


더블 클릭하면 원이 생기는 것을 볼 수 있다.


More Advanced Demo

더 좋은 기능을 만들어 볼 것이다. 그림 그리는 기능처럼 마우스를 드래그해서 도형을 그려볼 것이다. 그래서 우리의 마우스 callback 기능은 두 가지로, 하나는 직사각형을 그리고, 다른 하나는 원을 그리는 것이다. 이 특정 예제는 트래킹이나 image segmentation과 같은 것을 이해하고 만드는데 큰 도움이 될 것이다.

# True이면 마우스가 눌렸을 때이다. 
drawing = False
# True 이면 직사각형을 그린다. 'm'을 누르면 곡선으로 전환된다. 
mode = True
ux, iy = -1, -1

# Mouse Callback Function
def draw_circle(event,x,y,flags,param):
    global ix, iy, drawing, mode

    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        ix, iy = x,y

    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing == True:
            if mode == True:
                cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
            else:
                cv2.circle(img,(x,y),5,(0,0,255),-1)

그 다음으로 마우스 callback 기능을 OpenCV 창에 합쳐야한다. 메인 루프는, 키보드 ‘m’에 대한 키보드 바인딩을 설정하여 직사각형과 원을 전환해야 한다.

img = np.zeros((512,512,3),np.uint8)
cv2.namedWindow('image')
cv2.setMouseCallback('image',draw_circle)

while(1):
    cv2.imshow('image',img)
    k = cv2.waitKey(1) & 0xFF
    if k == ord('m'):
        mode = not mode
    elif k == 27:
        break

cv2.destroyAllWindows()


728x90
반응형