Deep Learning/Computer Vision

Histograms with OpenCV

해파리냉채무침 2023. 7. 16. 17:54

이미지에 RGB가 얼마나 있는지 시각화를 통해 알아보는 작업을 하겠습니다

dark_horse = cv2.imread('../DATA/horse.jpg') #original bgr opencv
show_horse = cv2.cvtColor(dark_horse, cv2.COLOR_BGR2RGB) #converted to rgb for show

rainbow = cv2.imread('../DATA/rainbow.jpg')
show_rainbow =cv2.cvtColor(rainbow, cv2.COLOR_BGR2RGB)

blue_bricks = cv2.imread('../DATA/bricks.jpg')
show_bricks = cv2.cvtColor(blue_bricks, cv2.COLOR_BGR2RGB)

오리지널 사진1과 BGR이 디폴트이기 때문에 RGB로 열리게 설정하는 사진2 각각 두개씩 열어줌

plt.imshow(show_horse)

plt.imshow(dark_horse)

RGB로 설정하니 시퍼런 말 한마리가 나온다

plt.imshow(show_rainbow)

plt.imshow(show_bricks)

OpenCV histogram

cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])

images: 이미지는 unit8 또는 float32의 타입이 되어야한다

channels: 컬러 채널로 회색으로 매핑된 그레이스케일 이미지면 [0], 컬러 이미지면BGR 0,1,2 중 하나가 나올 것이다 

mask: 마스크 이미지로 풀 이미지의 히스토그램을 찾으려면 None 을 부여해야함. 만약 이미지의 특정부분만을 보고싶으면 마스크를 부여해준다.

histSize: 풀 스케일로 256을 부여해준다

ranges: 최소최대범위로 [0,256] 0에서 255까지를 부여한다.

 

파란색 벽돌의 히스토그램을 살펴보자

hist_values = cv2.calcHist([blue_bricks],channels=[0],mask=None,histSize=[256],ranges=[0,256])

컬러채널 인덱스0은 blue, 마스크 변수옵션(이미지 일부사용하고 싶을때  사용),사이즈 기본적으로 상한값,0에서 255을 부여함

hist_values.shape

(256,1)

plt.plot(hist_values)

파란벽돌의 이미지는 밝은색의 분포가 크다는 것을 알 수 있다. 검은색(0) 이미지는 전무하다

hist_values = cv2.calcHist([dark_horse],channels=[0],mask=None,histSize=[256],ranges=[0,256])
plt.plot(hist_values)

시퍼런 말의 분포는 검은 배경이 많아서 그런지 0의 분포가 가장 많다

img = blue_bricks
color = ('b','g','r')
for i,col in enumerate(color): #각 컬러의 히스토그램 기능을 각 컬러마다 한번씩, 총 3번 불러오려고함
    histr = cv2.calcHist([img],[i],None,[256],[0,256]) #none은 마스크 없는 것
    plt.plot(histr,color = col) #col은 b,g,r
    plt.xlim([0,256])
plt.title('Blue Bricks Image')
plt.show()

파란색 벽돌사진의 RGB를 각각 보면 파란색이 가장 많이 분포함을 알 수 있음, (꼭짓점이 높음)

img = rainbow
color = ('b','g','r')
for i,col in enumerate(color):
    histr = cv2.calcHist([img],[i],None,[256],[0,256])
    plt.plot(histr,color = col)
    plt.xlim([0,256])
plt.title('Rainbow Image')
plt.show()

레인보우 이미지의 히스토그램은 골고루 분포되어 있음을 알 수 있다

이제 마스킹을 통해 이미지의 특정 부분을 분석해보자

img = rainbow
mask = np.zeros(img.shape[:2], np.uint8)
mask[300:400, 100:400] = 255
plt.imshow(mask,cmap='gray')

0으로 가득채워 검은색으로 만들고, image.shape의 index 0,1까지만 선택하여 X와 Y차원의 마스크만 살펴본다. 2차원의 마스크를 만들어서 3개의 다른 채널로 확장한다. 하얀색 직사각형으로 마스크를 만든다

masked_img = cv2.bitwise_and(img,img,mask = mask) #마스킹된 이미지
show_masked_img = cv2.bitwise_and(show_rainbow,show_rainbow,mask = mask)
plt.imshow(show_masked_img)

 

해당 이미지의 마스킹 버전 masked_img을 생성하고, 시각적 목적을 위해 레인보우 이미지의 show_masked 이미지를

설정해준다. 원본과 비교했을 때 빨간색이 거의 없다는 것을 알 수 있다. 

hist_mask_values_red = cv2.calcHist([rainbow],channels=[2],mask=mask,histSize=[256],ranges=[0,256])
hist_full_values_red = cv2.calcHist([rainbow],channels=[2],mask=None,histSize=[256],ranges=[0,256])

마스크를 적용한것 하나와 적용하지 않은 것 두개를 생성한다

plt.plot(hist_full_values_red)
plt.title('Histogram for RED values of the full image')

마스크를 적용하지 않은 것의 히스토그램 분포를 보면, 많은 빨간색의 분포가 보인다

plt.plot(hist_mask_values_red)
plt.title('Histogram for RED values for the Masked Area')

마스크를 적용한 사진의 분포를 보면 적색값이 점점 내려가고 0에 수렴한다. 

0에 많이 분포한 것으로 보아 거의 모든 값이 0 (검은색)임을 알 수 있다.

출처: udemy x KMOOC OpenCV 및 딥러닝을 이용한 Computer Vision 파이썬