일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- list
- Github
- numpy
- Google Excel
- math
- Google Spreadsheet
- django
- array
- Excel
- google apps script
- Apache
- PySpark
- gas
- PANDAS
- SQL
- Java
- Redshift
- GIT
- PostgreSQL
- Tkinter
- Python
- c#
- matplotlib
- string
- dataframe
- Mac
- Kotlin
- hive
- 파이썬
- Today
- Total
달나라 노트
Python opencv : opencv로 간단한 색상 이미지 생성하기 본문
opencv는 이미지 처리 기능, 머신러닝 등의 기능을 제공하는 툴 입니다.
opencv를 이용해 간단하게 원하는 크기의 원하는 색상의 이미지를 만들어봅시다.
이를 위해선 numpy array가 필요합니다.
import numpy as np
import cv2
arr_for_img = np.zeros(shape=(800, 500), dtype=float) # 행 개수 800개, 열 개수 500개의 0으로 채워진 2차원 array 생성
print(arr_for_img)
cv2.imwrite('img_black.png', arr_for_img) # array를 이용하여 png image 생성
-- Result
[[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]
...
[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]]
위 코드를 보면 먼저 zeros() method를 이용하여 0으로 채워진 행 개수 800개, 열 개수 500개의 array를 만듭니다.
그리고 이를 cv2 (cv2는 opencv를 의미합니다.)의 imwrite() method를 이용해서 img_black.png라는 이미지를 만듭니다.
생성된 이미지를 보면 위와 같습니다.
500 x 800 크기의 이미지가 만들어졌죠.
그리고 이 이미지는 오로지 검은색으로 칠해져 있습니다.
일단 이미지는 2차원이므로 2차원 array가 필요합니다.
그리고 array에 속해있는 각각의 단일 요소는 해당 위치에서의 pixel을 의미하죠.
0 -> 검정
255 -> 흰색
이렇게 되며 0에서 숫자가 높아질수록 점점 회색으로 변하다가 255에 접근할수록 흰색을 나타내게 됩니다.
또한 array를 만들 때 행 = 800개, 열 = 500개의 array를 만들었는데,
따라서 생성된 이미지도 행이 800개로 더 길며, 열이 500개로 좀 더 짧은 이미지가 생성되었습니다.
import numpy as np
import cv2
arr_for_img = np.array([0])
print(arr_for_img)
cv2.imwrite('img_black.png', arr_for_img)
-- Result
[0]
그래서 위 코드는 array가 [0] 이므로
1 pixel x 1 pixel 크기의 이미지를 만들게 됩니다.
아래 코드는 세로 길이 800 pixel, 가로 길이 500 pixel의 흰색 이미지를 생성하는 코드입니다.
import numpy as np
import cv2
arr_for_img = np.ones(shape=(800, 500), dtype=float) # 행 개수 800개, 열 개수 500개의 1로 채워진 2차원 array 생성
print(arr_for_img)
arr_for_img = arr_for_img * 255 # array 전체에 255를 곱하여 모든 요소 1을 255로 변경.
print(arr_for_img)
cv2.imwrite('img_white.png', arr_for_img) # png image 생성
-- Result
[[1. 1. 1. ... 1. 1. 1.]
[1. 1. 1. ... 1. 1. 1.]
[1. 1. 1. ... 1. 1. 1.]
...
[1. 1. 1. ... 1. 1. 1.]
[1. 1. 1. ... 1. 1. 1.]
[1. 1. 1. ... 1. 1. 1.]]
[[255. 255. 255. ... 255. 255. 255.]
[255. 255. 255. ... 255. 255. 255.]
[255. 255. 255. ... 255. 255. 255.]
...
[255. 255. 255. ... 255. 255. 255.]
[255. 255. 255. ... 255. 255. 255.]
[255. 255. 255. ... 255. 255. 255.]]
결과는 위와 같습니다.
import numpy as np
import cv2
arr_for_img = np.array(
[
[(10, 100, 200,)] # (150, 200, 100,)이 하나의 pixel에 대한 BGR값을 의미.
]
)
print(arr_for_img)
cv2.imwrite('img_test.png', arr_for_img)
-- Result
[[[ 10 100 200]]]
array에 있는 하나하나의 단일 요소는 하나의 픽셀을 의미한다고 했습니다.
RGB를 이용하면 각각의 pixel은 단순 흰색, 검은색, 회색 뿐 아니라 다양한 색상을 가질 수 있습니다.
그래서 위 코드는 (10, 100, 200,)이라는 하나의 요소를 가지고 있는데
이 말은 1개의 pixel을 가지고 있으며 해당 pixel의 BGR값은 B = 10, G = 100, R = 200이라는 것입니다.
주의할 점은 cv2에서 기본 color system은 RGB가 아니라 BGR입니다.
RGB와 BGR은 사실상 동일한 체계인데 순서만 반대로 되어있습니다.
결과로 생성된 이미지를 보면 1 pixel짜리 이미지라 잘 보이진 않지만 확대해봤을 때 아래와 같습니다.
B = 10, G = 100, R = 200 값에 대한 색을 찾아보면 위같은 주황색이 나옵니다.
따라서 위처럼 1 pixcel 크기의 주황색 이미지가 생성된 것입니다.
실제로 B = 10, G = 100, R = 200 에 대한 색상을 보면 예상대로 주황색이 나오는 것을 알 수 있습니다.
근데 좀 불편합니다.
왜냐면 보통 사용하는 color system은 RGB인데 매번 순서를 반대로 생각해서 BGR값을 전달하기엔 좀 귀찮습니다.
위 예시도 color code로서 (10, 100, 200,)를 전달했는데
사실 제가 원한건 일반적인 RGB 체계에서 R = 10, G = 100, B = 200 인 color를 얻고 싶었던 것이었습니다.
다만 cv2는 BGR 체계를 사용하기 때문에 전달된 색상 인자 (10, 100, 200,)를 B = 10, G = 100, G = 200로 받아들인 것이었죠.
만약 cv2의 BGR color 체계를 RGB로 바꾸고 싶으면 다음과 같은 방법을 사용하면 됩니다.
import numpy as np
import cv2
arr_for_img = np.array(
[
[(10, 100, 200,)] # (150, 200, 100,)이 하나의 pixel에 대한 BGR값을 의미.
]
)
cv2.imwrite('img_test.png', arr_for_img) # cv2 체계 하에서 이미지 생성
img = cv2.imread('img_test.png') # 생성된 이미지 읽음
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 생성된 이미지의 color를 BGR에서 RGB로 변환
cv2.imwrite('img_test_2.png', img) # RGB 체계로 변환된 이미지 생성
위 코드를 보면 지금까지 본 방식으로 cv2를 이용하여 이미지를 생성한 후
그 이미지의 color 체계를 BGR에서 RGB로 변경합니다.
color 체계의 변경은 cv2.cvtColor() method를 이용해서 할 수 있습니다.
그 결과로 생성된 img_test_2.png를 보면 위와 같습니다.
(10, 100, 200,)라는 색상을 전달한 것은 똑같은데 결과로 만들어진 이미지의 색상이 달라졌죠.
BGR 체계에서는 (10, 100, 200,)이 B = 10, G = 100, R = 200으로 간주되지만,
RGB 체계에서는 (10, 100, 200,)이 R = 10, G = 100, B = 200으로 간주되기 때문입니다.
실제로 R = 10, G = 100, B = 200의 색상을 봐보면 위처럼 파란 색이 나오는 것을 알 수 있죠.
아래 코드는 행 개수 10 pixel, 열 개수 10 pixel의 array를 생성하고
각 요소는 3개짜리 array로 만들어서 하나의 요소가 RGB값을 가지도록 했습니다.
그리고 여기에 0~255중 랜덤한 값을 곱해서 모든 pixel의 RGB 요소가 다 랜덤이 되게 합니다.
이렇게 되면 모든 pixel의 RGB값이 랜덤하게 결정되겠죠.
import numpy as np
import cv2
arr_test = np.ones(shape=(10, 10, 3))
row_cnt = arr_test.shape[0]
col_cnt = arr_test.shape[1]
for row_idx in range(row_cnt):
for col_idx in range(col_cnt):
arr_test[row_idx][col_idx][0] = arr_test[row_idx][col_idx][0] * (np.random.rand() * 255)
arr_test[row_idx][col_idx][1] = arr_test[row_idx][col_idx][1] * (np.random.rand() * 255)
arr_test[row_idx][col_idx][2] = arr_test[row_idx][col_idx][2] * (np.random.rand() * 255)
cv2.imwrite('img_test.png', arr_test)
그 결과로 생성된 이미지를 확대해보면 다음과 같습니다.
가로 세로 총 10 pixel씩 있고, 모든 pixel은 랜덤한 색상을 가지게 되죠.
아래 코드는 동일한 내용을 pixel의 행 개수, 열 개수를 각각 800, 500으로 늘린 코드입니다.
import numpy as np
import cv2
arr_test = np.ones(shape=(800, 500, 3))
row_cnt = arr_test.shape[0]
col_cnt = arr_test.shape[1]
for row_idx in range(row_cnt):
for col_idx in range(col_cnt):
arr_test[row_idx][col_idx][0] = arr_test[row_idx][col_idx][0] * (np.random.rand() * 255)
arr_test[row_idx][col_idx][1] = arr_test[row_idx][col_idx][1] * (np.random.rand() * 255)
arr_test[row_idx][col_idx][2] = arr_test[row_idx][col_idx][2] * (np.random.rand() * 255)
cv2.imwrite('img_test.png', arr_test)
그 결과는 다음과 같습니다.
모든 pixel이 불규칙적으로 각자의 색상을 가지고 있는 것을 볼 수 있죠.