파이썬 opencv를 이용해 이미지에 도형 그리기
파이썬에서 opencv 라이브러리를 이용하면 이미지에 도형을 그리고 텍스트를 넣을 수 있습니다. 이 글의 앞 부분에 쓰인 코드는 주피터노트북에서 이미지를 출력하기 위한 코드입니다. 파이썬 파일 py에서 출력하거나 이미지를 저장하는 방법은 목차의 6번째 이미지 저장하기, opencv로 출력하기에 나와있습니다.
목차
사각형 그리기
- img : 도형을 그릴 이미지
- (x1,y1) : 사각형 왼쪽 위 점의 좌표
- (x2,y2) : 사각형 오른쪽 아래 점의 좌표
- (B,G,R) : 사각형 색깔 (파랑, 초록, 빨강 순)
- thickness : 선 두께, 채우기
- linetype: 선 타입
- shift: 소수 좌표 지정시 사용
가로 400픽셀 세로 400픽셀의 회색 이미지에 사각형을 그려보겠습니다.
import cv2
from PIL import Image
img = cv2.imread("input.png")
cv2.rectangle(img, (0, 100), (200, 200), (255,0,0), -1)
cv2.rectangle(img, (200, 300), (300, 400), (0,0,255), 2, cv2.LINE_AA)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = Image.fromarray(img)
display(img)

이미지의 좌표는 왼쪽 위가 (0,0)입니다. x좌표는 왼쪽으로부터 픽셀 수이고 y좌표는 위로부터의 픽셀 수 입니다. opencv에서 색은 BGR 형식을 따르기 때문에 (255,0,0)은 파랑이고 (0,0,255)가 빨강입니다. thickness가 클수록 선이 두꺼워지는데 음수를 넣으면 내부를 채웁니다.
원 그리기
- img : 도형을 그릴 이미지
- (x,y) : 원의 중심 좌표
- r : 원의 반지름
- (B,G,R) : 원 색깔 (파랑, 초록, 빨강 순)
- thickness : 선 두께, 채우기
- linetype: 선 타입
- shift: 소수 좌표 지정시 사용
import cv2
from PIL import Image
img = cv2.imread("input.png")
cv2.circle(img, (100, 200), 10, (255,255,0), -1,cv2.LINE_AA)
cv2.circle(img, (300, 200), 50, (0,255,255), 2)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = Image.fromarray(img)
display(img)

타원 그리기
- img : 도형을 그릴 이미지
- (x,y) : 타원의 중심 좌표
- (a,b) : 타원 가로길이, 세로길이
- rotation: 회전각도 (시계방향)
- (B,G,R) : 타원 색깔 (파랑, 초록, 빨강 순)
- thickness : 선 두께, 채우기
- linetype: 선 타입
- shift: 소수 좌표 지정시 사용
- img : 도형을 그릴 이미지
- (x,y) : 타원의 중심 좌표
- (r1,r2) : 타원 가로길이 절반, 타원 세로길이 절반
- rotation: 회전각도 (시계방향)
- startangle: 그릴 범위에 대한 시작 각도
- endangle: 그릴 범위에 대한 끝 각도
- (B,G,R) : 사각형 색깔 (파랑, 초록, 빨강 순)
- thickness : 선 두께, 채우기
- linetype: 선 타입
- shift: 소수 좌표 지정시 사용
import cv2
from PIL import Image
img = cv2.imread("input.png")
cv2.ellipse(img, (100,200), (100,200), 30, 0,180, (0,0,255), -1)
cv2.ellipse(img, ((300,200),(200,400),0),(0,255,0),6,cv2.LINE_AA)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = Image.fromarray(img)
display(img)

각도는 3시방향부터 시계방향으로 계산합니다. 빨간 타원의 경우 0~180으로 설정되어 아래부분만 그려진 이후에 시계방향으로 30도 회전되었습니다.
글자 넣기
- img : 도형을 그릴 이미지
- text : 텍스트 내용
- (x,y) : 텍스트 좌표 (문자열의 왼쪽 아래 좌표)
- font: 글씨체
- scale: 폰트 크기 (기본크기에 곱해짐)
- (B,G,R) : 타원 색깔 (파랑, 초록, 빨강 순)
- thickness : 선 두께
- linetype: 선 타입
import cv2
from PIL import Image
img = cv2.imread("input.png")
cv2.putText(img, 'Hello', (0,40), cv2.FONT_HERSHEY_SIMPLEX, 1.2, (255,255,255), 2)
cv2.putText(img, 'World', (50,100), cv2.FONT_HERSHEY_PLAIN, 2.4, (0,0,0), 3, cv2.LINE_AA)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = Image.fromarray(img)
display(img)

직선 그리기
- img : 도형을 그릴 이미지
- (x1,y1) : 시작 점 좌표
- (x2,y2) : 끝 점 좌표
- (B,G,R) : 타원 색깔 (파랑, 초록, 빨강 순)
- thickness : 선 두께
- linetype: 선 타입
- shift: 소수 좌표 지정시 사용
import cv2
from PIL import Image
img = cv2.imread("input.png")
cv2.line(img, (0,40), (70,300), (255,124,6), 8, cv2.LINE_8)
cv2.line(img, (200,80), (400,10), (13,43,104), 8, cv2.LINE_AA)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = Image.fromarray(img)
display(img)

이미지 저장하기, opencv로 출력하기
위에서는 주피터노트북에서 출력하기 위해 BGR을 RGB로 변환하고 array를 PIL 라이브러리를 이용해 Image로 display로 출력을 했습니다. py 파일로 이미지를 보거나 이미지를 저장할 때는 이런 변환과정은 필요가 없습니다.
cv2.imshow로 출력
import cv2
img = cv2.imread("input.png")
cv2.rectangle(img, (0, 100), (200, 200), (255,0,0), -1)
cv2.rectangle(img, (200, 300), (300, 400), (0,0,255), 2, cv2.LINE_AA)
cv2.imshow('sd', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
이 파이썬 파일을 실행하면 새로운 창에 이미지가 나오고 닫거나 아무 키를 눌러서 끌 수 있습니다.

cv2.imwrite로 저장
import cv2
img = cv2.imread("input.png")
cv2.putText(img, 'Hello', (0,40), cv2.FONT_HERSHEY_SIMPLEX, 1.2, (255,255,255), 2)
cv2.putText(img, 'World', (50,100), cv2.FONT_HERSHEY_PLAIN, 2.4, (0,0,0), 3, cv2.LINE_AA)
cv2.imwrite('output.png',img)
주피터노트북이던 파이썬 파일이던 cv2.imwrite로 저장할 수가 있습니다.
opencv 도형 그리기를 이용해 YOLO같은 객체탐지나 insightface의 얼굴 탐지, 얼굴 인식 등을 쉽게 시각화할 수 있고 도형으로 이미지의 특정 탐지 대상을 가리는데 이용할 수 있습니다.