OpenCV 이벤트 처리

이주희·2022년 10월 6일
0

마우스 이벤트 처리

먼저 마우스 콜백(callback) 함수를 등록해야함

콜백함수 등록 함수

void setMouseCallback(string& winname, MouseCallback onMouse, void* userdata =0);

  • winname : 마우스 이벤트 처리할 창 이름
  • onMouse : 콜백함수 이름
  • userdata : 콜백함수에 전달할 사용자 데이터의 포인터

콜백함수

typedef void(MouseCallback)(int event, int x, int y, int flags, void userdata);

  • event : MouseEventType로 정의된 상수중 하나 전달
  • x,y : 이벤트 발생 좌표
  • int flags : MouseEventFlags 열거형 상수의 논리합 조합 전달
import cv2 as cv

def on_mouse(event, x, y, flags, param):
    global oldx, oldy
    
    if event == cv.EVENT_LBUTTONDOWN:
        oldx, oldy = x,y
        print('L down %d %d'%(x,y))
        
    elif event == cv.EVENT_LBUTTONUP:
        print('L up %d %d' %(x,y))
        
    elif event == cv.EVENT_MOUSEMOVE: # 마우스 움직이면
        if flags & cv.EVENT_FLAG_LBUTTON: # 왼쪽 버튼도 눌렸으면
            cv.line(img, (oldx, oldy),(x,y),(0,255,255),2) # 선 그음
            cv.imshow('img',img)
            oldx,oldy = x,y # 이전 위치 옮김

            
img = cv.imread('CV images/lenna.bmp') # 이미지 불러오기
if img is None:
    print('Image load failed!')
    exit()


cv.namedWindow('img')
cv.setMouseCallback('img', on_mouse) # 이미지에 콜백함수 붙이기 
cv.waitKey()
cv.destroyAllWindows()

트랙바

범위안의 값 선택가능한 GUI

  • 트랙바 이름 지정 필요
  • 위치는 마우스를 이용하여 이동시킴
  • 가리킬 수 있는 최대 위치는 생성시 지정가능, 최소는 0으로 고정

생성

int createTrackbar(string& trackbarname, String& winname, int value, int count, TrackbarCallback onChange = 0, void userdata =0);

  • (이름, 생성창, 위치 받을 정수형 변수 주소, 최대 위치, 콜백함수, 전달할 사용자 데이터 포인터)

  • 정상동작시 1 반환, 아니면 0 반환

콜백함수

typedef void (TrackbarCallback)(int pos, void userdata);

  • 트랙바 위치 변경시 자동으로 호출됨
  • pos에는 현재 위치정보 전달
  • userdata에는 사용자 데이터의 포인터값 전달

실습

트랙바를 이용해서 이미지를 점차 반전시키는 프로그램

import cv2 as cv
import numpy as np

def saturated(value): #숫자 0~255 내로 범위조정 함수
    
    if value > 255:
        value = 255
    elif value < 0:
        value =0
    return value

def callback(pos): # 콜백 함수
    img2 = img+saturated(pos*16)
    cv.imshow('img2', img2)


img = cv.imread('CV Images/lenna.bmp')
if img is None:
    print("open error")
    exit()

img2 = np.copy(img)
cv.imshow('img2',img2) # 이미지 보여주기
cv.createTrackbar('bar','img2',0,16,callback ) # 트랙바 생성

cv.waitKey()
cv.destroyAllWindows()

파일 저장하고 불러오기

  • uchar 자료형을 사용하는 영상만 저장가능
  • BMP, JPG, PNG 형식으로 저장가능
  • FileStorage 객체 사용

FileStorage(string& filename, int flags, string& encoding= String());

  • flags : 파일 열기 모드 결정
    cv.FILE _ STORAGE _~
    • READ : 읽기모드
    • WRITE : 쓰기모드
    • APPEND : 추가로 쓰기 모드
    • MEMORY : 논리합으로 READ, WRITE와 함께 쓰면 메모리 버퍼를 이용한 입출력 수행

virtual bool FileStorage::isOpened();
정상적으로 열렸으면 true 리턴

virtual void FileStorage:: release()
파일 닫고 메모리 버퍼 해제

저장

사진에 그림 그리고 저장

import cv2 as cv

def on_mouse(event, x, y, flags, param):
    global oldx, oldy
    
    if event == cv.EVENT_LBUTTONDOWN:
        oldx, oldy = x,y
        print('L down %d %d'%(x,y))
        
    elif event == cv.EVENT_LBUTTONUP:
        print('L up %d %d' %(x,y))
        
    elif event == cv.EVENT_MOUSEMOVE: # 마우스 움직이면
        if flags & cv.EVENT_FLAG_LBUTTON: # 왼쪽 버튼도 눌렸으면
            cv.line(img, (oldx, oldy),(x,y),(0,255,255),2) # 선 그음
            cv.imshow('img',img)
            oldx,oldy = x,y # 이전 위치 옮김

            
img = cv.imread('CV images/lenna.bmp')
if img is None:
    print('Image load failed!')
    exit()

fs = cv.FileStorage('myimg.json', cv.FILE_STORAGE_WRITE) # 저장 클래스 생성
cv.namedWindow('img')
cv.setMouseCallback('img', on_mouse)
cv.waitKey()
fs.write('data', img) # 이미지 저장
fs.release()
cv.destroyAllWindows()

불러오기

json 파일에는 JSON 문법을 이용하여 각각의 데이터가 저장돼있음

getNode() 함수를 이용하여 각 노드에 접근

import cv2 as cv
import numpy as np

fs = cv.FileStorage('myimg.json', cv.FILE_STORAGE_READ)

####
img = fs.getNode('data').mat()
####

img = np.array(img, dtype = np.uint8)
print(img)
print(img.shape)
cv.imshow('img',img)
cv.waitKey()
cv.destroyAllWindows()

0개의 댓글