1. 히스토그램
- 히스토그램은 해당 값에 대한 빈도수를 시각화하여 나타낸 그래프이다.
- 영상처리에서 히스토그램은 명암값에 대한 빈도수를 나타내기 위해 사용되었다.
- 주로 영상의 특성을 파악하기 위해 사용한다.
히스토그램의 용도
- 영상의 명암값의 분포를 보여준다.
- 조작을 통한 영상의 품질을 개선한다.
- 컬러 분포가 비슷한 영역을 검출하여 물체를 검출한다.
- 다음 그래프처럼 왼쪽에 치우칠수록 어두운 영상임을 알 수 있다.
- 다음 그래프는 명암의 범위가 넓으며 밝기 분포가 비교적 균일하다.
- 다음 영상의 그래프를 보면 두개의 봉우리가 선명하게 나타난 영상으로 이런 사진은 이진 영상으로 변환하기 쉽다.
히스토그램 OpenCV로 표현하기
- OpenCV와 Matplotlib을 이용하여 Histogram을 찾을 수 있다.
- cv2.calcHist()와 np.histogram()함수를 사용할 수 있다.
cv2.calcHist(image,channels,mask,histSize,ranges[,hist[,accumulate]])
Parameters
- image - 분석 대상 이미지. Array형태
- channels - 분석 채널, 이미지가 grayscale이면 [0], color이미지면 [0]: blue, [1]: green, [2]: red
- mask - 이미지의 분석 영역, None이면 전체 영역
- histSize - Bins 값, [256]
- ranges - Range값, [0,256]
- 다음 예시는 grayscale이미지를 읽어 명암의 분포를 보여주는 예제이다.
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('bwtest.jpg',0)
hist = cv2.calcHist([img],[0],None,[256],[0,256])
plt.subplot(221),plt.imshow(img,'gray')
plt.subplot(223),plt.plot(hist,color='b')
plt.xlim([0,256])
plt.show()
2. 히스토그램의 평활화 (Histogram Equalized)
- 히스토그램을 조작 및 연산을 통해 영상의 품질을 개선하기도 하는데 가장 대표적인 연산은 히스토그램 평활화 이다.
- 이미지의 히스토그램이 특정 영역에 너무 집중되어 있으면 contrast가 낮아 좋은 이미지라고 할 수 없다. 동적 범위가 골고루 분포 되어 있을때 좋은 이미지라고 할 수 있다.
- 이 연산은 영상의 명암 분포를 평평하게 만든다.
- 연산을 통해 영상의 명암 범위, 즉 동적 범위(Dynamic Range)가 늘어나 영상이 이전보다 선명해진다.
- 주로 명암 분포가 빈약한 영상을 균일하게 하기 위해 사용한다.
하지만 histogram equalization은 영상의 명암값의 범위를 stretch하여 이미지를 극적화 시킨것이지
이미지의 진짜 모습이라고 하기는 어렵다.
3. 히스토그램 평활화의 활용 여부
- 히스토그램은 영상의 품질을 개선하기 위해 사용되는 연산이지만, 오히려 품질을 떨어뜨리는 경우도 있다.
- 위 그림은 오히려 히스토그램 평활화가 이미지 품질을 떨어뜨린 사례라고 할 수 있다.
- 새의 깃털 텍스쳐도 훼손되었으며, 특히 시각적인 느낌이 퇴화한 것을 알 수 있다.
- 하지만 새에게 잡아먹히는 곤충의 영상은 오히려 선명해 졌다.
- 새에게 잡아먹히기 직전의 곤충을 확인하는 목적으로 국한한다면, 평활화된 영상이 더 적합하다.
- 용도에 따라 인식하려는 대상의 품질이 더 떨어질 수 있으니 잘 활용해야 한다.
5. 히스토그램 평활화 OpenCV를 사용하여 적용해보기
-OpenCV에서는 equalizeHist() 함수를 이용하여 히스토그램 평활화를 진행할 수 있다.
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('이미지의 저장경로',0);
# OpenCV의 Equaliztion함수
img2 = cv2.equalizeHist(img)
img = cv2.resize(img,(400,400))
img2 = cv2.resize(img2,(400,400))
dst = np.hstack((img, img2))
cv2.imshow('img',dst)
cv2.waitKey()
cv2.destroyAllWindows()
6. CLAHE (Contrast Limited Adaptive Histogram Equalization)
- 위의 히스토그램 평활화는 전체적인 부분에 균일화를 적용하였다.
- 하지만 일반적인 이미지는 밝은 부분과 어두운 부분이 섞여 있기 때문에 전체에 적용하는 것은 그렇게 유용하지 않다.
- 어두운 부분은 균일화가 적용되었지만, 가운데 원래 밝았던 부분은 너무 밝아져 경계선을 알아볼 수 없게 됨.
- 이러한 문제를 해결하기 위해서 adaptive histogram equalization을 적용하게 된다.
- 이미지를 작은 title 형태로 나누어 title 안에서 Equalization을 적용하는 방식이다.
- 하지만 작은 영역으로 나누다 보니 작은 노이즈가 있으면 이것이 반영되어 원하는 결과를 얻을 수 없게 된다.
- 이 문제를 해결하기 위해 contrast limit이라는 값을 적용하여 이 값을 넘어가는 경우 그 영역은 다른 영역에 균일하게 배분하여 적용한다.
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('images/clahe.png',0);
# contrast limit가 2이고 title의 size는 8X8
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
img2 = clahe.apply(img)
img = cv2.resize(img,(400,400))
img2 = cv2.resize(img2,(400,400))
dst = np.hstack((img, img2))
cv2.imshow('img',dst)
cv2.waitKey()
cv2.destroyAllWindows()
- 결과를 보면 가운데 이미지의 윤곽선도 유지가 되며 전체적인 명암비(contrast)가 높아졌다.
아직 공부 안함.
4. 히스토그램 역투영 (Histogram Back-Projection)
- 히스토그램 역투영은 영상의 각 픽셀이 주어진 히스토그램 모델에 얼마나 일치하는지를 검사하는 방법이다.
- 임의의 색상 영역을 검출할때 효과적이다.
- 역투영시 히스토그램은 명암 채널만 사용하는 1차원이 아니라, 최소 2차원 이상을 사용해야 한다.
- 왜냐하면 명암은 조명에 따라 쉽게 변할 뿐만 아니라 얼굴과 비슷한 명암을 갖는 다른 영역이 여러 군데 존재할 가능성이 높아 명암으로 임의의 물체를 검출하기에 어려움이 있다.
역투영은 알파 채널이나 크로마 키 같은 것이 없어도 복잡한 모양의 사물을 분리할 수 있다는 장점이 있습니다. 하지만 역투영은 히스토그램을 기반으로 관심 영역의 색상과 비슷한 물체를 추출하므로, 관심 영역의 색상과 비슷한 다른 물체가 뒤섞여 있을 때는 효과가 떨어질 수 있습니다.
'CV' 카테고리의 다른 글
OpenCV 기본 연산 (0) | 2022.10.22 |
---|---|
도형 그리기(직선, 사각형, 원, 타원, 다각형, 텍스트) (0) | 2022.10.22 |
연결 요소 (0) | 2022.10.22 |
이진화, 오츠 알고리즘(Binarization, Thresholding, Otsu Algorithm) (0) | 2022.10.22 |
에지 검출 (Edge Detection) / Image Gradients (0) | 2022.10.18 |