avatar
비루한 대학생

#2. OpenCV 인터페이스 기초

수업정리
3 months ago
·
9 min read

1. 윈도우 제어

OpenCv에서는 윈도우가 활성화된 상태에서만 마우스나 키보드 이벤트를 감지할 수 있다. 따라서 이런 이벤트를 감지해서 처리하려면 윈도우를 생성하고 제어할 수 있어야 한다.

  • cv2.namedWindow(winname [, flags]) : winname으로 윈도우 생성

    • flags

      • cv2.WINDOW_NORMAL : (0) 윈도우 크기 재조정 가능

      • cv2.WINDOW_AUTOSIZE : (1) 표시될 행렬의 크기에 맞춰 자동 조정

  • cv2.imshow(winname, mat) : winname으로 윈도우에 mat행렬을 영상으로 표시한다.

    • 생성된 윈도우가 없으면 winname으로 윈도우를 생성하고 영상을 표시한다.

  • cv2.destroyAllWindows() : HighGUI로 생성된 모드 윈도우를 파괴

  • cv2.destroyWindow(winname) : 인수로 지정된 타이틀의 윈도우를 파괴

  • cv2.moveWindow(winname, x, y) : winname의 윈도우를 지정된 위치인 (x, y)로 이동

  • cv2.resizeWindow(winname, width, height) : 윈도우의 크기를 재조정함

import cv2
import numpy as np

image = np.zeros((200, 300), np.unit8) #height, width순서 
image[:] = 200

title1, title2 = "Position1", "Position2"
cv2.namedWindow(title1, cv2.WINDOW_AUTOSIZE) #cv2.namedWindow(title)과 똑같음
cv2.namedWindow(title2, cv2.WINDOW_NORMAL)
cv2.waitKey(0)

cv2.destroyAllWindows()

>> 기본 창 생성
import cv2
import numpy as np

image = np.zeros((200, 300), np.uint8) #height, width순서 
image[:] = 200

title1, title2 = "Position1", "Position2"
cv2.namedWindow(title1, cv2.WINDOW_AUTOSIZE) #cv2.namedWindow(title)과 똑같음
cv2.namedWindow(title2, cv2.WINDOW_NORMAL)
cv2.waitKey(0)

cv2.moveWindow(title1, 150, 150)
cv2.moveWindow(title2, 400, 50)
cv2.waitKey(0)

cv2.destroyAllWindows()

>> 창 움직이기
import cv2
import numpy as np

image = np.zeros((200, 300), np.uint8) #height, width순서 
image[:] = 200

title1, title2 = "Position1", "Position2"
cv2.namedWindow(title1, cv2.WINDOW_AUTOSIZE) #cv2.namedWindow(title)과 똑같음
cv2.namedWindow(title2, cv2.WINDOW_NORMAL)
cv2.waitKey(0)

cv2.imshow(title1, image)
cv2.imshow(title2, image)
cv2.waitKey(0)

cv2.destroyAllWindows()

>> 이미지 보이기(image = 200, 연한 회색)

resize vs AUTOSIZE

import cv2
import numpy as np

image = np.zeros((200, 300), np.uint8) #height, width순서 
image[:] = 200

title1, title2 = "Position1", "Position2"
cv2.namedWindow(title1, cv2.WINDOW_AUTOSIZE) #cv2.namedWindow(title)과 똑같음
cv2.namedWindow(title2, cv2.WINDOW_NORMAL)
cv2.waitKey(0)

cv2.resizeWindow(title1, 600, 300)
cv2.resizeWindow(title2, 600, 300)
cv2.waitKey(0)

cv2.destroyAllWindows()

>>resize가 AUTOSIZE보다 쎔 얘가 먹음
until-1607

NORMAL로 생성 후 resize하면 이미지가 윈도우 크기에 맞춰 크기가 바뀐다. (캔버스에 맞춤 기능과 유사)

2. 이벤트 처리

2.1. 키보드 이벤트

  • waitKey([, delay]) or waitKeyEx([, delay])

    • delay시간만큼 키 입력을 대기하고, 키 이벤트가 발생하면 해당 키 값을 반환한다

      • delay <= 0 : 키 이벤트 발생까지 무한 대기

      • delay > 0 : 지연 시간동안 키 입력 대기, 지연 시간 안에 키 이벤트가 없으며 -1을 반환

    • waitKeyEx는 waitKey와 동일하지만, 전체 키 코드(full key code)를 반환한다. (e.g. 방향키 입력 등에 사용)

import cv2
import numpy as np

image = np.zeros((200, 300), np.uint8) #height, width순서 
cv2.imshow("img1", image)

while True:
    key = cv2.waitKeyEx(100) #ms단위
    if key == 27 : #escape키의 아스키코드값
        break
    elif key == -1 :
        continue
    else :
        if key < 255:
            print(key, chr(key)) #ord vs chr

        else : 
            print(key)

cv2.destroyAllWindows()

>> 키값 반환

2.2. 마우스 이벤트

마우스 콜백 함수를 사용하여 제어한다.

  • cv2.setMouseCallback(windowName, onMouse, param=None) : 사용자가 정의한 마우스 콜백 함수를 시스템에 등록

  • def onMouse(event, x, y, flags, param = None) : 발생한 마우스 이벤트에 대한 처리와 제어를 구현하는 콜백 함수

import numpy as np
import cv2

def onMouse(event, x, y, flags, param):
    if event == cv2.EVENT_LBUTTONDOWN:
        print(" 왼쪽 버튼 누르기")
    elif event == cv2.EVENT_RBUTTONDOWN:
        print("오른쪽 버튼 누르기")
    elif event == cv2.EVENT_RBUTTONUP:
        print("오른쪽 버튼 떼기")
    elif event == cv2.EVENT_LBUTTONUP:
        print("왼쪽 버튼 뗴기")
    
image = np.full((200, 300), 255, np.uint8)

title1, title2 = "me1", "me2"
cv2.imshow(title1, image)
cv2.imshow(title2, image)

cv2.setMouseCallback(title1, onMouse)
cv2.waitKey(0)
cv2.destroyAllWindows()

2.3. 트렉바 이벤트

  • cv2.createTrackvar(trackbarname, winname, value, count, onCnage) : 트랙바를 생성 후 지정한 윈도우에 추가

    • value : 트랙바 슬라이더의 위치를 반영하는 값(정수)

    • count : 트랙바 슬라이더의 최댓값, 최솟값은 항상 0이다.

    • onCnage : 트랙바 슬라이더의 값이 변경될 때 호출되는 콜백 함수

  • onCnage(pos) : 트랙바 슬라이더의 위치가 변경될 때마다 호출되는 콜백 함수

    • pos : 트랙바 슬라이더 위치

  • cv2.getTrackbarPos(trackbarname, winname) : 지정한 트랙바의 슬라이더 위치를 반환

  • cv2.setTrackbarPos(trackbarname, winname, pos) : 지정한 트랙바의 슬라이더 위치를 설정

import numpy as np
import cv2

def onChange(value):
    global image, title
    
    add_value = value - int(image[0][0])
    print("추가 화소값 : ", add_value)
    image[:] = image+add_value
    cv2.imshow(title, image)

image = np.zeros((300, 500), np.uint8)
title = "track"
cv2.imshow(title, image)

cv2.createTrackbar("bright", title, image[0][0], 255, onChange)
cv2.waitKey(0)
cv2.destroyAllWindows()

3. 그리기 함수

3.1. 직선 및 사각형 그리기

  • cv2.line(img, pt1, pt2, color [, thickness [, lineType[, shift]]]) : pt1에서 pt2를 잇는 직선을 그림

    • img : 그릴 대상 행렬(영상)

    • pt1, pt2 : 시작 좌표와 종료 좌표(정수형 튜플)

    • thickness : 선의 두께, cv2.FILLED일 경우 지정된 색으로 내부를 채움

    • color : 선의 색상(정수형 튜플)

    • lineType : 선의 형태

    • shift : 입력 좌표(pt1, pt2)에 대해 오른쪽으로 비트 시프트 연산한 결과를 좌표로 지정해서 직선을 그림

  • cv2.rectangle(img, pt1, pt2, color [, thickness [, lineType [, shift]]])

  • cv2.rectangle(img, rec, color [, thickness [, lineType [, shift]]])

    • 사각형은 2가지 방식으로 그릴 수 있다.

      • pt1, pt2 : 시작 좌표와 종료 좌표(정수형), 왼쪽 위 모서리 좌표와 오른쪽 밑 모서리 좌표

      • rec : 사각형 영역(x, y, w, h)을 나타내는 4원소 튜플(정수형)

import numpy as np
import cv2

blue, green, red = (255, 0, 0), (0, 255, 0), (0, 0, 255)
image = np.zeros((400, 600, 3), np.uint8)
image[:] = (255, 255, 255)

pt1, pt2 = (50, 50), (250, 150)
pt3, pt4 = (400, 150), (500, 50)
roi = (50, 200, 200, 100) #reason of interesting 관심 영역? 내가 처리하고자 하는 영역. 보토 이렇게 표기함

cv2.line(image, pt1, pt2, red)
cv2.line(image, pt3, pt4, green, 3, cv2.LINE_AA)

cv2.rectangle(image, pt1, pt2, blue, 3, cv2.LINE_4)
cv2.rectangle(image, roi, red, 3, cv2.LINE_8)
cv2.rectangle(image, (400, 200, 100, 100), green, cv2.FILLED)

cv2.imshow("l&r", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

3.2. 글자 쓰기

  • cv2.putText(img, text, org, fontFace, fontScale, color [, thickness [, lineType [, bottomLeftOrigin]]])

    • img : 문자열을 작성할 대상 행렬(영상)

    • text : 작성할 문자열

    • org : 문자열의 시작 좌표, 문자열에서 가장 왼쪽 하단을 의미

    • fontFace : 문자열의 폰트

    • fontScale : 글자 크기 확대 비율

    • color : 글자의 색상

    • thickness : 글자의 굵기

    • lineType : 글자 선의 형태

    • bottomLeftOrigin : 영상의 원점 좌표 설정(True-좌하단 왼쪽, False-좌상단)

3.3. 원 그리기

  • cv2.circle(img, center, radius, color [, thickness [, lineType [, shift]]]) : center를 중심으로 radius 반지름의 원을 그린다.

    • img : 원을 그릴 대상 행렬

    • center : 원의 중심 좌표

    • radius : 원의 반지름

3.4. 타원 그리기

  • cv2.ellipse(img, center, axes, angle, startAngle, endAngle, color [, thickness [, lineType [, shift]]]) : center를 중심으로 axes크기의 타원을 그린다.

    • img : 그릴 대상 행렬

    • center : 원의 중심 좌표

    • axes : 타원의 절반 크기(x축 반지름, y축 반지름)

    • angle : 타원의 각도 (3시 방향이 0, 시계방향으로 회전)

    • startAngle : 호의 시작 각도

    • endAngle : 호의 종료 각도


- 컬렉션 아티클






2!=2