본문 바로가기

Fields Applied with AI/컴퓨터 비전 Computer Vision

Ⅰ. 컴퓨터 비전 기초 (7. 입력 장치 이벤트)

영상을 처리할 때 키보드나 마우스 등과 같은 입력 장치를 이용하여 특정 영상 처리 동작을 수행할 수 있습니다. 예를 들어 특정 키보드 키를 누르면 영상이 반전된다던지 마우스의 왼쪽 클릭을 하면 클릭한 영상 속 위치의 좌표를 알려주는 등 OpneCV에서 제공하는 다양한 함수들을 이용하여 해당 기능을 구현할 수 있습니다.

 

7-(1) 키보드 이벤트 처리하기

키보드 이벤트는 키보드의 특정 키를 누르는 것을 뜻하며 OpenCV의 waitKey() 함수를 이용하여 키보드의 특정 키를 눌렀을 때 특정 동작을 수행할 수 있도록 만들 수 있습니다.

Upload File

from google.colab import files
upload = files.upload()

Saving cat.bmp to cat.bmp

 

 

Import Library

import sys
import numpy as np
import cv2

 

  • 필요한 라이브러리들을 불러옵니다.

 

 

Print Image 

img = cv2.imread('cat.bmp', cv2.IMREAD_GRAYSCALE)
 
if img is None:
    print('Image load failed!')
    sys.exit()
 
cv2.namedWindow('image')
cv2.imshow('image', img)

 

  • 우선 처리할 영상을 흑백 영상으로 불러오고, 영상 불러오기가 실패했을 경우를 대비한 코드를 작성합니다.
  • img = 'cat.bmp'라는 영상을 흑백 영상으로 불러온 영상.
  • 만약 img의 값이 None이라면 시스템에서 나가게 됩니다.
  • 'image'라고 하는 영상창을 만들고 출력합니다.

 

 

Invert Image

while True:
    keycode = cv2.waitKey()
    if keycode == ord('i') or keycode == ord('I'):
        img = ~img
        cv2.imshow('image', img)
    elif keycode == 27:
        break
 
cv2.destroyAllWindows()

 

  • waitKey() 함수를 이용하여 i를 클릭했을 때 영상이 반전되도록 합니다.
  • 무한 루프를 통해 키보드의 특정 키를 입력받을 대기 상태로 만들어줍니다.
  • keycode = 입력되는 특정 키의 아스키코드값 또는 대기 상태의 값(-1).
  • 만약 keycode의 값이 키보드의 'i' 또는 'I'일 경우 아래의 명령을 수행합니다.
  • ord() 함의 반환값은 () 안의 키의 아스키코드값입니다.
  • img의 영상 데이터를 반전시킵니다.
  • 여기에서 틸다(~)는 0을 1로, 1을 0으로 바꿔주는 비트 연산자입니다.
  • 만약 keycode의 값이 ESC(27)라면 무한루프에서 빠져나옵니다.
  • 무한루프를 빠져나오게 되면 모든 창을 닫습니다.

 

 

 

 

7-(2) 마우스 이벤트 처리하기

마우스 이벤트는 마우스의 다양한 조작을 뜻하며 OpenCV의 setMouseCallback() 함수를 이용하여 마우스의 특정 조작을 했을 때 특정 동작을 수행할 수 있도록 만들 수 있습니다. 여기에서 마우스의 이벤트는 마우스를 움직이거나 왼쪽 클릭, 오른쪽 클릭, 휠 조작 등 다양한 종류가 존재합니다.

Import Library

import sys
import numpy as np
import cv2

 

  • 필요한 라이브러리들을 불러옵니다.

 

 

Create Mouse Callback Function 

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, 255), 4, cv2.LINE_AA)
            cv2.imshow('image', img)
            oldx, oldy = x, y

 

  • 원래 Window 운영체제 환경에서 마우스 이벤트는 발생했으나 기본적으로 무시됩니다. 그래서 마우스 이벤트를 무시하지 않고 처리하기 위해서는 무시됐던 값들을 불러 되돌려 받아야 하는데 이를 콜백 함수라고 합니다.
  • oldx와 oldy는 나중에 마우스가 움직일때 선을 그릴 수 있도록 순간 직선의 시작점을 뜻합니다. 그래서 초기값을 임의의 수인 -1로 설정합니다.
  • on_mouse()라는 이름으로 다음과 같은 인자를 받으며 콜백 함수를 정의합니다.
  • event : 마우스 이벤트. (마우스 조작 종류)
  • x, y : 영상창 위에서 마우스의 위치. (영상창의 제일 왼쪽 위는 0,0)
  • flags : 키보드나 마우스 버튼을 누른 상태의 종류.
  • param : cv2.setMouseCallback() 함수에서 설정한 데이터.
  • 다양한 마우스 이벤트 경우에 해당할 때를 if문을 사용하여 구현합니다. 위 코드에서는 3가지 이벤트가 있습니다.

 

 

1) 마우스 왼쪽 클릭을 누를 때

  • event의 종류가 왼쪽 클릭을 누른 경우라면 아래의 코드를 실행합니다.
  • oldx, oldy = 영상창 위에서 현재 마우스의 위치 좌표.
  • 영상창 위에서 현재 마우스의 위치 좌표를 출력해줍니다.

2) 마우스 왼쪽 클리을 뗄 때

  • event의 종류가 왼쪽 클릭을 떼는 경우라면 아래의 코드를 실행합니다.
  • 영상창 위에서 현재 마우스의 위치 좌표를 출력해줍니다.

3) 마우스를 움직일 때

  • event의 종류가 마우스 포인터가 움직이는 경우라면 아래의 코드를 실행합니다.
  • 만약 키보드 또는 마우스 조작을 누른 상태이고, 마우스 왼쪽 클릭을 누른 상태라면 아래의 코드를 실행합니다.
  • img 위에 (oldx,oldy)에서 (x,y)로 잇는 직선을 그리는데 두께는 4 pixel, 색은 (0,0,255) 빨간색으로 부드럽게 그린다.
  • 영상을 보여주고 현재의 좌표를 old 좌표로 바꾼다.

 

 

Create Image

img = np.ones((480, 640, 3), dtype=np.uint8) * 255
cv2.namedWindow('image')

 

  • img = 세로 픽셀 480, 가로 픽셀 540, 채널 3이고 모든 픽셀의 밝기가 255 하얀색인 영상.
  • 'image'라는 영상창을 생성합니다.

 

 

Create setMouseCallback Function

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

 

  • 'image'라고 하는 창위에서 정의한 on_mouse() 함수대로 마우스 이벤트 처리 함수를 생성합니다.

 

 

Print Image 

cv2.imshow('image', img)
cv2.waitKey()
 
cv2.destroyAllWindows()

EVENT_LBUTTONDOWN: 91, 338

EVENT_LBUTTONUP: 572, 96

 

 

 

 

 

*참고 : OpenCV를 활용한 컴퓨터 비전과 딥러닝