기본 입출력

이미지와 비디오 입출력

opencv 를 이용한 대부분의 작업은 파일로 된 이미지를 읽어서 적절한 연산을 적용하고 그 결과를 화면에 표시하거나 다른 파일로 저장하는 것이다.

이미지 읽기

opencv를 이용하여 이미지 파일을 화면에 표시

img = cv2.imread(file_name [, mode_flag]) : 파일로부터 이미지 읽기
  • file_name : 이미지 경로, 문자열
mode_flag=cv.imread_color : 읽기 모드 지정
  • cv2.imread_color : 컬러스케일로 읽기, 기본값
  • cv2.imread_unchanged : 파일 그대로 읽기
  • cv2.imread_grayscale : 그레이스케일로 읽기
img : 읽은 이미지, numpy 배열
cv2.imshow( ‘title’ , img) : 이미지를 화면에 표시
  • title : 창 제목, 문자열
  • img : 표시알 이미지, numpy 배열
cv2.waitKey( [delay] ) : 키보드 입력 대기
  • delay = 0 :키보드 입력을 대기할 시간(ms) / 0 : 무한대(기본 값)
  • key : 사용자가 입력한 키 값, 정수
  • -1 : 대기시간 동안 키 입력 없음
import cv2

img_file = './img/girl.jpg'    # 표시할 이미지 경로
img = cv2.imread(img_file)     # 이미지를 읽어서 img로 선언

if img is not None:
    cv2.imshow('IMG', img)     # 읽은 이미지를 화면에 표시
    cv2.waitKey()              # 키가 입력될 때까지 대기
    cv2.destroyAllWindows()    # 창 모두 닫기
else:
    print('No image file.')

이미지읽기

  • 옵션 변경하여 실행 (그레이 스캐일로 변경)
import cv2

img = cv2.imread(img_file, cv2.IMREAD_GRAYSCALE)

if img is not None:
    cv2.imshow('IMG', img)
    cv2.waitKey()
    cv2.destroyAllWindows()
else:
    print('No image file.')

이미지읽기

이미지 저장하기

읽은 이미지를 다시 파일로 저장하는 함수는 CV2.imwrite() 이다.

cv2.imwrite(file_path, img) : 이미지를 파일에 저장
  • file_path : 저장할 파일 경로 이름, 문자열
  • img : 저장할 영상, numpy 배열

이미지를 그레이 스케일로 저장

import cv2

img_file = './img/girl.jpg'
save_file = './img/girl_gray1.jpg'

img = cv2.imread(img_file, cv2.IMREAD_GRAYSCALE)
cv2.imshow(img_file, img)
cv2.imwrite(save_file, img)     # 파일로 저장, 포맷은 확장자에따라 다름
cv2.waitKey()
cv2.destroyAllWindows()

동영상 및 카메라 프레임 읽기

opencv는 동영상 파일이나 컴퓨터에 연결한 카메라 장치로 부터 연속된 이미지 프레임을 읽을수 있는 API를 제공한다.

cap = cv2.VideoCapture(file_path 또는 index) : 비디오 캡처 객체 생성자
  • file_path : 동영상 파일 경로
  • index : 카메라 장치 번호, 0부터 순차적으로 증가
  • cap : VideoCapture 객체
ret = cap.isOpened( ) : 객체 초기화 확인
  • ret : 초기화 여부, True/False
ret, img = cap.read( ) : 영상 프레임 읽기
  • ret : 프레임 읽기 성공 또는 실패 여부, True/False
  • img : 프레임 이미지, numpy 배열 또는 None
cap.set( id, value) : 프로퍼티 변경
cap.get(id) : 프로퍼티 확인
cap.release( ) : 캡처 자원 반납

동영상 파일 읽기

import cv2

video_file = './img/big_buck.avi'    # 동영상 파일 경로

cap = cv2.VideoCapture(video_file)    # 동영상 캡처 객체 생성
if cap.isOpened():             # 캡처 객체 초기화 확인
    while True:
        ret, img = cap.read()    # 다음 프레임 읽기
        if ret:     # 프레임 읽기 정상이면
            cv2.imshow(video_file, img)    # 화면에 표시
            cv2.waitKey(25)      # 25ms 지연
        else:      # 읽을 수 없으면
            break   # 완료
else:
    print("can't open video")    # 캡처 객체 초기화 실패
cap.release()      # 캡처 자원 반납
cv2.destroyAllWindows()

카메라(웹캠) 프레임 읽기

import cv2

cap = cv2.VideoCapture(0)     # 0번 카메라 장치 연결
if cap.isOpened():
    while True:
        ret, img = cap.read()   # 카메라 프레임 읽기
        if ret:
            cv2.imshow('camera', img)    # 프레임 이미지 표시
            if cv2.waitKey(1) != -1:     # 1ms 동안 키 입력 대기
                break                 # 아무 키나 눌렀으면 중지
        else:
            print('no frame')
            break
else:
    print("can't open cameera.")
cap.release()
cv2.destroyAllWindows()

카메라 비디오 속성 제어

속성 ID : ‘cv2.CAP_PROP_‘로 시작하는 상수
  • cv2.CAP_PROP_FRAME_WIDTH : 프레임 폭
  • cv2.CAP_PROP_FRAME_HEIGHT : 프레임 높이
  • cv2.CAP_PROP_FPS : 초당 프레임 수
  • cv2.CAP_PROP_POS_MSEC : 동영상 파일의 프레임 위치(ms)
  • cv2.CAP_PROP_POS_AVI_RATIO : 동영상 파일의 상대 위치(0:시작, 1:끝)
  • cv2.CAP_PROP_FOURCC : 동영상 파일 코덱 문자
  • cv2.CAP_PROP_AUTOFOCUS : 카메라 자동 초점 조절
  • cv2.CAP_PROP_ZOOM : 카메라 줌

FPS 를 지정해서 동영상 재생

import cv2

video_file = './img/big_buck.avi'    # 동영상 파일 경로

cap = cv2.VideoCapture(video_file)    # 동영상 캡처 객체 생성
if cap.isOpened():     # 캡처 객체 초기화 확인
    fps = cap.get(cv2.CAP_PROP_FPS)    # 프레임 수 구하기
    delay = int(1000/fps)      # 지연시간 구하기
    print("FPS: %f, Delay: %dms"%(fps, delay))
    
    while True:
        ret, img = cap.read()    # 다음 프레임 읽기
        if ret:    
            cv2.imshow(video_file, img)
            cv2.waitKey(delay)   # fps 에 맞게 시간 지연
        else:
            break
else:
    print("can't open video.")
cap.release()
cv2.destroyAllWindows()
FPS: 24.000000, Delay: 41ms

카메라 프레임 크기 설정

import cv2

cap = cv2.VideoCapture(0)
width=cap.get(cv2.CAP_PROP_FRAME_WIDTH)   # 프레임 폭 값 구하기
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)   # 프레임 높이 값 구하기
print("Original width: %d, height:%d"%(width, height))

cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320)    # 프레임 폭을 320으로 설정
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)    # 프레임 높이를 240으로 설정
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)   # 재지정한 프레임 폭 값 구하기
print("Resized width: %d, height:%d"%(width,height))    # 재지정한 프레임 높이 값 구하기

if cap.isOpened():
    while True:
        ret, img = cap.read()
        if ret:
            cv2.imshow('camera', img)

            if cv2.waitKey(1) != -1:   # 아무키나 누르면
                break
        else:
            print('no frame')
            break
else:
    print("can't open camera")
    
cap.release()
cv2.destroyAllWindows()
Original width: 1280, height:720
Resized width: 1280, height:720

비디오 파일 저장하기

  • 카메라로 사진찍기
import cv2

cap = cv2.VideoCapture(0)
if cap.isOpened():
    while True:
        ret, frame = cap.read()
        if ret:
            cv2.imshow('camera', frame)
            if cv2.waitKey(1) != -1:    # 아무키나 누르면
                cv2.imwrite('photo.jpg', frame)   # 저장
                break
        else:
            print('no frame')
            break
else:
    print('no camera')
cap.release()
cv2.destroyAllWindows()
  • 카메라로 녹화하기
import cv2

cap = cv2.VideoCapture(0)
if cap.isOpened:
    file_path = './record.avi'
    fps = 25.40
    fourcc = cv2.VideoWriter_fourcc(*'DIVX')
    width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
    height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
    size = (int(width), int(height))
    out = cv2.VideoWriter(file_path, fourcc, fps, size)
    while True:
        ret, frame = cap.read()
        if ret:
            cv2.imshow('camera-recording', frame)
            out.write(frame)
            if cv2.waitKey(int(1000/fps)) != -1:
                break
        else:
            print('no frame')
            break
    out.release()
else:
    print("can't open camera")
cap.release()
cv2.destroyAllWindows()

그림그리기

하양색 배경 만들기

import cv2
import numpy as np

img = np.full((500,500,3),255,dtype=np.uint8)
cv2.imwrite('./img/blank_500.jpg',img)
True

이미지읽기

직선그리기

cv2.line(img, start, end, colot [ , thikness, lineType]) : 직선 그리기
  • img : 그림 그릴 대상 이미지, numpy 배열
  • start : 선 시작 지점 좌표(x, y)
  • end : 선 끝 지점 좌표(x, y)
  • color : 선 색상, (Blue, Green, Red), 0-255
  • thickness=1 : 선두께

  • lineType : 선 그리기 형식
    • cv2.LINE_4 : 연결선 알고리즘
    • cv2.LINE_8 : 연결선 알고리즘
    • cv2.LINE_AA : 안티에일리어싱(antialiasing, 계단 현상 없는 선)
import cv2

img = cv2.imread('./img/blank_500.jpg')

cv2.line(img, (50, 50), (150, 50), (255, 0, 0))    # 파란색 1픽셀 선
cv2.line(img, (200, 50), (300, 50), (0, 255, 0))   # 초록색 1픽셀 선
cv2.line(img, (350, 50), (450, 50), (0, 0, 255))   # 빨간색 1픽셀 선

# 하늘색 10픽셀 선
cv2.line(img, (100, 100), (400, 100), (255, 255, 0), 10)
# 분홍색 10픽셀 선
cv2.line(img, (100, 150), (400, 150), (255, 0, 255), 10)
# 노란색 10픽셀 선
cv2.line(img, (100, 200), (400, 200), (0, 255, 255), 10)
# 회색 10픽셀 선
cv2.line(img, (100, 250), (400, 250), (200, 200, 200), 10)
# 검은색 10픽셀 선
cv2.line(img, (100, 300), (400, 300), (0, 0, 0), 10)

# 4연결 선
cv2.line(img, (100, 350), (400, 400), (0, 0, 255), 20, cv2.LINE_4)
# 8연결 선
cv2.line(img, (100, 400), (400, 450), (0, 0, 255), 20, cv2.LINE_8)
# 안티에일리어싱 선
cv2.line(img, (100, 450), (400, 500), (0, 0, 255), 20, cv2.LINE_AA)
# 이미지 전체에 대각선
cv2.line(img, (0, 0), (500, 500), (0, 0, 255))

cv2.imshow('lines', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

이미지읽기

사각형 그리기

  • 사각형을 그리는 함수는 cv2.rectangle()이다.
cv2.rectangle( img, start, end, color [ , thickness, lineType ] ) : 사각형 그리기
  • img : 그림 그릴 대상 이미지, numpy 배열
  • start : 사각형 시작 꼭짓점(x,y)
  • end : 사각형 끝 꼭짓점(x,y)
  • color : 색상(blue, green, red)
  • thickness : 선 두께
  • -1 : 채우기
  • lineType : 선 타입, cv2.line()과 동일
import cv2

img = cv2.imread('./img/blank_500.jpg')
# 좌상, 우하 좌표로 사각형 그리기
cv2.rectangle(img,  (50, 50), (150, 150), (255, 0, 0))
cv2.rectangle(img,  (300, 300), (100, 100), (0, 255, 0), 10)
cv2.rectangle(img,  (450, 200), (200, 450), (0, 0, 255), -1)

cv2.imshow('rectangle', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

이미지읽기

다각형 그리기

  • 다각형을 그리는 함수는 cv2.polylines()이다.
cv2.polylines( img, points, isClosed, color [ , thickness, lineType ] ) : 다각형 그리기
  • img : 그림 그릴 대상 이미지, numpy 배열
  • points : 꼭지점 좌표, numpy 배열 리스트
  • isClosed : 닫힌도형 여부, True/False
  • color : 색상(blue, green, red)
  • thickness : 선 두께
  • lineType : 선 타입, cv2.line()과 동일
import cv2
import numpy as np     # 좌표 표현을 위한 numpy ahebf

img = cv2.imread('./img/blank_500.jpg')

pts1 = np.array([[50,50], [150,150], [100,140], [200,240]], dtype=np.int32)
pts2 = np.array([[350,50], [250,200], [450,200]], dtype=np.int32)
pts3 = np.array([[150,300], [50,450], [250,450]], dtype=np.int32)
pts4 = np.array([[350,250], [450,350], [400,450], [300,450], [250,350]], dtype=np.int32)

cv2.polylines(img, [pts1], False, (255,0,0))    # 번개모양
cv2.polylines(img, [pts2], False, (0,0,0), 10)   # 삼각형 열린 선 그리기
cv2.polylines(img, [pts3], True, (0,0,255), 10)   # 삼각형 닫힌 도형 그리기
cv2.polylines(img, [pts4], True, (0,0,0))    # 오각형 닫힌 도형 그리기

cv2.imshow('polyline', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

이미지읽기

원, 타원, 호 그리기

cv2.circle( img, center, radius, color [ , thickness, lineType ] ) : 원 그리기
  • img : 그림 대상 이미지
  • center : 원점 좌표(x,y)
  • radius : 원의 반지름
  • color : 색상(blue, green, red)
  • thickness : 선 두께(-1 : 채우기)
  • lineType : 선 타입, cv2.line()과 동일
cv2.ellipse( img, center, axes, angle, from, to, color [ , thickness, lineType ] ) : 호나 타원 그리기
  • img : 그림 대상 이미지
  • center : 원점 좌표(x,y)
  • axes : 기준 축 길이
  • angle : 기준 축 회전 각도
  • form, to : 호를 그릴 시작 각도와 끝 각도
import cv2

img = cv2.imread('./img/blank_500.jpg')

# 원점(150, 150), 반지름 100
cv2.circle(img, (150, 150), 100, (255,0,0))
# 원점(300, 150), 반지름 70
cv2.circle(img, (300, 150), 70, (0,255,0), 5)
# 원점(400, 150), 반지름 50, 채우기
cv2.circle(img, (400, 150), 50, (0,0,255), -1)

# 원점(50, 300), 반지름(50), 회전 0, 0도부터 360도 그리기
cv2.ellipse(img, (50, 300), (50, 50), 0, 0, 360, (0,0,255))
# 원점(150, 300), 아래 반원 그리기
cv2.ellipse(img, (150, 300), (50, 50), 0, 0, 100, (255,0,0))
# 원점(200, 300), 위 반원 그리기
cv2.ellipse(img, (200, 300), (50, 50), 0, 181, 360, (0,0,255))

# 원점(325, 300), 반지름(75, 50), 납작한 타원 그리기
cv2.ellipse(img, (325, 300), (75, 50), 0, 0, 360, (0,255,0))
# 원점(450, 300), 반지름(50, 70), 홀쭉한 타원 그리기
cv2.ellipse(img, (450, 300), (50, 70), 0, 0, 360, (255,0,255))

# 원점(50, 425), 반지름(50, 75), 회전 15도
cv2.ellipse(img, (50, 425), (50, 75), 15, 0, 360, (0,0,0))
# 원점(200, 425) 반지름(50, 75), 회전 45도
cv2.ellipse(img, (200, 425), (50, 75), 45, 0, 360, (0,0,0))

# 원점(350, 425), 홀쭉한 타원 45도 회전후 아래반원 그리기
cv2.ellipse(img, (350, 425), (50, 70), 45, 0, 180, (0,0,255))
# 원점(350, 425), 홀쭉한 타원 45도 회전후 위 반원 그리기
cv2.ellipse(img, (400, 425), (50, 75), 45, 181, 360, (255,0,0))

cv2.imshow('circle', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

이미지읽기

글씨 그리기

cv2.putText(img, text, point, fontFace, fontSize, color [ , thickness, lineType ] )
  • txt : 표시할 문자열
  • point : 표시할 좌표(x,y)
  • fontFace : 글꼴
import cv2

img = cv2.imread('./img/blank_500.jpg')

cv2.putText(img, 'Plain', (50, 30), cv2.FONT_HERSHEY_PLAIN, 1, (0, 0, 0))
cv2.putText(img, 'Simplex', (50, 70), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0))
cv2.putText(img, 'Duplex', (50, 110), cv2.FONT_HERSHEY_DUPLEX, 1, (0, 0, 0))
cv2.putText(img, 'Simplex', (200, 110), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 0))

cv2.putText(img, 'Complex Small', (50, 180), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 0, 0))
cv2.putText(img, 'Complex', (50, 220), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 0, 0))
cv2.putText(img, 'Triplex', (50, 110), cv2.FONT_HERSHEY_TRIPLEX, 1, (0, 0, 0))

cv2.putText(img, 'Complex', (200, 260), cv2.FONT_HERSHEY_TRIPLEX, 2, (0, 0, 255))
cv2.putText(img, 'Script Simplex', (50, 330), cv2.FONT_HERSHEY_SCRIPT_SIMPLEX, 1, (0, 0, 0))
cv2.putText(img, 'Script Simplex', (50, 370), cv2.FONT_HERSHEY_SCRIPT_SIMPLEX, 1, (0, 0, 0))

cv2.putText(img, 'Plain Italic', (50, 430), cv2.FONT_HERSHEY_PLAIN | cv2.FONT_ITALIC, 1, (0, 0, 0))
cv2.putText(img, 'Complex Italic', (50, 470), cv2.FONT_HERSHEY_PLAIN | cv2.FONT_ITALIC, 1, (0, 0, 0))

cv2.imshow('draw text', img)
cv2.waitKey()
cv2.destroyAllWindows()

이미지읽기

창 관리

cv2.namedWindow( title [ , option ] ) : 이름을 갖는 창 열기
  • title : 창 이름, 제목 줄에 표시
  • option : 창 옵션, ‘cv2.WINDOW_‘로 시작
  • cv2.WINDOW_NORMAL : 임의의 크기, 사용자 창 크기 조정 가능
  • cv2.WINDOW_AUTOSIZE : 이미지와 같은 크기, 창 크기 재조정 불가능

  • cv2.moveWindow(title, x, y) : 창 위치 이동
  • title : 위치를 변경할 창의 이름
  • x, y : 이동할 창의 위치

  • cv2.resizeWindow(title, width, height) : 창 크기 변경
  • title : 크기를 변경할 창의 이름
  • width, height : 변경할 폭과 높이

  • cv2.destroyWindow(title) : 창 닫기
  • title : 닫을 대상 창 이름

  • cv2.destroyAllWindow() : 열린 모든 창 닫기
import cv2

file_path = './img/girl.jpg'
img = cv2.imread(file_path)
img_gray = cv2.imread(file_path, cv2.IMREAD_GRAYSCALE)

cv2.namedWindow('origin', cv2.WINDOW_AUTOSIZE)
cv2.namedWindow('gray', cv2.WINDOW_NORMAL)

cv2.imshow('origin', img)
cv2.imshow('gray', img_gray)

cv2.moveWindow('origin', 0, 0)
cv2.moveWindow('gray', 100, 100)

cv2.waitKey(0)  # 아무키나 누르면
cv2.resizeWindow('origin', 200, 200)
cv2.resizeWindow('gray', 100, 100)

cv2.waitKey(0)
cv2.destroyWindow('gray')

cv2.waitKey(0)
cv2.destroyAllWindows()

이미지읽기

이벤트 처리

키보드와 마우스 입력 방법에 대해 알아보자.

키보드 이벤트

키보드에서 어떤 키를 눌렀는지 알아내려면 cv2.waitKey( ) 함수의 반환값을 출력해보면 된다.

import cv2

img_file = './img/girl.jpg'
img = cv2.imread(img_file)
title = 'IMG'
x, y = 100, 100    # 최초 좌표

while True:
    cv2.imshow(title, img)
    cv2.moveWindow(title, x, y)
    key = cv2.waitKey(0) &0xFF   # 키보드 입력을 무한 대기, 8비트 마스크 처리
    print(key, chr(key))     # 키보드 입력값, 문자값 출력
    
    if key == ord('h'):      # h 키 누르면 좌로 10이동
        x -= 10
    elif key == ord('j'):    # j 키 누르면 좌로 10이동
        y += 10
    elif key == ord('k'):    # k 키 누르면 좌로 10이동
        y -= 10
    elif key == ord('l'):    # l 키 누르면 좌로 10이동
        x += 10
    elif key == ord('q') or key == 27:    # q, esc 키 누르면 좌로 10이동
        break
        cv2.destroyAllWindows()
    cv2.moveWindow(title,x,y)    # 새로운 좌표로 창 이동

마우스 이벤트

마우스에서 입력을 받으려면 이벤트를 처리할 함수를 미리 선언해 놓고 cv2.setMouseCallback() 함수에 그 함수를 전달한다.

간단히 표연하면 다음과 같다.
def onMouse(event, x, y, flags, param): (마우스 이벤트에 맞게 해야할 작업을 작성)
cv2.setMouseCallback(‘title’, onMouse)

cv2.setMouseCallback(win_name, onMouse [ , param] ) : onMouse 함수를 등록
  • win_name : 이벤트를 등록할 윈도 이름
  • onMouse : 이벤트 처리를 위해 미리 선언해 놓은 콜백 함수
  • 필요에 따라 on Mouse 함수에 전달할 인자
MouseCallback(event, x, y, flags, param) : 콜백함수 선언부
  • event : 마우스 이벤트 종류, cv2.EVENT_ 로 시작하는 상수
    • cv2.EVENT_MOUSEMOVE : 마우스 움직임
    • cv2.EVENT_LBUTTONDOWN / UP : 마우스 왼쪽 버튼 누름 / 뗌
    • cv2.EVENT_RBUTTONDOWN / UP : 마우스 오른쪽 버튼 누름 / 뗌
    • cv2.EVENT_MBUTTONDOWN / UP : 마우스 가운데 버튼 누름 / 뗌
    • cv2.EVENT_LBUTTONDBLCLK : 왼쪽 버튼 더블클릭
    • cv2.EVENT_RBUTTONDBLCLK : 오른쪽 버튼 더블클릭
    • cv2.EVENT_MBUTTONDBLCLK : 가운데 버튼 더블클릭
    • cv2.EVENT_MOUSEWHEEL : 휠 스크롤
    • cv2.EVENT_MOUSEHWHEEL : 휠 가로스크롤
  • x, y : 마우스 좌표

  • flags : 마우스 동작과 함께 일어난 상태, cv2.EVENT_FLAG_ 로 시작하는 상수
    • cv2.EVENT_FLAG_LBUTTON(1) : 왼쪽 버튼 누름
    • cv2.EVENT_FLAG_RBUTTON(2) : 오른쪽 버튼 누름
    • cv2.EVENT_FLAG_MBUTTON(4) : 가운데 버튼 누름
    • cv2.EVENT_FLAG_CTRLKEY(8) : Ctrl키 누름
    • cv2.EVENT_FLAG_SHIFTKEY(16) : Shift키 누름
    • cv2.EVENT_FLAG_ALTKEY(32) : Alt키 누름
  • param : cv2.setMouseCallback( ) 함수에서 전달한 인자

마우스 이벤트로 동그라미 그리기

import cv2

title = 'mouse event'
img = cv2.imread('./img/blank_500.jpg')
cv2.imshow(title, img)

def onMouse(event, x, y, flags, param):    # 마우스 콜백 함수 구현
    print(event, x, y)      # 파라미터 출력
    if event == cv2.EVENT_LBUTTONDOWN:   # 왼쪽버튼을 누르면
        cv2.circle(img, (x,y), 30, (0,0,0), -1)   # 원을 좌표에 스림
        cv2.imshow(title, img)   # 그려진 이미지를 다시 표시
        
cv2.setMouseCallback(title, onMouse)   # 마우스 콜백 함수를 GUI 윈도에 등록

while True:
    if cv2.waitKey(0) &0xFF == 27:    # esc로 종료
        break
cv2.destroyAllWindows()

이미지읽기

플래그를 이용한 동그라미 그리기

import cv2

title = 'mouse event'
img = cv2.imread('./img/blank_500.jpg')
cv2.imshow(title, img)

colors = {'black':(0,0,0),
         'red' : (0,0,255),
         'blue' : (255,0,0)
         'green' : (0,255,0)}

def onMouse(event, x, y, flags, param):
    print(event, x, y)
    color = colors['black']
    if event == cv2.EVENT_LBUTTONDOWN:
        if flags & cv2.EVENT_FLAG_CTRLKEY and flags & cv2.EVENT_FLAG_SHIFTKEY:
            color = colors['green']
        elif flags & cv2.EVENT_FLAG_SHIFTKEY:
            color = colors['blue']
        elif flags & cv2.EVENT_FLAG_CTRLKEY:
            color = colors['red']
        
        cv2.circle(img, (x,y), 30, (0,0,0), -1)
        cv2.imshow(title, img)
        
cv2.setMouseCallback(title, onMouse)

while True:
    if cv2.waitKey(0) &0xFF == 27:
        break
cv2.destroyAllWindows()

이미지읽기

트랙바

슬라이드 모양의 인터페이스를 마우스로 움직여서 값을 입력받는 GUI 이다.

cv2.createTrackbar(trackbar_name, win_name, value, count, onChange) : 트랙바 생성
  • traackbar_name : 트랙바 이름
  • win_name : 트랙바를 표시할 창 이름
  • value : 트랙바 초기 값, 0-count 사이의 값
  • count : 트랙바 눈금의 개수, 트랙바가 표시할 수 있는 최대 값
  • onChange : TrackbarCallback, 트랙바 이벤트 핸들러 함수
TrackbarCallback(value) : 트랙바 이벤트 콜백 함수
  • value : 트랙바가 움직인 새 위치 값
pos = cv2.getTrackbarPos(trackbar_name, win_name)
  • trackbar_name : 찾고자 하는 트랙바 이름
  • win_name : 트랙바가 있는 창의 이름
  • pos : 트랙바 위치 값
import cv2
import numpy as np

win_name = 'Trackbar'

img = cv2.imread('./img/blank_500.jpg')
cv2.imshow(win_name, img)    # 초기 이미지 창에 표시

def onChange(x):
    print(x)         # 트랙바의 새로운 위치 값
    # 트랙바 위치 값
    r = cv2.getTrackbarPos('R', win_name)
    g = cv2.getTrackbarPos('G', win_name)
    b = cv2.getTrackbarPos('B', win_name)
    print(r, g, b)
    img[:] = [b,g,r]    # 기존 이미지에 새로운 픽셀 값 적용
    cv2.imshow(win_name, img)     # 새 이미지 창에 표시

cv2.createTrackbar('R', win_name, 255, 255, onChange)
cv2.createTrackbar('G', win_name, 255, 255, onChange)
cv2.createTrackbar('B', win_name, 255, 255, onChange)

while True:
    if cv2.waitKey(1) & 0xFF == 27:
        break
cv2.destroyAllWindows()
178
255 178 255
178
255 178 255
178
255 178 255
147
147 178 255
147

이미지읽기