이전 글에서는 히스토그램을 이용한 1D 분석에 대하여 작성하였다 

1D 히스토그램을 이용하면 Gray scale로 이미지의 밝기 분포를 볼 수 있고 

Color scale을 통해 R,G,B 값의 분포를 확인할 수 있다. 

 

이번 글에서는 2D Histogram을 이용한 채도( saturation ), 색상(Hue) 에 대하여 분석하기 앞서
HSV - Hue, Saturation, Value 포멧에 대하여 설명하겠다 

1. HSV Color space 

  • Hue - 색상 : 일반적인 색깔을 의미한다 . HSV 포멧에서는 각도로 표현된다 0º 부터 120º 마다 각각 Red Green Blue를 뜻한다 
  • Saturation - 채도 : 색의 순수성을 의미한다. 색이 짙다 흐리다로 표현된다 HSV 포멧에서 중심에서 바깥쪽으로 이동하면 채도가 높다 
  • Value - 명도 : 밝기를 의미한다. HSV 포멧에서 수직측의 깊이로 표현된다 값이 작을 수록 어둡다  
import cv2
import numpy as np
from matplotlib import pyplot as plt

origin_image = cv2.imread('puppy.jpg')
hsv_image = cv2.cvtColor(origin_image, cv2.COLOR_BGR2HSV)
image = np.concatenate((origin_image,hsv_image), axis=1)

print('원본 : \t',origin_image[0,0,:])
print('hsv : \t',hsv_image[0,0,:])

cv2.imshow('HSV', image)
cv2.waitKey(0)

BGR과 HSV 포멧의 imshow

  • BGR 포멧과 HSV 포멧을 imshow를 통해 보여봤다 hsv 포멧에서 이미지의 색상이 이상하게 변하는것은 현재 imread가 hsv 포멧을 생각안하고 BGR 포멧이라고 인식하여 읽어왔기 때문이다 

  • 각 원본 이미지와 hsv 포멧의 가장 왼쪽 위의 값을 찍어보면 다음과 같다 각각  B,G,R를 뜻하던 값이 H,S,V를 뜻하는 값으로 변경되었다
  • 원본에서 눈으로 봤을 때 하얀색과 가깝다 그렇기 때문에 BGR값이 모두 높은 220대가 나왔다 
  • HSV의 값은 120의 H 값은 위의 HSV 색상 공간 그림을 봤을 떄는 초록색의 방향이다 하지만 S의 값이 11이라는 낮은 값이 나와 채도는 의미가 낮아졌고 다음 V의 값이 232로 높은 값이 나와 밝은 값이라고 알 수 있다.
  • 강아지의 눈동자 부분의 값을 찍어보았다 BGR의 값이 전체적으로 낮아져 어두운 색상을 의미한다 
  • HSV의 경우 밝기를 뜻하는 V의 값이 낮아져 어두운 부분이라고 알 수 있다.

 

2. 이미지 값 조절 

  • 이미지에서 각 포멧의 값을 늘리거나 줄이는 방법을 이용하여 이미지의 특정 부분을 수정할 수 있다 
  • cv2.add(image, value_array), cv2.subtract(image, value_array)
  • 각 함수의 첫번쨰 파라미터는 변경할 이미지
  • 두번째 파라미터는 더하거나 빼거나 할 값이다
  • cv2.add, cv2.subtract에서는 0이하의 값들은 모두 0으로 취급하고 255이상의 값은 모두 255로 취급한다
import cv2
import numpy as np
from matplotlib import pyplot as plt

origin_image = cv2.imread('puppy.jpg')
hsv_image = cv2.cvtColor(origin_image, cv2.COLOR_BGR2HSV)

val = 100
array = np.full(hsv_image.shape, (0,0,val), dtype=np.uint8)

val_add_image = cv2.add(hsv_image, array)

print('BGR : \t',origin_image[55,116,:])
print('hsv : \t',hsv_image[55,116,:])
print('hsv 밝기(v) 증가 : \t',val_add_image[55,116,:])

val_add_image = cv2.cvtColor(val_add_image, cv2.COLOR_HSV2BGR)
image = np.concatenate((origin_image,val_add_image), axis=1)

cv2.imshow('add, subtract', image)
cv2.waitKey(0)

  • numpy 를 이용하여 이미지와 shape같은 배열을 생성한 뒤 이미지와 생성된 배열을 합한다 
  • 여기서 중요한 점은 생성한 배열의 dtype이다 
  • imread는 이미지 데이터를 불러올 때 기본 dtype이 uint8로 되어있다 그렇게 때문에 배열을 생성할 때도 dtype을 uint8로 설정해 줘야 더하거나 뺄때 type mismatch가 발생하지 않는다 
  • 강아지 사진을 불러와 HSV 포멧으로 변경한 후 HSV의 V값인 밝기를 100만큼 증가시켰다 
  • 증가시킨뒤 눈으로 확인하기 위해 다시 BGR 포멧으로 변경한 후 imshow 하였다
     
  • 강아지의 눈 부분의 값 변화를 체크해 보겠다
  • 보다시피 HSV 각각에 0, 0, 100의 값을 추가하였기 때문에 밝기 증가 hsv 에서 V의 값만 100이 증가하였다 

3. 특정 부분 이미지 값 변경

  • 이번에는 특정 부분의 밝기만 변경해 보자 
  • 위에서 말했듯이 cv2.add, cv2.subtract 에서는 0이하의 값은 모두 0으로 취급한다 
import cv2
import numpy as np
from matplotlib import pyplot as plt

origin_image = cv2.imread('puppy.jpg')
hsv_image = cv2.cvtColor(origin_image, cv2.COLOR_BGR2HSV)

val = 255

mask = hsv_image[:50,:100,:]

array = np.full(mask.shape, (0,0,val), dtype=np.uint8)

sub_mask_image = cv2.subtract(mask, array)

hsv_image[:50,:100,:] = sub_mask_image

val_sub_image = cv2.cvtColor(hsv_image, cv2.COLOR_HSV2BGR)

print("원본 bgr \t:",origin_image[0,0,:])
print("변환 bgr \t:",val_sub_image[0,0,:])

image = np.concatenate((origin_image,val_sub_image), axis=1)

cv2.imshow('add, subtract', image)
cv2.waitKey(0)

  • 원본 이미지에서 특정 부분을 선택하여 해당 부분의 HSV- V의 값을 255만큼 뺏다
  • 특정 부분을 다시 원본 이미지에 대입하였다 
  • V의 값이 0이 되었기 때문에 BGR 포멧으로 다시 변환한 후 해당 영역의 값을 확인 해보면 BGR 모두 0이 된것을 확인할 수 있다 

+ Recent posts