위의 대상 이미지는 3차원의 BGR컬러 데이터 (세로픽셀 x 가로필셀 x 색상채널: 4500 x 6000 x 3)를 나타내고,
색상채널은 R(빨강색) G(초록색) B(파랑색)의 데이터를 표현합니다.
위 이미지는 본 블로그 맨밑 출처 1에 가셔서 다운로드 받을 수 있습니다.
위의 대상 이미지가 이미 Jupyter Notebook에 "img_color" 라는 변수에 저장되어 있다고 가정합시다.
( 이미지 파일 불러오기는 본 블로그의 [Python 영상처리 기초 1] 이미지 파일 불러오기 참조 )
import cv2
import matplotlib.pyplot as plt
%matplotlib inline
# img_color = cv2.imread('path/filename', cv2.IMREAD_COLOR)
img_color = cv2.imread('national-cancer-institute-jdfn7Z03Qa4-unsplash.jpg', cv2.IMREAD_COLOR)
plt.axis("off")
plt.imshow(cv2.cvtColor(img_color, cv2.COLOR_BGR2RGB))
plt.show()
이제는 "img_color" 변수에 담긴 3차원 컬러 데이터를 각각의 색상채널로 분리하고서 결과를
출력해 봅시다. 단, 색상채널별로 분리된 각 이미지는 (NumPy arrays 속성의) 2차원 데이터 입니다.
또 한가지 주의할 점은 - [Python 영상처리 기초 1] 이미지 파일 불러오기 에서 강조 하였듯이 -
"img_color" 변수에서 색상을 저장하는 순서는 B(파랑색) G(초록색) R(빨강색) 입니다.
색상채널을 직접 3번이나 접근해서 BGR채널을 분리하고 합치는것은 불편하니 밑의 주석처리된
'alternative way' 의 코드와 같이 cv2.split( ), cv2.merge( ) 메소드를 이용하는 방법도 있습니다.
이 방법이 직관적이며 적은 코드를 사용하므로 cv2.split( ), cv2.merge( ) 명령어 사용을 추천 드립니다.
import numpy as np
# channel separation
#img_b,img_g,img_r = cv2.split(img_color) # alternative way
img_b = img_color[ : , : , 0] # Blue channel
img_g = img_color[ : , : , 1] # Green channel
img_r = img_color[ : , : , 2] # Red channel
print("data type of img_r: ", type( img_r[0,0])) # data type of pixel
# channel merging
#img_bgr = cv2.merge([img_b,img_g,img_r]) # alternative way
height, width, channel = img_color.shape
img_bgr = np.zeros( (height,width,channel), np.uint8 ) # make a color image
img_bgr[ : , : , 0] = img_b
img_bgr[ : , : , 1] = img_g
img_bgr[ : , : , 2] = img_r
# show result images
fig = plt.figure(figsize=(8,7))
img_arr = [cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB), img_r, img_g, img_b]
title_arr = ["Color image", "Red", "Green", "Blue"]
for i in range(4):
fig.add_subplot(2,2,i+1)
plt.axis("off")
if i==0: # Color image
plt.imshow(img_arr[i])
plt.title(title_arr[i])
else: # each channels
plt.imshow(img_arr[i],cmap='gray')
plt.title("{} channel".format(title_arr[i]))
plt.show()
위의 코드에 부연설명을 하자면, 각각의 색상의 채널을 분리할시 다음 코드와 같이
"img_color" 변수의 3번째 차원수를 직접 새로운 변수에 지정 하였지만
img_b = img_color[:, :, 0]
OpenCV의 명령어를 이용하면 더 간단하게 채널을 분리하고 합칠수 있습니다.
img_b,img_g,img_r = cv2.split(img_color) # split color channel
img_bgr = cv2.merge((img_b,img_g,img_r)) # make a color image
결과를 출력하는 부분이 좀 긴데, 동일한 코드를 for 문으로 반복하기 위해 출력 데이터와
그에따른 타이틀을 각각 "img_arr", "title_arr" 변수들에 저장해 두었습니다.
다시한번 강조하지만, BGR 채널 순서로 저장된 컬러 이미지 데이터를 RGB순서로 바꾸기 위해
cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)
cv2.COLOR_BGR2RGB 명령문을 입력하였습니다.
결과물의 색상채널별로 분리된 각각의 이미지에서 cell(세포)의 영역을 본다면,
3가지 색상으로 염색된 부분의 형태적 특징을 쉽게 관찰할 수 있습니다.
예를들어, cell(세포)의 윤곽이나 cell(세포)의 내, 외부에 분포한 어떠한 것을 이미지로부터 알아낼 수 있습니다.
이미지 분석시 특정 색상채널의 결과에 가중치를 두어 데이터를 분석하는 경우가 많습니다.
위의 색상별로 분리된 이미지에서 바탕이 되는 배경은 검은색으로 보이지만 실제로도 픽셀값 0을 갖는
검은색일까? 그리고 3차원 컬러 이미지에서 2차원의 gray scale 이미지로 변환할 수 있을까?
이미지에서 cell(세포)을 나타내는 픽셀값들의 분포는 어떠할까?
이에대한 답은 다음의 [Python 영상처리 기초 3] 이미지의 픽셀값 다루기 에서 참조 바랍니다.
출처1: https://unsplash.com/photos/jdfn7Z03Qa4
사진 작가: National Cancer Institute, Unsplash
Cells from cervical cancer – Splash에서 National Cancer Institute의 이 사진 다운로드
unsplash.com
'Python 영상처리 기초 with OpenCV' 카테고리의 다른 글
[Python 영상처리 기초 6] 선형 공간 필터링 - Average, Laplacian, Sobel filters (0) | 2023.08.08 |
---|---|
[Python 영상처리 기초 5] 이미지의 화질개선 - Normalization, Standardization (1) | 2023.08.02 |
[Python 영상처리 기초 4] 이미지의 픽셀값 다루기 - Crop, 선형연산 (2) | 2023.07.31 |
[Python 영상처리 기초 3] 이미지의 픽셀값 다루기 - Gray scale, Histogram, Binarization (0) | 2023.07.29 |
[Python 영상처리 기초 1] 이미지 파일 불러오기 - cv2.imread( ), plt.imshow( ) (0) | 2023.07.28 |