반응형
Histogram
▶ 개념
- 영상의 픽셀 값 분포를 그래프 형태로 표현
- 그레이스케일 영상 : 그레이 스케일 값의 픽셀 개수를 히스토그램으로 표현
- 컬러 영상 : 색상 성분 조합의 픽셀 개수를 히스토 그램으로 표현
▶ 히스토그램 계산
-
- 4x4 크기, 0~7 밝기값(gray scale)
- 각 밝기 값의 대한 히스토그램간단한 히스토그램 예제
▶ 영상 분석
▶ 비교함수
- cv2.CMP_EQ
- src1과 src2의 요소가 같음
- cv2.CMP_NE
- src1과 src2의 요소가 같지 않음
- cv2.CMP_GT
- src1과 src2의 요소가 큼
- cv2.CMP_GE
- src1과 src2의 요소가 크거나 같음
- cv2.CMP_LT
- src1과 src2의 요소가 작음
- cv2.CMP_LE
- src1과 src2의 요소가 작거나 같음
▶ 히스토그램 스트레칭
- 영상의 히스토그램을 전 구간에 분포하게 하는 선형 변환 기법.
- 명암비가 낮은 영상은 히스토그램이 특정 구간에 집중됨.
- 히스토그램을 늘려 그레이스케일 범위를 전 구간으로 변환.
▶ 히스토그램 응용
히스토그램 평활화
- 영상의 픽셀 값 분포가 그레이스케일 전체영역에서 균일하게 분포하도록 변경하는 알고리즘
- 특정 밝기값 근방에 몰려 잇는 픽셀 분포를 분산시킴.
- 히스토그램 누적 함수 H(g)를 이용하여 계산
- h(g) : 밝기값이 g인 픽셀의 개수
- N : 영상 픽셀 개수
- LMax : 255
▷ cv2.equalizerHist(src[, dst]) -> dst
In [44]:
import cv2
import numpy as np
import matplotlib.pyplot as plt
src = cv2.imread('./image/lena.jpg', cv2.IMREAD_GRAYSCALE)
hist1 = cv2.calcHist(images=[src], channels=[0], mask=None, histSize=[32], ranges=[0,256])
hist2 = cv2.calcHist(images=[src], channels=[0], mask=None, histSize=[256], ranges=[0,256])
print('hist1 : ', hist1)
print('hist2 : ', hist2)
hist1 : [[0.0000e+00]
[0.0000e+00]
[4.0000e+00]
[4.5700e+02]
[3.9840e+03]
[1.2842e+04]
[1.5364e+04]
[9.7330e+03]
[6.6300e+03]
[6.9730e+03]
[7.5490e+03]
[9.9030e+03]
[1.4938e+04]
[1.2189e+04]
[1.1516e+04]
[1.5556e+04]
[1.7769e+04]
[1.7279e+04]
[1.8434e+04]
[2.0473e+04]
[1.2963e+04]
[9.8330e+03]
[7.7490e+03]
[5.4350e+03]
[7.0610e+03]
[7.3390e+03]
[7.2600e+03]
[2.4070e+03]
[4.7200e+02]
[2.8000e+01]
[4.0000e+00]
[0.0000e+00]]
hist2 : [[0.000e+00]
[0.000e+00]
[0.000e+00]
[0.000e+00]
[0.000e+00]
[0.000e+00]
[0.000e+00]
[0.000e+00]
[0.000e+00]
[0.000e+00]
[0.000e+00]
[0.000e+00]
[0.000e+00]
[0.000e+00]
[0.000e+00]
[0.000e+00]
[0.000e+00]
[0.000e+00]
[1.000e+00]
[0.000e+00]
[0.000e+00]
[0.000e+00]
[1.000e+00]
[2.000e+00]
[4.000e+00]
[8.000e+00]
[1.700e+01]
[2.400e+01]
[5.600e+01]
[8.200e+01]
[1.100e+02]
[1.560e+02]
[2.010e+02]
[2.870e+02]
[3.380e+02]
[4.240e+02]
[5.210e+02]
[6.130e+02]
[7.080e+02]
[8.920e+02]
[1.031e+03]
[1.265e+03]
[1.459e+03]
[1.604e+03]
[1.695e+03]
[1.905e+03]
[1.889e+03]
[1.994e+03]
[2.002e+03]
[2.065e+03]
[2.022e+03]
[2.031e+03]
[1.897e+03]
[1.886e+03]
[1.743e+03]
[1.718e+03]
[1.524e+03]
[1.460e+03]
[1.256e+03]
[1.266e+03]
[1.190e+03]
[1.078e+03]
[9.910e+02]
[9.680e+02]
[9.160e+02]
[8.770e+02]
[8.210e+02]
[8.120e+02]
[7.330e+02]
[8.060e+02]
[8.460e+02]
[8.190e+02]
[7.680e+02]
[8.850e+02]
[8.760e+02]
[8.570e+02]
[8.720e+02]
[8.690e+02]
[9.590e+02]
[8.870e+02]
[9.740e+02]
[9.080e+02]
[8.380e+02]
[9.760e+02]
[9.480e+02]
[9.460e+02]
[9.520e+02]
[1.007e+03]
[1.052e+03]
[1.153e+03]
[1.149e+03]
[1.163e+03]
[1.221e+03]
[1.258e+03]
[1.445e+03]
[1.462e+03]
[1.601e+03]
[1.852e+03]
[1.815e+03]
[1.928e+03]
[1.967e+03]
[1.901e+03]
[2.006e+03]
[1.868e+03]
[1.816e+03]
[1.692e+03]
[1.594e+03]
[1.551e+03]
[1.397e+03]
[1.436e+03]
[1.382e+03]
[1.321e+03]
[1.395e+03]
[1.375e+03]
[1.375e+03]
[1.412e+03]
[1.403e+03]
[1.453e+03]
[1.478e+03]
[1.625e+03]
[1.628e+03]
[1.593e+03]
[1.808e+03]
[1.831e+03]
[2.033e+03]
[2.098e+03]
[2.220e+03]
[2.345e+03]
[2.444e+03]
[2.356e+03]
[2.463e+03]
[2.309e+03]
[2.296e+03]
[2.027e+03]
[1.961e+03]
[1.913e+03]
[1.903e+03]
[1.911e+03]
[2.068e+03]
[2.035e+03]
[2.339e+03]
[2.293e+03]
[2.337e+03]
[2.393e+03]
[2.485e+03]
[2.425e+03]
[2.247e+03]
[2.279e+03]
[2.222e+03]
[2.196e+03]
[2.276e+03]
[2.304e+03]
[2.433e+03]
[2.667e+03]
[2.643e+03]
[2.724e+03]
[2.741e+03]
[2.584e+03]
[2.421e+03]
[2.260e+03]
[2.076e+03]
[1.915e+03]
[1.748e+03]
[1.634e+03]
[1.474e+03]
[1.438e+03]
[1.387e+03]
[1.291e+03]
[1.231e+03]
[1.192e+03]
[1.168e+03]
[1.249e+03]
[1.265e+03]
[1.229e+03]
[1.235e+03]
[1.264e+03]
[1.241e+03]
[1.170e+03]
[1.115e+03]
[1.033e+03]
[9.470e+02]
[8.260e+02]
[7.510e+02]
[6.660e+02]
[6.330e+02]
[6.410e+02]
[5.940e+02]
[6.600e+02]
[6.330e+02]
[7.110e+02]
[7.810e+02]
[7.820e+02]
[8.100e+02]
[8.660e+02]
[9.110e+02]
[9.630e+02]
[9.550e+02]
[8.320e+02]
[8.580e+02]
[8.660e+02]
[8.380e+02]
[9.060e+02]
[8.390e+02]
[9.030e+02]
[9.220e+02]
[9.420e+02]
[9.760e+02]
[1.013e+03]
[1.087e+03]
[1.077e+03]
[9.690e+02]
[9.650e+02]
[1.023e+03]
[8.700e+02]
[7.000e+02]
[5.690e+02]
[4.630e+02]
[4.050e+02]
[3.580e+02]
[3.280e+02]
[2.570e+02]
[2.080e+02]
[2.130e+02]
[1.750e+02]
[1.200e+02]
[1.020e+02]
[7.500e+01]
[6.500e+01]
[3.700e+01]
[3.300e+01]
[2.300e+01]
[1.700e+01]
[9.000e+00]
[9.000e+00]
[3.000e+00]
[4.000e+00]
[2.000e+00]
[1.000e+00]
[0.000e+00]
[0.000e+00]
[0.000e+00]
[1.000e+00]
[0.000e+00]
[0.000e+00]
[1.000e+00]
[1.000e+00]
[0.000e+00]
[1.000e+00]
[0.000e+00]
[0.000e+00]
[0.000e+00]
[0.000e+00]
[0.000e+00]
[0.000e+00]
[0.000e+00]
[0.000e+00]]
두 히스토그램 1차원 벡터로 변경 후 선그래프, 히스토그램 막대그래프로 표현¶
In [45]:
import cv2
import numpy as np
import matplotlib.pyplot as plt
hist1 = hist1.flatten() #32
hist2 = hist2.flatten() #256
plt.subplot(2,1,1)
plt.title("hist1 : size32")
plt.plot(hist1, c='r')
plt.bar(np.arange(32), hist1, color='blue')
plt.subplot(2,1,2)
plt.title("hist2 : size256")
plt.plot(hist2, c='r')
plt.bar(np.arange(256), hist2, color='skyblue')
plt.show()
히스토그램 스트레칭은 OpenCV에서 함수로 제공하지 않는다.¶
cv2.minMaxLoc 함수 사용
기본 값으로 0,255를 많이 가지고 있는 경우 의미가 없어진다.
In [55]:
import cv2
import numpy as np
import matplotlib.pyplot as plt
src = cv2.imread('./image/lena.jpg', cv2.IMREAD_GRAYSCALE)
dst1 = cv2.normalize(src, None, 0, 255, cv2.NORM_MINMAX)
hist1 = cv2.calcHist(images=[dst1], channels=[0], mask=None, histSize=[32], ranges=[0,256])
hist2 = cv2.calcHist(images=[dst2], channels=[0], mask=None, histSize=[256], ranges=[0,256])
hist1 = hist1.flatten() #32
hist2 = hist2.flatten() #256
plt.subplot(2,1,1)
plt.title("hist1 : size32")
plt.plot(hist1, c='r')
plt.bar(np.arange(32), hist1, color='blue')
plt.subplot(2,1,2)
plt.title("hist2 : size256")
plt.plot(hist2, c='r')
plt.bar(np.arange(256), hist2, color='skyblue')
plt.show()
kawkes 실제 이미지, 명암비 히스토그램 확인 후 선명하게 변경¶
- 명암비 히스토그램 확인
- 선명하기 변경
In [2]:
import cv2
import numpy as np
import matplotlib.pyplot as plt
src = cv2.imread('./image/hawkes.bmp', cv2.IMREAD_GRAYSCALE)
hist1 = cv2.calcHist(images=[src], channels=[0], mask=None, histSize=[32], ranges=[0,256])
hist2 = cv2.calcHist(images=[src], channels=[0], mask=None, histSize=[256], ranges=[0,256])
hist1 = hist1.flatten() #32
hist2 = hist2.flatten() #256
plt.subplot(2,1,1)
plt.title("hist1 : size32")
plt.plot(hist1, c='r')
plt.bar(np.arange(32), hist1, color='blue')
plt.subplot(2,1,2)
plt.title("hist2 : size256")
plt.plot(hist2, c='r')
plt.bar(np.arange(256), hist2, color='skyblue')
Out[2]:
<BarContainer object of 256 artists>
In [1]:
import cv2
import numpy as np
import matplotlib.pyplot as plt
src = cv2.imread('./image/hawkes.bmp', cv2.IMREAD_GRAYSCALE)
dst = cv2.normalize(src, None, 0, 255, cv2.NORM_MINMAX)
hist1 = cv2.calcHist(images=[dst], channels=[0], mask=None, histSize=[32], ranges=[0,256])
hist2 = cv2.calcHist(images=[dst], channels=[0], mask=None, histSize=[256], ranges=[0,256])
hist1 = hist1.flatten() #32
hist2 = hist2.flatten() #256
plt.subplot(2,1,1)
plt.title("hist1 : size32")
plt.plot(hist1, c='r')
plt.bar(np.arange(32), hist1, color='blue')
plt.subplot(2,1,2)
plt.title("hist2 : size256")
plt.plot(hist2, c='r')
plt.bar(np.arange(256), hist2, color='skyblue')
# cv2.imshow('dst', dst)
# cv2.waitKey()
# cv2.destroyAllWindows()
Out[1]:
<BarContainer object of 256 artists>
In [ ]:
# 추가 데이터를 넣음으로서 명암이 사라짐
src[:10,:10] = 0
src[11:20, 11:20] = 255
dst = cv2.normalize(src, None, 0, 255, cv2.NORM_MINMAX)
cv2.imshow("src", src)
cv2.imshow("dst", dst)
cv2.waitKey()
cv2.destroyAllWindows()
cv2.waitKey(1)
히스토그램 평활화¶
영상의 픽셀 값 분포가 그레이스케일 전체영역에서 균일하게 분포하도록 변경하는 알고리즘
특정 밝기값 근방에 몰려있는 픽셀 분포를 분산시킴
히스토그램 누적 함수 H(g)를 이용하여 계산
cv2.equalizeHist(src[,dst])
In [16]:
src = np.array([[0,0,0,0],
[1,1,3,5],
[6,1,1,3],
[4,3,1,7]], dtype=np.uint8)
dst = cv2.normalize(src, None, 0, 255, cv2.NORM_MINMAX)
hist1 = cv2.calcHist(images=[dst], channels=[0], mask=None, histSize=[256], ranges=[0,256])
hist1 = hist1.flatten() #256
dst2 = cv2.equalizeHist(dst)
hist2 = cv2.calcHist(images=[dst2], channels=[0], mask=None, histSize=[256], ranges=[0,256])
hist2 = hist2.flatten() #256
plt.subplot(2,1,1)
plt.title("hist1 : size256")
plt.plot(hist1, c='r')
plt.bar(np.arange(256), hist1, color='blue')
# 평활화
plt.subplot(2,1,2)
plt.title("hist2 : size256")
plt.plot(hist2, c='r')
plt.bar(np.arange(256), hist2, color='skyblue')
Out[16]:
<BarContainer object of 256 artists>
lena, hawkes 영상 노멀라이스, 평활하 적용하여 원본과 비교¶
In [ ]:
# 레나 영상 노멀라이즈 평활화 모두 적용하여 원본과 비교
import cv2
import numpy as np
import matplotlib.pyplot as plt
src = cv2.imread('./image/lena.jpg', cv2.IMREAD_GRAYSCALE)
dst = cv2.normalize(src, None, 0, 255, cv2.NORM_MINMAX)
dst2 = cv2.equalizeHist(src)
dst3 = cv2.equalizeHist(dst)
cv2.imshow('norm', dst)
cv2.imshow('norm_equl', dst2)
cv2.imshow('equl', dst3)
cv2.waitKey()
cv2.destroyAllWindows()
# 히스토그램
hist1 = cv2.calcHist(images=[src], channels=[0], mask=None, histSize=[256], ranges=[0,256])
hist1 = hist1.flatten() #256
hist2 = cv2.calcHist(images=[dst3], channels=[0], mask=None, histSize=[256], ranges=[0,256])
hist2 = hist2.flatten() #256
plt.subplot(2,1,1)
plt.title("hist1 : size256")
plt.plot(hist1, c='r')
plt.bar(np.arange(256), hist1, color='blue')
plt.subplot(2,1,2)
plt.title("hist2 : size256_norm_equal")
plt.plot(hist2, c='r')
plt.bar(np.arange(256), hist2, color='skyblue')
In [ ]:
# hawkes 영상 노멀라이즈 평활화 모두 적용하여 원본과 비교
import cv2
import numpy as np
import matplotlib.pyplot as plt
src = cv2.imread('./image/hawkes.bmp', cv2.IMREAD_GRAYSCALE)
dst = cv2.normalize(src, None, 0, 255, cv2.NORM_MINMAX)
dst2 = cv2.equalizeHist(src)
dst3 = cv2.equalizeHist(dst)
cv2.imshow('norm', dst)
cv2.imshow('norm_equl', dst2)
cv2.imshow('equl', dst3)
cv2.waitKey()
cv2.destroyAllWindows()
# 히스토그램
hist1 = cv2.calcHist(images=[src], channels=[0], mask=None, histSize=[256], ranges=[0,256])
hist1 = hist1.flatten() #256
hist2 = cv2.calcHist(images=[dst3], channels=[0], mask=None, histSize=[256], ranges=[0,256])
hist2 = hist2.flatten() #256
plt.subplot(2,1,1)
plt.title("hist1 : size256")
plt.plot(hist1, c='r')
plt.bar(np.arange(256), hist1, color='blue')
plt.subplot(2,1,2)
plt.title("hist2 : size256_norm_equal")
plt.plot(hist2, c='r')
plt.bar(np.arange(256), hist2, color='skyblue')
반응형
'Python' 카테고리의 다른 글
[Python] openCV : Morphology (0) | 2022.11.17 |
---|---|
[Python] openCV : Filltering (0) | 2022.11.17 |
[Python] openCV : normalization (0) | 2022.11.10 |
[Python] openCV : image access (0) | 2022.11.10 |
[Python] openCV : Event (0) | 2022.11.10 |