달나라 노트

Python opencv : opencv로 간단한 색상 이미지 생성하기 본문

Python/Python opencv

Python opencv : opencv로 간단한 색상 이미지 생성하기

CosmosProject 2024. 3. 7. 02:08
728x90
반응형

 

 

 

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 크기의 주황색 이미지가 생성된 것입니다.

 

https://rgbcolorpicker.com/

실제로 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으로 간주되기 때문입니다.

 

https://rgbcolorpicker.com/

실제로 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이 불규칙적으로 각자의 색상을 가지고 있는 것을 볼 수 있죠.

 

 

 

 

 

728x90
반응형
Comments