import cv2
import numpy as np
import math
from random import shuffle
도형그리기
캔버스 만들기
img = np.full((512, 512, 3), 255, np.uint8) 도형을 그리기 위한 공간을 생성한다. 위 코드는 (512, 512, 3)의 크기에 255라는 값으로 채워진 numpy array를 생성하는 코드이다. 데이터 타입은 uint8(0~255의 정수)이다. 여기서 배열을 채우는 값이 단일 상수로 되어있으면 흑백의 binary 값으로 인식하여 0이면 검은색, 255이면 흰색으로 채워지게 되고, (0, 0, 255)처럼 3개의 요소를 가진 벡터로 되어있으면 BGR 값으로 인식하여 해당 색으로 값이 채워지게 된다.
cv2.line(img, pt1, pt2, color[, thickness[, lineType[, shift]]]) → img
cv2.line(img, (0, 0), (511, 511), (255, 0, 0), 5)
1. img : 그림판
2. pt1 : 시작점
3. pt2 : 끝점
4. color : BGR 값으로 정해지는 선의 색 (파란색)
5. thickness : 선의 두께
6. lineType : 선을 화면에 표현하는 방법으로 디폴트로 cv2.LINE_8(8-connected)로 정해져 있다. 이 외에도 cv2.LINE_AA(anti-aliased) 등으로 설정 가능하다
cv2.rectangle(img, pt1, pt2, color[, thickness[, lineType[, shift]]]) → img
cv2.rectangle(img, (384, 8), (504, 200), (0, 255, 0), 10)
1. img : 그림판
2. pt1 : 좌상단 꼭지점
3. pt2 : 우하단 꼭지점
4. color : BGR 값으로 정해지는 선의 색 (초록색)
5. thickness : 선의 두께, 만약 이 값이 음수(-1)이면 도형 안쪽을 선의 색으로 채운다.
6. lineType : 선을 화면에 표현하는 방법으로 디폴트로 cv2.LINE_8(8-connected)로 정해져 있다. 이 외에도 cv2.LINE_AA(anti-aliased) 등으로 설정 가능하다
cv2.circle(img, center, radius, color[, thickness[, lineType[, shift]]]) → img
cv2.circle(img, (128, 128), 63, (0, 0, 255), -1)
1. img : 그림판
2. center : 원의 중심
3. radius : 원의 반지름
4. color : BGR 값으로 정해지는 선의 색 (빨간색)
5. thickness : 선의 두께, 만약 이 값이 음수(-1)이면 도형 안쪽을 선의 색으로 채운다.
6. lineType : 선을 화면에 표현하는 방법으로 디폴트로 cv2.LINE_8(8-connected)로 정해져 있다. 이 외에도 cv2.LINE_AA(anti-aliased) 등으로 설정 가능하다
cv2.ellipse(img, center, axes, angle, startAngle, endAngle, color[, thickness[, lineType[, shift]]]) → img
cv2.ellipse(img, (256, 256), (100, 50), 30, 90, 180, (255, 0, 255), -1)
1. img : 그림판
2. center : 타원의 중심
3. axis : 각각 장축과 단축의 반의 길이
4. angle : 타원이 기울어지는 각도, 시계방향으로 돈다.
5. startAngle : 타원을 그리기 시작하는 각도, 시계방향으로 돈다.
6. endAngle : 타원을 그리는데 마치는 각도, 시계방향으로 돈다.
7. color : BGR 값으로 채워지는 선의 색 (분홍색)
8. thickness : 선의 두께, 만약 이 값이 음수(-1)이면 도형 안쪽을 선의 색으로 채운다.
9. lineType : 선을 화면에 표현하는 방법으로 디폴트로 cv2.LINE_8(8-connected)로 정해져 있다. 이 외에도 cv2.LINE_AA(anti-aliased) 등으로 설정 가능하다
cv2.putText(img, text, org, fontFace, fontScale, color[, thickness[, lineType[, bottomLeftOrigin]]]) → img
font = cv2.FONT_HERSHEY_SCRIPT_SIMPLEX
1. FONT_HERSHEY_COMPLEX
2. FONT_HERSHEY_COMPLEX_SMALL
3. FONT_HERSHEY_DUPLEX
4. FONT_HERSHEY_PLAIN
5. FONT_HERSHEY_SCRIPT_COMPLEX
6. FONT_HERSHEY_SCRIPT_SIMPLEX
7. FONT_HERSHEY_SIMPLEX
8. FONT_HERSHEY_TRIPLEX
cv::HersheyFonts 참고
cv2.putText(img, 'OpenCV', (10, 500), font, 4, (0, 255, 255), 3)
1. img : 그림판
2. text : 넣고 싶은 텍스트
3. org : 텍스트 이미지의 좌하단 꼭짓점
4. fontFace : fontFace 폰트 스타일 지정.
5. fontScale : 폰트 크기를 지정
6. color : BGR 값으로 채워지는 선의 색 (노란색)
7. thickness : 폰트 굵기를 지정
8. lineType : 선을 화면에 표현하는 방법으로 디폴트로 cv2.LINE_8(8-connected)로 정해져 있다. 이 외에도 cv2.LINE_AA(anti-aliased) 등으로 설정 가능하다
def drawing():
img = np.full((512, 512, 3), 255, np.uint8)
cv2.line(img, (0, 0), (511, 511), (255, 0, 0), 5)
cv2.rectangle(img, (384, 8), (504, 200), (0, 255, 0), 10)
cv2.circle(img, (128, 128), 63, (0, 0, 255), -1)
cv2.ellipse(img, (256, 256), (100, 50), 30, 90, 180, (255, 0, 255), -1)
font = cv2.FONT_HERSHEY_SCRIPT_SIMPLEX
cv2.putText(img, 'OpenCV', (10, 500), font, 4, (0, 255, 255), 3)
cv2.imshow('drawing', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
drawing()
마우스로 도형 그리기
cv2.setMouseCallback(windowName, onMouse [, param])
cv2.setMouseCallback('paint', onMouse, param = img) setMouseCallback 마우스 이벤트를 처리하는 함수
1. 첫번째 인자에는 이미지를 띄울 윈도우의 이름을,
2. 두번째 인자에는 마우스 이벤트를 처리할 함수의 이름을 지정한다. 두번째 인자를 MouseCallback 함수라고 부른다.
3. 세번째 인자에는 Callback 함수에 전달되는 데이터를 지정한다.
MouseCallback :: def onMouse(event, x, y, flags, param)
setMouseCallback 함수에서 두번째 인자로 들어갈 MouseCallback 함수에는 총 5가지 인자를 입력으로 받는다. 첫번째 인자에는 MouseEventTypes이 들어간다. 다음과 같은 이벤트를 입력으로 받을 수 있다.
1. cv2.EVENT_MOUSEMOVE : 윈도우 위에서의 마우스 포인터 움직임
2. cv2.EVENT_LBUTTONDOWN : 왼쪽 마우스 버튼 누르기
3. cv2.EVENT_LBUTTONUP : 왼쪽 마우스 버튼 떼기
4. cv2.EVENT_LBUTTONDBLCLK : 왼쪽 마우스 버튼 더블클릭
cv::MouseEventTypes 참고
두번째 인자, 세번째 인자의 x, y에는 마우스 이벤트가 벌어진 위치를 확인한다.
네번째 인자에는 MouseEventFlags 타입이 들어간다. 다음과 같은 이벤트 발생시 생성된다.
1. cv2.EVENT_FLAG_LBUTTON : 왼쪽 마우스 버튼 누르기
2. cv2.EVENT_FLAG_CTRLKEY : CTRL 키 누르기
3. cv2.EVENT_FLAG_SHIFTKEY : SHIFT 키 누르기
4. cv2.EVENT_FLAG_ALTKEY : ALT 키 누르기
cv::MouseEventFlags 참고
마지막 인자에는 cv2.setMouseCallback()함수에서 전달받은 사용자 데이터가 전달된다. 아래 코드에서는 img가 전달된다.
b = [i for i in range(256)]
g = [i for i in range(256)]
r = [i for i in range(256)]
def onMouse(event, x, y, flags, param):
global img
if event == cv2.EVENT_LBUTTONDBLCLK:
shuffle(b), shuffle(g), shuffle(r)
cv2.circle(param, (x, y), 50, (b[0], g[0], r[0]), -1)
cv2.imshow('paint', img)
img = np.full((512, 512, 3), 0, np.uint8)
def mouseBrush():
global img
cv2.namedWindow('paint')
cv2.setMouseCallback('paint', onMouse, param=img)
while True:
cv2.imshow('paint', img)
if cv2.waitKey(0) & 0xFF == 27:
break
cv2.destroyAllWindows()
mouseBrush()
위 mouseBrush 함수는 더블클릭으로 반지름이 50인 원을 그리는 예제이다.
우선 np.full 함수를 이용해 검정색을 배경으로 하는 캔버스를 하나 만든다. 이 캔버스에 'paint'이름을 붙이고 'paint' 캔버스 위에서 마우스 이벤트 발생시 onMouse 함수를 불러와 기능을 수행하게 한다. 왼쪽 마우스 더블클릭 외 다른 이벤트 발생시 이를 무시하고, 왼쪽 마우스 더블클릭이 발생하면 (event == cv2.MOUSE_LBUTTONDBLCLK) 랜덤으로 BGR 값을 정한 후 해당 마우스 이벤트가 벌어진 위치에 반지름이 50인 원을 그린다.
마우스로 도형 그리기 2차
mode = True
img2 = np.full((512, 512, 3), 0, np.uint8)
drawing = False
ix, iy = -1, -1
B = [i for i in range(256)]
G = [i for i in range(256)]
R = [i for i in range(256)]
def onMouse(event, x, y, flags, param):
global ix, iy, drawing, mode, B, G, R ,img2
if event == cv2.EVENT_LBUTTONDOWN:
drawing = True
ix, iy = x, y
shuffle(B), shuffle(G), shuffle(R)
elif event == cv2.EVENT_MOUSEMOVE:
if drawing:
paint_img = img2.copy()
if mode:
cv2.rectangle(param, (ix, iy), (x, y), (B[0], G[0], R[0]), -1)
cv2.imshow('paint_mode', img2)
else:
r = (ix-x)**2 + (iy-y)**2
r = int(math.sqrt(r))
cv2.circle(param, (ix, iy), r, (B[0], G[0], R[0]), -1)
cv2.imshow('paint_mode', img2)
elif event == cv2.EVENT_LBUTTONUP:
if drawing:
drawing = False
def mouseBrush():
global mode, img2
cv2.namedWindow('paint_mode')
cv2.setMouseCallback('paint_mode', onMouse, param = img2)
while True:
cv2.imshow('paint_mode', img2)
k = cv2.waitKey(0) & 0xFF
if k == 27:
break
elif k == ord('m'):
mode = not mode
cv2.destroyAllWindows()
mouseBrush()
위 mouseBrush 함수는 처음에 더블클릭으로 직사각형을 그릴 부분을 지정하고 마우스를 옮긴 만큼 직사각형을 그린 후, 키보드에서 'm'을 눌러 직사각형을 그리던 것을 원으로 바꿔그리는 예제이다. 동작 원리는 위와 동일하다.
우선 np.full 함수를 이용해 검정색을 배경으로 하는 캔버스를 하나 만든다. 이 캔버스에 'paint'이름을 붙이고 'paint' 캔버스 위에서 마우스 이벤트 발생시 onMouse 함수를 불러와 기능을 수행하게 한다. 왼쪽 마우스 버튼을 누르는 이벤트 외 다른 이벤트 발생시 이를 무시하고, 해당 이벤트가 발생하면 (event == cv2.MOUSE_LBUTTONDOWN) 랜덤으로 BGR 값을 정한 후 해당 마우스 이벤트가 벌어진 위치에 직사각형의 좌상단 꼭지점의 위치를 확인한다. 이후 마우스를 움직이면 마우스를 움직인 곳이 우하단 꼭지점이 되어 그만큼의 직사각형이 그려지게 된다. 키보드에서 'm'을 누르면 직사각형이 아닌 원을 그리기 시작한다. 마찬가지로 마우스를 움직인만큼 원을 그린다.
'데이터 분석 & 시각화 > OpenCV' 카테고리의 다른 글
[OpenCV Practice 04] 트랙바 (Trackbar) (0) | 2020.08.11 |
---|---|
[OpenCV Programming] 디스크립터(Descriptor) (0) | 2020.08.10 |
[OpenCV Practice 02] 비디오 reading and writing (0) | 2020.08.08 |
[OpenCV Practice 01] 이미지 reading and writing (0) | 2020.08.07 |
[OpenCV practice] - 차준영 (0) | 2020.08.06 |
최근댓글