02wk-2

통계와 시각화
Author

최규빈

Published

September 14, 2022

Histogram equalization

강의영상

https://youtube.com/playlist?list=PLQqh36zP38-zbK5TSpioGW87b8PDRXS5M

참고자료

- 넘파이 문법이 약하다면? (reshape, concatenate, stack)

  1. reshape: 링크의 넘파이공부 2단계 reshape 참고

  2. concatenate, stack: 링크의 넘파이공부 4단계 참고

- 주피터에서 !로 시작하는 명령의 기원, 혹은 원리를 알고싶다면?: 링크의 3세대 프로그래머의 삶까지 살펴볼 것

- import, from … import … 등 모듈을 임포트하는 방식이 낯설다면?

오늘 배울 내용?

- 히스토그램의 활용: 정규분포인지 판단 <- 지난시간 내용

- 히스토그램의 활용2: 이미지 보정! 히스토그램 이퀄라이제이션 <– 오늘소개할 내용

imports

!pip install opencv-python
import cv2 
import matplotlib.pyplot as plt 
import pandas as pd
import numpy as np

이미지자료 다운로드

!wget https://upload.wikimedia.org/wikipedia/commons/0/08/Unequalized_Hawkes_Bay_NZ.jpg
img = cv2.imread('Unequalized_Hawkes_Bay_NZ.jpg')
--2022-09-14 17:57:58--  https://upload.wikimedia.org/wikipedia/commons/0/08/Unequalized_Hawkes_Bay_NZ.jpg
Resolving upload.wikimedia.org (upload.wikimedia.org)... 103.102.166.240, 2001:df2:e500:ed1a::2:b
Connecting to upload.wikimedia.org (upload.wikimedia.org)|103.102.166.240|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 110895 (108K) [image/jpeg]
Saving to: ‘Unequalized_Hawkes_Bay_NZ.jpg.5’

Unequalized_Hawkes_ 100%[===================>] 108.30K   505KB/s    in 0.2s    

2022-09-14 17:57:59 (505 KB/s) - ‘Unequalized_Hawkes_Bay_NZ.jpg.5’ saved [110895/110895]
img.shape
(683, 1024, 3)
plt.imshow(img)
<matplotlib.image.AxesImage at 0x7f385c732850>

이미지자료의 이해

비밀1: 이미지는 사실 숫자들의 집합이었음.

- 예시1

_img1 = np.array([0,30,90,120,150,180,210,240,255]).reshape(3,3)
_img1
array([[  0,  30,  90],
       [120, 150, 180],
       [210, 240, 255]])
plt.imshow(_img1,cmap='gray')
plt.colorbar()
<matplotlib.colorbar.Colorbar at 0x7f385a14c450>

- 예시2

_img2 = np.array([0,20,40,60,80,100,120,140,160]).reshape(3,3)
_img2
array([[  0,  20,  40],
       [ 60,  80, 100],
       [120, 140, 160]])
plt.imshow(_img2,cmap='gray',vmin=0,vmax=255)
plt.colorbar()
<matplotlib.colorbar.Colorbar at 0x7f385a04e590>

- 예시3

_img3 = np.concatenate([_img1,_img2],axis=1)
_img3
array([[  0,  30,  90,   0,  20,  40],
       [120, 150, 180,  60,  80, 100],
       [210, 240, 255, 120, 140, 160]])
plt.imshow(_img3,cmap='gray')
<matplotlib.image.AxesImage at 0x7f3859fda8d0>

비밀2: 칼라이미지는 red + green + blue 의 조합으로 표현가능 (다른방식도 가능)

- 예시1

r = np.array([0]*25*3).reshape(5,5,3) 
g = np.array([0]*25*3).reshape(5,5,3) 
b = np.array([0]*25*3).reshape(5,5,3) 
r[:3,:3,0] = 255   
g[:3,2:,1] = 255
b[2:,:,2] = 255 
plt.imshow(r)
<matplotlib.image.AxesImage at 0x7f3859f00a50>

plt.imshow(g)
<matplotlib.image.AxesImage at 0x7f3859e8a4d0>

plt.imshow(b)
<matplotlib.image.AxesImage at 0x7f3859e47590>

plt.imshow(r+g+b)
<matplotlib.image.AxesImage at 0x7f3859dd67d0>

- 예시2: R,G,B를 같은 비율로 섞으면 무채색이 된다.

r = np.array([0]*25*3).reshape(5,5,3) 
g = np.array([0]*25*3).reshape(5,5,3) 
b = np.array([0]*25*3).reshape(5,5,3) 
r[:3,:3,0] = 80   
g[:3,2:,1] = 80
b[2:,:,2] = 80 
plt.imshow(r+g+b)
<matplotlib.image.AxesImage at 0x7f3859d53610>

- 예시3: 우리가 관심있는 자료

img.shape
(683, 1024, 3)
img_red = img * 0 
img_green = img * 0 
img_blue = img * 0 
img_red[...,0] = img[...,0] 
img_green[...,1] = img[...,1] 
img_blue[...,2] = img[...,2] 
plt.imshow(img_blue)
<matplotlib.image.AxesImage at 0x7f3859ccb750>

히스토그램 이퀄라이제이션

- 이미지를 rgb로 각각 분리하고 각 색깔들의 히스토그램을 그려보자.

plt.hist(img[:,:,0].reshape(-1))
(array([  3691.,  56282., 235628., 170392., 120545.,  60511.,  22052.,
         14354.,  15246.,    691.]),
 array([114. , 123.4, 132.8, 142.2, 151.6, 161. , 170.4, 179.8, 189.2,
        198.6, 208. ]),
 <BarContainer object of 10 artists>)

  • 히스토그램 그림1
_fig = plt.hist(img[:,:,0].reshape(-1),bins=255, range=[0,255])

  • 히스토그램 그림2
  • 120-200 사이에 값이 몰려있음
  • 그런데 컴퓨터가 표현가능한 색은 0~255..
  • 만약에 120-200까지의 분포된 모양은 그대로 유지하면서 range를 0-255 까지 늘린다면?

- 분포의 모양은 대략적으로 유지하면서 값을 퍼트리자!

img2_red = cv2.equalizeHist(img[...,0])
plt.hist(img2_red.reshape(-1))
(array([59973., 57426., 82721., 73706., 61999., 76539., 72114., 72030.,
        72601., 70283.]),
 array([  0. ,  25.5,  51. ,  76.5, 102. , 127.5, 153. , 178.5, 204. ,
        229.5, 255. ]),
 <BarContainer object of 10 artists>)

_fig=plt.hist(img2_red.reshape(-1),bins=255,range=(0,255))

- red말고 다른채널에도 이와 같은 변환을 정의한다면?

img2 = np.stack([img2_red,img2_red,img2_red],axis=-1)
plt.imshow(img2)
<matplotlib.image.AxesImage at 0x7f3848570810>

plt.imshow(img)
<matplotlib.image.AxesImage at 0x7f38484eea90>

plt.imshow(np.concatenate([img,img2],axis=1))
<matplotlib.image.AxesImage at 0x7f3848446ad0>

히스토그램 이퀄라이제이션 (흑백버전)

img_black =  cv2.imread('Unequalized_Hawkes_Bay_NZ.jpg',0)
img_black2 = cv2.equalizeHist(img_black)
plt.imshow(np.concatenate([img_black,img_black2],axis=1),cmap='gray')
<matplotlib.image.AxesImage at 0x7f384840bc90>

숙제

- HE(Histogram Equalization)을 이용하여 아래주소에 저장된 이미지의 명암비를 보존하라

https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/hw_img.png