이미지의 밝기 분포를 나타내는 표입니다. 밝기는 0에서 255 단계까지(0은 검은색, 255는 하얀색) 정의해 놓습니다. 이미지를 픽셀에 단위로 분해 하고 픽셀 별로 명암 값(0에서 255)을 구하여 밝기가 0인 픽셀의 총계, 1인 픽셀의 총계.... 255인 픽셀의 총계를 구하여 도표로 보여주는 것 입니다. 도표의 x축은 명암 0~255 이고 y축은 명암 별 픽셀 개수를 나타냅니다.
0에 가까운 값을 가진 픽셀이 많다면 이미지가 너무 어두울 테고 255쪽의 값을 가진 픽셀이 많다면 너무 밝은 이미지라고 할 수 있습니다.
cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]]) → hist
parameter |
설명 |
images |
이미지 파일 |
channels |
분석 채널(0:gray, 1: |
mask |
히스토그램을 계산할 영역 |
histSize |
히스토그램 (BIN)의 개수. [256] |
ranges |
계산 범위 [0, 256] |
hist |
계산 결과 |
accumulate |
누적 여부. true이면 초기화 하지 않고 이전 값을 계속 누적 |
6.1 흑백 이미지
검은 색과 흰색의 영역이 동일한 이미지를 이용하여 테스트를 진행해 봅니다. 물론 실제 사용하는 이미지에는 테두리가 없습니다.
import cv2 import numpy as np from matplotlib import pyplot as plt
img = cv2.imread('D:/tensorflow/images/image_calcuHist001.png', 0)
hist = cv2.calcHist([img], [0], None, [256], [0, 256])
plt.plot(hist) plt.show() |
그래프를 보면 픽셀의 명암 값이 0인 개수와 255인 픽셀의 개수가 동일 하다는 걸 확인할 수 있습니다.
6.2 컬러 이미지
컬러 이미지를 이용하여 테스트를 진행해 봅니다. 파랑색 블럭과 녹색, 붉은색 블럭의 크기가 동일 하도록 이미지를 준비 하였습니다.
import cv2 import numpy as np from matplotlib import pyplot as plt
img = cv2.imread(‘D:/tensorflow/images/image_calcuHist003.png’, 1)
hist = cv2.calcHist([img], [2], None, [256], [0, 256])
plt.subplot(2,2,1), plt.imshow(img) plt.subplot(2,2,2), plt.plot(hist) #plt.plot(hist)
plt.show() |
컬러값을 만들 때 파란색은 [0, 0, 255]로 표현 되는데 값의 두 개 중 하나만 255이고 나머지는 0으로 표현 됩니다. 즉, B[0,0,255], G[0,255,0], R[255,0,0] 이런 식으로 255보다 0이 두 배 많게 나옵니다. 결과적으로 그래프의 값도 255의 픽셀 값보다 0의 값을 가진 픽셀이 2배 많다는 것을 나타내고 있습니다.
위의 두 경우 모두 너무 극단적인 예제들 이었고 실제 사진을 가지고 테스트를 해보겠습니다. 아래사진은 저녁에 도로를 찍어서 좀 어둡습니다.
히스토그램 결과도 0에 가까운 값들이 많은걸 알 수 있습니다. 이런 식으로 히스토그램을 이용하면 사진을 안보고도 어떤 느낌인지 대충 예상할 수 있겠네요.
6.3 히스토그램 균일화(평활화) : Histogram Equalization
이미지의 히스토그램 결과가 한쪽으로 몰려있는 경우 너무 밝거나 어둡게 보이는데 가능하면 골고루 분포되도록 조절을 하는 작업을 균일화 또는 평활화 하고 합니다.
import cv2 import numpy as np
img = cv2.imread('D:/tensorflow/images/image_calcuHist004.png');
hist, bins = np.histogram(img.ravel(), 256,[0,256]) # 히스토그램 구하기 cdf = hist.cumsum() #numpy 배열을 1차원으로 하고 더한 값을 누적하여 배열 생성
cdf_m = np.ma.masked_equal(cdf,0) #cdf에서 값이 0인 부분을 mask하여 제외 처리 cdf_m = (cdf_m - cdf_m.min())*255/(cdf_m.max()-cdf_m.min()) #여기가 균일화 방정식 cdf = np.ma.filled(cdf_m,0).astype('uint8') #mask로 제외했던 0값을 복원
img2 = cdf[img]
cv2.imshow('Equalization', img2) cv2.waitKey(0) cv2.destroyAllWindows() |
어둡던 이미지가 많이 밝아졌습니다. 어둠에 묻혀있던 사물들이 좀더 선명해진 것을 확인할 수 있습니다. 길을 걷는 사람이 조금 포함된걸 알기는 했는데 무슨 상표 옷인지 눈에 확들어오네요.
- copy coding -
'Tensorflow > OpenCV' 카테고리의 다른 글
OpenCV 7. Contours 이미지 윤곽선 검출 (0) | 2020.11.27 |
---|---|
OpenCV threshold 설명 (0) | 2020.11.23 |
OpenCV 이미지 붙이기 (1) | 2019.04.08 |
OpenCV 5. 임계처리 (이진화) (Python) (0) | 2019.04.07 |
OpenCV 4. 이미지 비트 연산 (Python) (0) | 2019.04.06 |