파이썬(Python)/opencv

[Python]OpenCV 마우스 이벤트/클릭(Mouse Event, Click) 콜백함수

끄적끄적아무거나 2022. 3. 30. 11:59
반응형

 

목차

     

     

    파이썬 마우스 클릭시 함수 구현

     

    파이썬 OpenCV에서 이미지를 띄워 놓고 마우스 클릭 시 특정 함수가 동작되게 하기 위해서는 콜백 함수를 사용해야 합니다. 콜백 함수는 이벤트(Event)가 발생할 시 특정 함수를 시행하는 함수 입니다.

     

    간단히 설명을 드리면 파이썬(Python) 함수는 라인 별로 구현을 하고 완료 합니다. 하지만 마우스 입력(Mouse Click)이나

    키보드 입력(Keyboard input)시에 어떤 동작을 구현하길 원한다면 누군가는 코드가 진행되는 와중에도 event가 발생하는 지 모니터링(Monitoring)하고 있어야 합니다. 그리고 이벤트 발생 시 특정 동작을 이행하는데 이것이 콜백 함수의 역할 입니다. 

     

    아래는 OpenCV 라이브러리에서 마우스(Mouse) 이벤트 발생 시 필요한 함수 입니다.

     

    cv2.setMouseCallback(타이틀명, 콜백함수)

     

    위에 setMouseCallback 함수를 시행하여서 마우스 이벤트가 발생하면 입력 인자의 콜백함수를 실행해 줍니다. 타이틀 명은 window 창의 타이틀 명으로 imread에 읽은 타이틀명과 일치해야 합니다. 그렇지 않으면 에러가 발생합니다.

     

    콜백 함수는 아래와 같이 별도로 지정합니다.

    def 콜백함수명(event, x, y, flags, param):
    	구현할 코드

     

     

    입력 값에 event는 어떤 이벤트가 왔는지를 전달해줍니다. 이번 포스트는 마우스에 대한 내용이므로 왼쪽 버튼을 클릭했는지 오른쪽 버튼을 클릭 했는지 마우스 휠(Mouse wheel)을 사용했는지에 대한 이벤트 정보가 들어 있습니다. 

     

    x,y는 이벤트가 발생했을 때의 좌표(Cooridnate) 정보입니다. flags, param은 실제 사용할 일이 없어 생략 합니다. 하지만 빈칸으로 놔두면 argument 에러가 발생하므로 위치럼 채워만 놓습니다.

     

    마우스 이벤트 종류에 대해 아래와 같이 간략하게 정리 하였습니다. event 명을 입력하여도 되고 명이 의미하는 숫자를 넣어도 구현 됩니다.

     

    • cv::EVENT_MOUSEMOVE = 0 : 윈도우창 위에 마우스 올릴 시
    • cv::EVENT_LBUTTONDOWN = 1 :왼쪽 버튼 클릭
    • cv::EVENT_RBUTTONDOWN = 2 :오른쪽 버튼 클릭
    • cv::EVENT_MBUTTONDOWN = 3 :가운데 버튼 클릭
    • cv::EVENT_LBUTTONUP = 4 :왼쪽 버튼 클릭 후 땔 때
    • cv::EVENT_RBUTTONUP = 5 :오른쪽 버튼 클릭 후 땔 때
    • cv::EVENT_MBUTTONUP = 6 :가운데 버튼 클릭 후 땔 때
    • cv::EVENT_LBUTTONDBLCLK = 7 : 왼쪽 더블 클릭
    • cv::EVENT_RBUTTONDBLCLK = 8 : 오른쪽 더블 클릭
    • cv::EVENT_MBUTTONDBLCLK = 9 : 가운데 더블 클릭
    • cv::EVENT_MOUSEWHEEL = 10 :상하 휠 사용
    • cv::EVENT_MOUSEHWHEEL = 11 :좌우 휠 사용

     

    아래 예제 코드를 보시면 쉽게 이해할 수 있습니다.

     

     

     

     

    파이썬 마우스 클릭 시 콜백 함수 시행 예제

     

    이번 Example에서는 마우스 왼쪽 클릭 시 빈 하얀색 윈도우 창에 동그라미(Circle)을 그리고 마우스 오른쪽 클릭 시 동그라미를 삭제 / 지우는 예제 실습입니다.

     

    예제 코드>>

    import cv2
    import numpy as np
    
    img = np.full((800, 800, 3), 255, dtype=np.uint8)
    
    cv2.imshow("blank", img)
    
    def mouse_click(event, x, y, flags, param):
        global img
        
        if event == cv2.EVENT_FLAG_LBUTTON:    
            cv2.circle(img, (x, y), 5, (0, 0, 255), 2)
            cv2.imshow("blank", img)
        elif event == cv2.EVENT_FLAG_RBUTTON:   
            img = np.full((800, 800, 3), 255, dtype=np.uint8) 
            cv2.imshow("blank", img)
    
    cv2.setMouseCallback("blank", mouse_click)
    
    while True:
        if cv2.waitKey(0):
            break
    
    cv2.destroyAllWindows()

    4번 라인: numpy 함수 full을 사용해서 800 x 800 픽셀(Pixel) 윈도우에 255로 채워서 흰색 바탕을 만듭니다. 픽셀 이미지에 대한 내용은 괄호 링크를 참조 하십시오(https://scribblinganything.tistory.com/493)

    6번 라인: imread를 사용해서 빈 흰색 윈도우창을 띄웁니다.

    8~16번 라인: 콜백 함수로 마우스 이벤트(Event) 발생 시 실행합니다.

    11~13번 라인: 마우스 왼쪽 클릭 시 원을 그리는 코드를 구현합니다.

    14~16번 라인: 마우스 오른쪽 클릭 시 원을 삭제합니다.

    18번 라인: setMouseCallback 함수를 구현해서 마우스 동작을 감시 합니다.

    20번~22번 라인: 키보드 입력을 무한정 대기하면서 아무 값이나 입력되면 while 문을 벗어납니다.

     

     

    결과>>

    마우스 왼쪽 클릭 시

     

    마우스 오른쪽 클릭 시

     

     

    반응형