본문 바로가기
데이터 과학 관련 스터디/OpenCV

[Open CV] 파이썬 이미지에 선/ 도형/ 글씨 입력하기

by inhovation97 2022. 3. 4.
본 글은 파이썬으로 만드는 OpenCV프로젝트 서적의 내용을 포스팅하는 내용입니다. 
2장 기본 입출력
해당 실습은 cv2 라이브러리를 이용하여 진행합니다.

1. 이미지에 선 긋기
2. 이미지에 사각형 그리기
3. 이미지에 다각형 그리기
4. 이미지에 원/타원/호 그리기
5. 이미지에 글씨 쓰기

개인적으로는 YOLO모델로 추론한 객체에 정보를 적어줄 때 이용했던 것 같습니다.

 

1. 이미지에 선 긋기

 

import cv2
import numpy as np

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

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

cv2.line(img, (50,50), (150,50), (255,0,0))
cv2.line(img, (200,50), (300,50), (0,255,0))
cv2.line(img, (350,50), (450,50), (0,0,255))

##### thickness 추가
# 하늘색 (파랑+초록) 
cv2.line(img, (100,100), (400,100), (255,255,0), 10)
# 분홍색
cv2.line(img, (100,150), (400,150), (255,0,255), 10)
# 노란색
cv2.line(img, (100,200), (400,200), (0,255,255), 10)
# 회색
cv2.line(img, (100,250), (400,250), (200,200,200), 10)
# 검은색
cv2.line(img, (100,300), (400,300), (0,0,0))

#### lineType 추가
# 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()

맨 첫 줄에 정의한 img 객체는 (255, 255, 255)색을 주어 흰 바탕의 도화지 이미지를 만든 것입니다.

 

cv2.line(img, start, end, color[, thickness, lineType]) - 직선그리기

입력 : img - 그림 그릴 대상 이미지(numpy배열)

        start - 선 시작 지점 좌표(x,y)

        end - 선 끝 지점 좌표(x,y)

        color - 선 색상, (B,G,R), 0~255 <- 주의할 것.

        thickness - 선 두께

        lineType - 선 그리기 형식

                      cv2.LINE_4 - 연결 선 알고리즘

                      cv2.LINE_8 - 연결 선 알고리즘

                      cv2.LINE_AA - 안티 앨리어싱( 계단 현상 없는 선 -> 가장 마지막 결과 확인 )

 

결과창

 

2. 이미지에 사각형 그리기

 

import cv2

img = cv2.imread('../CV2/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.rectangle 함수는 어느 지점이든 시작 지점과 그 반대 지점을 사용한다는 것이 특징

보통은 좌상단 꼭짓점과 우하단 꼭짓점 좌표릉 이용하는 경우가 많음.

 

cv2.rectangle( img, start, end, color[, thickness, lineType]) - 사각형 그리기

입력 : img - 그림 그릴 대상 이미지(numpy배열)

        start - 사각형 시작 꼭짓점(x,y)

        end - 사각형 지점 꼭짓점(x,y)

        color - 선 색상, (B,G,R), 0~255 <- 주의할 것.

        thickness - 선 두께 (-1은 색 채우기)

        lineType - 선 타입 cv2.line() 함수와 동일함

                      cv2.LINE_4 - 연결 선 알고리즘

                      cv2.LINE_8 - 연결 선 알고리즘

                      cv2.LINE_AA - 안티 앨리어싱( 계단 현상 없는 선 )

 

결과창

 

3. 이미지에 다각형 그리기

 

import cv2
import numpy as np

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

# 번개 모양 선 좌표
pts1 = np.array([[50,50], [150,150],[100,140], [200,240]])
# 삼각형 좌표
pts2 = np.array([[350, 50], [250, 200], [450, 200]], dtype = np.int32)
# 삼각형 좌표
pts3 = np.array([[150,300], [50, 450], [250,450]], dtype = np.int32)
# 5각형 좌표
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()

 

points 인자는 다각형을 그리기 위한 여러개의 꼭짓점 좌표를 numpy 배열 리스트 형식으로 전달합니다.

이 함수는 rectangle처럼 선 굵기 인자에 -1로 지정하는 색 채우기 효과는 지원하지 않습니다.

 

cv2.polylines( img, points, isClosed, color[, thickness, lineType]) - 다각형 그리기

입력 : img - 그림 그릴 대상 이미지(numpy배열)

        points - 꼭짓점 좌표 (numpy 배열 리스트)

        isClosed - 닫힌 도형 여부, T/F

        color - 색상, (B,G,R), 0~255 <- 주의할 것.

        thickness - 선 두께

        lineType - 선 타입 cv2.line() 함수와 동일함

                      cv2.LINE_4 - 연결 선 알고리즘

                      cv2.LINE_8 - 연결 선 알고리즘

                      cv2.LINE_AA - 안티 앨리어싱( 계단 현상 없는 선 )

 

결과창

 

4. 이미지에 원/타원/호 그리기

 

import cv2

img = cv2.imread('../CV2/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, 180, (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, 75) 아래 반원 그리기
cv2.ellipse(img, (450,300), (50,75), 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, 75), 45, 0, 180, (0,0,255))
# 원점 (400,425), 홀쭊한 타원45도 회전 후 위 반원 그리기
cv2.ellipse(img, (400,425), (50, 75), 45, 181, 360, (255,0,0))

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

 

완전한 동그라미를 그릴때는 circle함수가 좋습니다.

cv2.circle( img, center, radius, color[, thickness, lineType]) - 원 그리기

입력 : img - 그림 그릴 대상 이미지(numpy배열)

        points - 원점 좌표 (x, y)

        radius - 원의 반지름

        color - 색상, (B,G,R), 0~255 <- 주의할 것.

        thickness - 선 두께 (-1: 채우기)

        lineType - 선 타입 cv2.line() 함수와 동일함

                      cv2.LINE_4 - 연결 선 알고리즘

                      cv2.LINE_8 - 연결 선 알고리즘

                      cv2.LINE_AA - 안티 앨리어싱( 계단 현상 없는 선 )

 

cv2.ellipse( img, center, axes, angle, from, to, color[, thickness, lineType]) - 호/타원 그리기

입력 : img - 그림 그릴 대상 이미지(numpy배열)

        center - 원점 좌표 (x, y)

        axes - 기준 축 길이 -> 반지름을 튜플 형식으로 지정. (만약 (50, 150)이라면, x축 반지름: 50, y축 반지름: 150)

        angle - 기준 축 회전 각도

        from, to - 호를 그릴 시작 각도와 끝 각도

        color - 색상, (B,G,R), 0~255 <- 주의할 것.

        thickness - 선 두께 (-1: 채우기)

        lineType - 선 타입 cv2.line() 함수와 동일함

                      cv2.LINE_4 - 연결 선 알고리즘

                      cv2.LINE_8 - 연결 선 알고리즘

                      cv2.LINE_AA - 안티 앨리어싱( 계단 현상 없는 선 )

 

 

결과창

 

5. 이미지에 원/타원/호 그리기

 

import cv2

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

# sans-serif smallnormal X2
cv2.putText(img, 'Plain', (50,30), cv2.FONT_HERSHEY_PLAIN, 1, (0, 0,0))
# sans-serif normal
cv2.putText(img, 'Simplex', (50,70), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0,0))
# sans-serif bold
cv2.putText(img, 'DUPLEX', (50,100), cv2.FONT_HERSHEY_DUPLEX, 1, (0, 0,0))
# sans-serif normal X2
cv2.putText(img, 'Simplex', (200,110), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0,250))

#serif small
cv2.putText(img, "Complex Small", (50,180), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 0,0))
#serif normal
cv2.putText(img, "Complex", (50,220), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 0,0))
#serif bold
cv2.putText(img, "Triplex", (50,260), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 0,0))
#serif normal X2
cv2.putText(img, "Complex", (200,260), cv2.FONT_HERSHEY_TRIPLEX, 2, (0, 0,255))
#hand-writing snans-serif
cv2.putText(img, "Script Simplex", (50,330), cv2.FONT_HERSHEY_SCRIPT_SIMPLEX, 1, (0, 0,0))
#hand-writing serif
cv2.putText(img, "Script Complex", (50,370), cv2.FONT_HERSHEY_SCRIPT_COMPLEX, 1, (0, 0,0))

# sans-serif + italic
cv2.putText(img, "Plain Italic", (50,430), cv2.FONT_HERSHEY_PLAIN | cv2.FONT_ITALIC, 1, (0, 0,0))
# sarif + italic
cv2.putText(img, "Complex Italic", (50,470), cv2.FONT_HERSHEY_COMPLEX | cv2.FONT_ITALIC, 1, (0, 0,0))

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

 

point 좌표는 문자열의 좌측 하단을 기준으로 지정해야 합니다.

선택할 수 있는 글꼴의 종류는 cv2.FONT_HERSHEYS_로 시작하는 상수로 정해지는데, 

크게 세리프체 산세리프체 그리고 필기체가 있습니다. 세리프체는 한글 글꼴의 명조체처럼 글자 끝에 장식을 붙이는 글꼴이며, 산세리프체는 고딕체처럼 획에 튿별히 모양을 낸 것이 없는 글꼴입니다.

(sans는 불어로 없다 라는 의미이며, serif는 타이포그래피에서 획의 끝이 돌출된 부분을 말하는 것으로 산세리프는 세리프가 없다는 것을 의미)

OpenCV 상수에서는 상대적으로 단순한 모양인 산세리프체에 SIMPLEX를 복잡한 모양인 세리프체에는 COMPLEX라고 이름을 붙인 것을 알 수 있습니다.

 

cv2.putText( img, text, point, fontFace, fontSize, color [, thickness, lineType]) - 원 그리기

입력 : img - 그림 그릴 대상 이미지(numpy배열)

        text - 표시할 문자열

        point - 글씨를 표시할 좌표 (좌측 하단 기준)(x,y)

        fontFace - 글꼴

                      cv2.FONT_HERSHEY_PLAIN - 산세리프체 작은 글꼴

                      cv2.FONT_HERSHEY_SIMPLEX - 산세리프체 일반 글꼴

                      cv2.FONT_HERSHEY_DUPLEX - 산세리프체 진한 글꼴

                      cv2.FONT_HERSHEY_COMPLEX_SMALL - 세리프체 작은 글꼴

                      cv2.FONT_HERSHEY_COMPLEX - 세리프체 일반 글꼴

                      cv2.FONT_HERSHEY_TRIPLEX - 세리프체 진한 글꼴

                      cv2.FONT_HERSHEY_SCRIPT_SIMPLEX - 필기체 산세리프 글꼴

                      cv2.FONT_HERSHEY_SCRIPT_COMPLEX - 필기체 세리프 글꼴

                      cv2.FONT_ITALIC - 이탤릭체 플래그

        fontSize - 글꼴 크기

        color - 색상, (B,G,R), 0~255 <- 주의할 것.

        thickness - 선 두께 (-1: 채우기)

        lineType - 선 타입 cv2.line() 함수와 동일함

                      cv2.LINE_4 - 연결 선 알고리즘

                      cv2.LINE_8 - 연결 선 알고리즘

                      cv2.LINE_AA - 안티 앨리어싱( 계단 현상 없는 선 )

 

결과창

댓글