Paul's Grit

[OpenCV] OpenCV 마우스 사용 본문

카테고리 없음

[OpenCV] OpenCV 마우스 사용

Paul-K 2023. 8. 29. 18:02

참고: https://opencv-python.readthedocs.io/en/latest/doc/01.imageStart/imageStart.html

 

이미지 다루기 — gramman 0.1 documentation

cv2.imread() 함수를 이용하여 이미지 파일을 읽습니다. 이미지 파일의 경로는 절대/상대경로가 가능합니다. 이미지 읽기의 flag는 3가지가 있습니다. Note 3개의 flag대신에 1, 0, -1을 사용해도 됩니다.

opencv-python.readthedocs.io

 

1. 이미지 보기

cv2.imshow() 함수는 이미지를 사이즈에 맞게 보여준다..

cv2.imshow(title, image)
  • title (str) – 윈도우 창의 Title
  • image (numpy.ndarray) – cv2.imread() 의 return값
c22.imshow('image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • cv2.waitKey() 는 keyboard입력을 대기하는 함수로 0이면 key입력까지 무한대기이며 특정 시간동안 대기하려면 milisecond값을 넣어주면 된다.
  • cv2.destroyAllWindows() 는 화면에 나타난 윈도우를 종료합니다. 일반적으로 위 3개는 같이 사용된다.

 

import cv2
import numpy as np 

img = np.ones((512,512,3), np.uint8)

while True:
    cv2.imshow('my_first_drawing', img)
    
    if cv2.waitKey(10) == 27:
        break

cv2.destroyAllWindows()

위의 코드를 실행하면 아래와 같은 윈도우가 보인다.

while True:
    cv2.imshow('my_first_drawing', img)
    
    if cv2.waitKey(10) == 27:
        break
  • 27은 특수키 ESC의 아스키코드 값이며, ESC를 누르면, 반복문을 탈출하여 cv2.destropyAllWindows()를 실행하여 위도우를 닫는다.
  • 주요 특수키 27(ESC), 13(ENTER), 9(TAB)

 

2. Mouse로 그리기

cv2.setMouseCallback()은 Mouse Event를 확인하고 Callback을 호출하는 함수이다.

cv2.setMouseCallback(windowName, callback, param=None)
  • windowName – windowName
  • callback – callback함수. callback함수에는 (event, x, y, flags, param)가 전달 됨.
  • param – callback함수에 전달되는 Data

 

(1) 화면에 Double-Click을 하면 원이 그려지는 예제

import sys
import cv2
import numpy as np 

img = np.ones((512,512,3), np.uint8)

def draw_circle(event, x, y, flags, param):
    if event == cv2.EVENT_MOUSEWHEEL:
        cv2.circle(img, (x, y), 30, (50, 50, 200), -1)
    elif event == cv2.EVENT_LBUTTONDBLCLK:
        cv2.circle(img, (x, y), 30, (50, 200, 50), -1)

cv2.namedWindow(winname='my_first_drawing')
cv2.setMouseCallback('my_first_drawing', draw_circle, img)

while True:
    cv2.imshow('my_first_drawing', img)
    if cv2.waitKey(10) == 27:
        break

cv2.destroyAllWindows()

 

위의 코드를 실행하면, 마우스 외쪽 클릭할 때마다 cv2.circle()을 실행하여 원을 그린다.

 

 

(2) 마우스를 누른 상태에서 이동시 원 또는 사각형을 그리는

import sys
import cv2
import numpy as np 

oldx = oldy = -1
def on_mouse(event, x, y, flags, param):
    global oldx, oldy

    if event == cv2.EVENT_LBUTTONDOWN:
        oldx, oldy = x, y
        print('EVENT_LBUTTONDOWN: %d, %d' % (x, y))
    
    elif event == cv2.EVENT_LBUTTONUP:
        print('EVENT_LBUTTONUP: %d, %d' % (x, y))
    
    elif event == cv2.EVENT_MOUSEMOVE:
        if flags & cv2.EVENT_FLAG_LBUTTON:
            cv2.line(img, (oldx, oldy), (x, y), (0, 0, 0), 4, cv2.LINE_AA)
            cv2.imshow('image', img)
            oldx, oldy = x, y

img = np.ones((480, 640, 3), dtype=np.uint8) * 255

cv2.namedWindow('image')
cv2.setMouseCallback('image', on_mouse, img)

cv2.imshow('image', img)
while True:
    # cv2.imshow('image', img)
    if cv2.waitKey(10) == 27:
        break

cv2.destroyAllWindows()

 

마우스 이벤트 종류가 cv2.EVENT_LBUTTONDOWN (마우스 왼쪽 버튼이 눌리는 경우)인 경우 현재 마우스 위치 저장

cv2.EVENT_MOUSEMOVE (마우스가 창 위에서 움직이는 경우) & cv2.EVENT_FLAG_LBUTTON (마우스 왼쪽 버튼이 눌려져 있는 경우) 인 상태에서 현재 마우스 위치와 과거 저장된 마우스 위치를 사용하여 cv2.line()으로 직선을 그린다.