2020-02-29 20:18:05

opencv-python은 영상처리 및 컴퓨터비전에 관한 대표적인 패키지입니다. opencv-python의 유용한 함수들을 이 곳에 정리해보려고 합니다. 제가 자주 사용하는 함수들을 위주로 정리하도록 하겠습니다. 각 함수에 대해서 아주 상세히 다루지는 않겠지만, 기본적인 사용법과 이후 추가 검색을 위한 힌트는 얻으실 수 있을 것이라고 생각합니다.^^ 

 

1. 이미지 읽기: cv2.imread()

컬러 이미지를 읽으려면 cv2.IMREAD_COLOR를, 그레이스케일 모드로 읽으려면 cv2.IMREAD_GRAYSCALE을 입력해주시면 됩니다. 참고로 opencv-python에서 컬러이미지는 BGR 순서로 구성되어 있음을 주의하세요.^^

 

2. 이미지 컬러 공간 변환: cv2.cvtColor()

BGR 색공간을 gray-scale로 변환하고 싶은 경우에는 cv2.COLOR_BGR2GRAY를, BGR 색공간을 HSV 색공간으로 변환하고 싶은 경우에는 cv2.COLOR_BGR2HSV를 선택하시면 됩니다. 2개만 예로 들었는데 150개 이상의 색공간 변환 기능을 지원한다고 합니다. 

 

3. 이미지 사이즈 변경: cv2.resize()

이미지를 축소시킬 때는 보간법(interpolation) 설정을 cv2.INTER_AREA로 해주는 것을, 확대시킬 때는 cv2.INTER_CUBIC 또는 cv2.INTER_LINEAR를 사용할 것을 권장합니다. cv2.INTER_CUBIC보다는 cv2.INTER_LINEAR가 좀 더 빠릅니다. 

 

4. 이미지 보여주기: cv2.imshow()

보통 cv2.waitKey(0), cv2.destroyAllWindows()와 같이 다닙니다. 

 

5. 이미지 저장: cv2.imwrite()

 

위 다섯 함수들을 모두 사용한 예제 코드는 다음과 같습니다. 컬러 이미지를 읽은 후 그레이스케일로 변환했고, 그 이미지를 가로, 세로 각각 반으로 줄였고, 마지막으로 그것을 result.jpg라는 이름의 파일로 저장했습니다. 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import cv2
 
# 이미지 읽기
img_color = cv2.imread('test1.jpg', cv2.IMREAD_COLOR)
 
# 컬러 이미지를 그레이스케일로 변환
img_gray = cv2.cvtColor(img_color, cv2.COLOR_BGR2GRAY)
 
# 이미지 사이즈 변경
img_gray_reduced = cv2.resize(img_gray, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_AREA) # 가로, 세로 모두 반으로 줄이기
 
# 이미지 보여주기
cv2.imshow('color', img_color) # color라는 이름의 윈도우 안에 img_color라는 이미지를 보여줌
cv2.imshow('gray-scale', img_gray)
cv2.imshow('gray-scale reduced', img_gray_reduced)
 
cv2.waitKey(0)
cv2.destroyAllWindows()
 
# 이미지 저장
cv2.imwrite('result.jpg', img_gray_reduced) #img_gray_reduced를 result.jpg 이미지 파일로 저장
cs

 

실행해보면 다음과 같은 이미지들이 보여지고, 현재 디렉토리 내에 result.jpg라는 이미지 파일이 생성된 것을 알 수 있습니다. 원하는 결과가 제대로 나왔습니다. 

 

 

 

6. 선, 사각형, 원, 타원 그리기: cv2.line(), cv2.rectangle(), cv2.circle(), cv2.ellipse()

 

7. 텍스트 넣기: cv2.putText()

 

사각형 그리기와 텍스트 넣기를 이용해서 다음과 같은 결과 이미지를 만들어냈습니다. 마치 객체 검출 알고리즘이 찾아낸 것처럼 말이죠.ㅎㅎ 

 

 

필요한 코드는 다음과 같습니다. 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import cv2
 
# 이미지 읽기
img = cv2.imread('test1.jpg', cv2.IMREAD_COLOR)
 
# 사각형 그리기
img = cv2.rectangle(img, (35025), (610230), (25500), 3)
# 사각형을 그릴 이미지, 사각형의 좌측상단좌표, 우측하단좌표, 테두리 색, 테두리 두께
img = cv2.rectangle(img, (490180), (760360), (25500), 3)
img = cv2.rectangle(img, (390380), (670530), (25500), 3)
img = cv2.rectangle(img, (110180), (365480), (02550), 3)
 
# 텍스트 넣기
cv2.putText(img, 'Coffee', (360220), cv2.FONT_HERSHEY_SIMPLEX, 1, (25500), 2, cv2.LINE_AA)
# 텍스트를 넣을 이미지, 텍스트 내용, 텍스트 시작 좌측하단좌표, 글자체, 글자크기, 글자색, 글자두께, cv2.LINE_AA(좀 더 예쁘게 해주기 위해)
cv2.putText(img, 'Coffee', (500350), cv2.FONT_HERSHEY_SIMPLEX, 1, (25500), 2, cv2.LINE_AA)
cv2.putText(img, 'Coffee', (400520), cv2.FONT_HERSHEY_SIMPLEX, 1, (25500), 2, cv2.LINE_AA)
cv2.putText(img, 'Cake', (120470), cv2.FONT_HERSHEY_SIMPLEX, 1, (02550), 2, cv2.LINE_AA) 
 
 
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
cs

 

 

8. 이미지 채널 분리: cv2.split()

 

9. 이미지 채널 병합: cv2.merge()

 

cv2.split()과 cv2.merge()를 활용하여 다음과 같은 예제를 만들어봤습니다. HSV 색공간으로 변환한 후에 채널을 각각 분리해줍니다. 그리고 H 채널의 값을 모두 반으로 줄인 다음에 채널을 병합한 후에 BGR 색공간으로 다시 변환해줍니다. 참고로 HSV 색공간에서 H는 Hue 채널로 색상을, S는 Saturation 채널로 색상의 짙음과 옅음의 정도를, V는 Value 채널로 밝기를 담당합니다. 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import cv2
 
# 이미지 읽기
img = cv2.imread('test1.jpg', cv2.IMREAD_COLOR)
 
# 이미지 사이즈 축소
img = cv2.resize(img, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_AREA)
 
cv2.imshow('original image', img)
 
# 색공간 변환
img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # BGR 색공간을 HSV로
 
# 이미지 채널 분리
(H, S, V) = cv2.split(img)
 
cv2.imshow('Hue channel', H)
cv2.imshow('Saturation channel', S)
cv2.imshow('Value channel', V)
 
# Hue 채널값 변화주기
= H//2;
 
# 이미지 채널 병합
HSV = cv2.merge((H, S, V))
 
# 색공간 변환
img = cv2.cvtColor(HSV, cv2.COLOR_HSV2BGR)
 
cv2.imshow('new image', img)
 
cv2.waitKey(0)
cv2.destroyAllWindows()
cs

 

 

Hue 채널, 즉 색상을 담당하는 채널을 건드렸더니 색이 많이 바뀐 것을 확인할 수 있습니다. 하늘색을 띄던 커피가 연두색으로 바뀌었죠? 

 

10. 값의 범위 바꿔주기: cv2.normalize()

영상처리를 하다보면 값의 범위를 바꿔줘야할 경우가 꽤 자주 있습니다. 0-255 범위의 값을 0-1로 매핑해줘야할 때도 있고, 0-1 범위의 값을 0-255로 바꿔줘야할 때도 있습니다. cv2.normalize() 함수가 그런 용도로 사용될 수 있습니다. 아래 예제는 1부터 10까지의 정수를 0-1의 범위로 바꿔준 것과 0-255의 범위로 바꿔준 것을 포함합니다. 자주 사용할 일이 있을테니 꼭 기억해두세요.^^ 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import cv2
import numpy as np
 
= np.float64(np.array([12345678910]))
 
= np.float64(np.zeros((10)))
 
cv2.normalize(A, B, 01, cv2.NORM_MINMAX)
 
print("0에서 1로 normalize \n", B)
print()
 
cv2.normalize(A, B, 0255, cv2.NORM_MINMAX)
 
print("0에서 255로 normalize \n", B)
cs

 

실행 결과

 

끝까지 읽어주셔서 감사합니다. 수고하셨습니다. 항상 질문과 지적에는 열려있으니 댓글로 남겨주세요.^^ 

 

bskyvision의 추천글

[python] 파이썬 유용한 내장 함수들 10개 정리

[python] numpy 패키지 유용한 함수들 10개 정리

[python] numpy 다차원배열 클래스 객체 유용한 메소드 20개 정리

 

참고자료

[1] https://readthedocs.org/projects/opencv-python-tutroals/downloads/pdf/latest/