▶ 키보드 이벤트 처리하기
이번 포스팅에서는 키보드 이벤트 처리하기를 알아보고 응용으로 'I' 키를 누르면 영상이 반전되는 것을 해보겠습니다.
→ 키보드 입력 대기 함수
cv2.waitkey 함수로 키보드 이벤트를 처리할 수 있습니다.
[명령어 설명]
cv2.waitKey(delay=None) -> retval
• delay: 밀리초 단위 대기 시간. delay 0 이면 무한히 기다림. 기본값은 0
• retval: 눌린 키 값(ASCII code). 키가 눌리지 않으면 -1.
[참고 사항]
▪ cv2.waitKey() 함수는 OpenCV 창이 하나라도 있을 때 동작합니다.
▪ 특정 키 입력을 확인하려면 ord() 함수를 이용합니다.
▪ 주요 특수키 코드: 27(ESC), 13(ENTER), 9(TAB)
[예시 코드]
while True: # 무한 루프
if cv2.waitKey() == ord('q'): # q를 누르면 종료
break
영상이 출력되면 q를 눌렀을 때 종료하는 코드입니다.
▶ 특수키 입력 처리하는 방법
cv2.waitKey()는 일반적인 키보드를 처리할 수 있지만 특수 키를 처리하지 못합니다.
cv2.waitKeyEX() 함수를 이용하면 방향키, 함수키와 같은 특수 키를 처리할 수 있습니다.
▶ 키보드에서 'i' 또는 'I' 키를 누르면 영상을 반전시키기
cv2.waitKey 함수를 이용해서 'i', 'I' 키를 누르면 영상을 반전시키도록 해보겠습니다.
[코드]
# 영상을 흑백 영상으로 불러옵니다.
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)
# 영상 반전 코드
while True: # 무한 루프
keycode = cv2.waitKey() # 키보드 입력 반환 값 저장
if keycode == ord('i') or keycode == ord('I'): # i 또는 I 누르면 영상 반전
img = ~img # 영상 반전, 그레이스케일 영상에만 가능
cv2.imshow('image', img) # 반전된 영상 출력
elif keycode == 27: # ESC 누를 시 종료
break
# 모든 창 닫기
cv2.destroyAllWindows()
출력된 영상에서 i 를 누르면 반전된 영상이 출력됩니다.
다시 i를 누르면 반전이 되어 기본 영상으로 되돌아갑니다.
마우스 이벤트 처리하기
마우스 이벤트 처리하는 방법을 알아보고 마우스를 이용해 그림을 그려보도록 하겠습니다.
→ 마우스 이벤트 콜백함수 등록 함수 - cv2.setMouseCallback
마우스 이벤트가 입력되면 사전에 작성한 함수를 불러와서 작동시킵니다.
[함수 설명]
cv2.setMouseCallback(windowName, onMouse, param=None) -> None
• windowName: 마우스 이벤트 처리를 수행할 창 이름
• onMouse: 마우스 이벤트 처리를 위한 콜백 함수 이름.
• param: 콜백 함수에 전달할 데이터
[예시 코드]
# 윈도우 창
cv2.namedWindow('image')
# 마우스 입력, namedWIndow or imshow가 실행되어 창이 떠있는 상태에서만 사용가능
# 마우스 이벤트가 발생하면 on_mouse 함수 실행
cv2.setMouseCallback('image', on_mouse, img)
→ 마우스 이벤트 콜백함수 - onMouse
마우스 입력 값에 따라 어떤 동작을 실행할 것인지 지정하는 함수입니다.
지정해둔 함수를 cv2.setMouseCallback함수로 등록해서 사용할 수 있습니다.
[함수 설명]
onMouse(event, x, y, flags, param) -> None
• event: 마우스 이벤트 종류. cv2.EVENT_로 시작하는 상수.
• x: 마우스 이벤트가 발생한 x 좌표
• y: 마우스 이벤트가 발생한 y 좌표
• flags: 마우스 이벤트 발생 시 상태. cv2.EVENT_FLAG_로 시작하는 상수
• param: cv2.setMouseCallback() 함수에서 설정한 데이터
[예시 코드]
def on_mouse(event, x, y, flags, param):
# event는 마우스 동작 상수값, 클릭, 이동 등등
# x, y는 내가 띄운 창을 기준으로 좌측 상단점이 0,0이 됌
# flags는 마우스 이벤트가 발생할 때 키보드 또는 마우스 상태를 의미, Shif+마우스 등 설정가능
# param은 영상이룻도 있도 전달하고 싶은 데이타, 안쓰더라도 넣어줘야함
global oldx, oldy 함수 밖에 있는 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: # ==를 쓰면 다른 키도 입력되었을 때 작동안하므로 &(and) 사용
# cv2.circle(img, (x, y), 5, (0, 255, 0), -1) # 단점이 빠르게 움직이면 끊김
# circle은 끊기므로 line 이용
# 마우스 클릭한 좌표에서 시작해서 마우스 좌표까지 그림
cv2.line(img, (oldx, oldy), (x, y), (0, 0, 255), 4, cv2.LINE_AA)
cv2.imshow('image', img)
oldx, oldy = x, y # 그림을 그리고 또 좌표 저장
이처럼 마우스를 이용해 그림을 그릴 수 있는 함수를 만들었습니다.
함수 이름은 onMouse가 아니어도 됩니다.
▶ 마우스 이벤트 처리 함수의 event, flags 인자
onMouse에 입력값은 event, flags 인자에 대해 알아보겠습니다.
4. 마우스를 이용해 그리기
앞에서 열거한 코드들을 조합하여 마우스를 이용해 그림을 그려보겠습니다.
[코드]
import sys
import numpy as np
import cv2
oldx = oldy = -1 # 좌표 기본값 설정
# 내가 만든 마우스 함수를 실행시켜줘
def on_mouse(event, x, y, flags, param):
# event는 마우스 동작 상수값, 클릭, 이동 등등
# x, y는 내가 띄운 창을 기준으로 좌측 상단점이 0,0이 됌
# flags는 마우스 이벤트가 발생할 때 키보드 또는 마우스 상태를 의미, Shif+마우스 등 설정가능
# param은 영상이룻도 있도 전달하고 싶은 데이타, 안쓰더라도 넣어줘야함
global oldx, oldy # 밖에 있는 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: # ==를 쓰면 다른 키도 입력되었을 때 작동안하므로 &(and) 사용
# cv2.circle(img, (x, y), 5, (0, 255, 0), -1) # 단점이 빠르게 움직이면 끊김
# circle은 끊기므로 line 이용
# 마우스 클릭한 좌표에서 시작해서 마우스 좌표까지 그림
cv2.line(img, (oldx, oldy), (x, y), (0, 0, 255), 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')
# 마우스 입력, namedWIndow or imshow가 실행되어 창이 떠있는 상태에서만 사용가능
# 마우스 이벤트가 발생하면 on_mouse 함수 실행
cv2.setMouseCallback('image', on_mouse, img)
# 영상 출력
cv2.imshow('image', img)
cv2.waitKey()
cv2.destroyAllWindows()
[결과]
출력된 좌표값
'Language - Python(Opencv)' 카테고리의 다른 글
Python Opencv - #10, 동영상 응용 (0) | 2021.11.22 |
---|---|
Python Opencv - #9, Trackbar (0) | 2021.11.22 |
Python Opnecv - #7 카메라, 동영상 처리 (0) | 2021.11.22 |
Python Opencv - #6 Draw 함수 (0) | 2021.11.21 |
Python Opencv - #5 Mask 연산과 R.O.I (0) | 2021.11.21 |