2. [Python] Color Channel
1. Gray Channel
img_gray = cv2.imread(path,cv2.IMREAD_GRAYSCALE)
img = cv2.imread(path,cv2.IMREAD_COLOR)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
fig,ax = plt.subplots(1,2, figsize=(6,4))
ax[0].imshow(img)
ax[0].set_title('Color Image')
ax[0].axis('off')
ax[1].imshow(img_gray, cmap='gray')
ax[1].set_title('Color Image')
ax[1].axis('off')
plt.tight_layout()
plt.show()
- matplotlib으로 읽으면 RGB, OpenCV로 읽으면 BGR이다.
2. RGB Channel
fig,ax = plt.subplots(2,2, figsize=(4,3))
ax[0,0].imshow(img)
ax[0,0].axis('off')
ax[0,0].set_title('Origin')
colors = ['Reds', 'Greens', 'Blues']
for i,color in enumerate(colors,start=1):
r,c = i//2,i%2
ax[r,c].imshow(img[:,:,i-1], cmap=f'{color}_r')
ax[r,c].axis('off')
ax[r,c].set_title(f'{color} Channel')
plt.tight_layout()
plt.show()
- 컬러 매핑이 반대로 되어있어서 cmap 지정할 때, _r을 붙여서 색상 반전을 시켜준다.
- 이러면 하늘색 배경에서 Blue Channel을 보면 배경의 흰색으로 밝기가 높게 나오는 것을 확인할 수 있다.
- 각 채널에서 밝은 부분들이 밝게 나타난 것을 확인할 수 있다.
3. HSV Channel
img_hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
fig, ax = plt.subplots(2,2, figsize=(4,3))
ax[0,0].imshow(img)
ax[0,0].axis('off')
ax[0,0].set_title('Origin')
colors = ['Hue', 'Saturation', 'Value']
for i,color in enumerate(colors,start=1):
r,c = i//2,i%2
ax[r,c].imshow(img_hsv[:,:,i-1], cmap='gray')
ax[r,c].axis('off')
ax[r,c].set_title(f'{color} Channel')
plt.tight_layout()
plt.show()
- Hue는 색조라서 컬러 팔레트를 외우고 있지 않으면 값을 조정하면서 확인하기 어렵다.
- 트랙바를 띄워서 할 수 있긴 한데, 보통은 Saturation이나 Value를 위주로 건드린다.
img_hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
hue, saturation, value = cv2.split(img_hsv)
saturation_added = cv2.add(saturation, 50)
value_added = cv2.add(value, -50)
img_add = cv2.merge([hue, saturation_added, value_added])
img_add = cv2.cvtColor(img_add, cv2.COLOR_HSV2RGB)
fig,ax = plt.subplots(1,2,figsize=(12,6))
ax[0].imshow(img)
ax[0].set_title('Original')
ax[0].axis('off')
ax[1].imshow(img_add)
ax[1].set_title('Adjusted HSV')
ax[1].axis('off')
plt.tight_layout()
plt.show()
- 채도를 높여서 조금 더 원색처럼 진해진 모습을 볼 수 있다.
- 밝기는 전체적으로 낮아진 모습을 볼 수 있다.
- 명암의 구분이 확실해졌다.
각각 차례대로 채도, 밝기의 변화
4. YCbCr
img_ycbcr = cv2.cvtColor(img, cv2.COLOR_RGB2YCrCb)
y,cr,cb = cv2.split(img_ycbcr)
fig,ax = plt.subplots(2,2,figsize=(10, 8))
ax[0,0].imshow(img_gray, cmap='gray')
ax[0,0].axis('off')
ax[0,0].set_title('Gray')
channels = [('Y Channel', y), ('Cr Channel', cr), ('Cb Channel', cb)]
for i, (title, channel) in enumerate(channels, start=1):
r,c = i//2,i%2
ax[r,c].imshow(channel, cmap='gray')
ax[r,c].axis('off')
ax[r,c].set_title(title)
plt.tight_layout()
plt.show()
- Y(luma) 이미지는 gray 이미지의 밝기인 (R+G+B)/3이 아니라 인간의 지각능력을 고려해 G,R,B 순서대로 가중치를 둡니다. (luma = 0.2126 * R + 0.7152 * G + 0.0722 * B)
- 보통 YCbCr이라 하는데, OpenCV에서는 Cr이 먼저나온다.
- RGB와 마찬가지로, Chroma Red, Blue도 해당 색상이 밝으면 흰색으로 나온다.
- 밝기 Y는 Origin이랑 같은 모습을 확인할 수 있다.
- Cr의 경우에는 사과의 빨간 부분이 밝은 모습을 확인할 수 있다.
- Cb의 경우에는 배경의 부분의 밝은 모습을 확인할 수 있다.
RGB 이미지에서 Ycbcr 이미지 변환
원본 이미지를 프로세싱 할 때 3채널 이미지에서 밝기 성분만 건드릴 때(히스토그램 스트레칭 등)가 있는데 채널별로 밝기를 추출해서 프로세싱 할 수도 있지만 밝기값만 따로 빼내어 프로세싱을 하기도 합니다.
# %% 5.Ycbcr
cvt = np.array([[0.299, 0.587, 0.114],
[-0.169, -0.331, 0.499],
[0.499, -0.418, -0.0813]])
img1 = img.copy()
h,w,d = img.shape
for i in range(h) :
for j in range(w) :
img1[i,j,0] = sum(img1[i,j] * cvt[0])
img1[i,j,1] = sum(img1[i,j] * cvt[1])+128
img1[i,j,2] = sum(img1[i,j] * cvt[2])+128
img_ycbcr = img1.astype(dtype=np.uint8)
- YCbCr 변환행렬에서 크로마에는 128을 더해주면 변환행렬이 만들어진다. (YCbCr도 쓰이는 곳 마다 변환 식이 약간 다르게 생겨서 배운 내용과 같은 형태로 진행)
- 2중 for문을 통해서 픽셀에 접근하고 채널성분과 변환행렬 곱해주고 uint8로 변환.
- 아무튼 컬러채널 접근과 색공간 변환에 대해서 알아보기.
- 이미지 데이터 다룰 때 넘파이로 접근을 해서 메서드가 아니라 직접 구현하는 경우도 많기 때문에 공부할 겸 변환하기.
- cv2 method에 대부분 함수가 있긴 하지만 할줄은 알아야한다.
'Machine Learning > Image Processing' 카테고리의 다른 글
8. [Python] Morpological Transfomation (0) | 2022.08.15 |
---|---|
7. [Python] Thresholding (0) | 2022.08.08 |
6. [Python] Image Compression (0) | 2022.08.05 |
5. [Python] Histogram Modeling (0) | 2022.07.28 |
4. [Python] Frequency Domain (0) | 2022.07.22 |
3. [Python] Spatial Domain (0) | 2022.07.13 |
1. Color Space (0) | 2022.07.07 |
댓글