Open CV

히스토그램

손가락라잎 2020. 9. 28. 21:40

 

 

히스토그램이란 영상의 픽셀값들에 대한 분포를 나타내는 그래프로 영상분석을 하는데 매우 유용하다.

히스토그램의 가로축은 영상의 픽셀값이고 세로축은 픽셀값에 대한 빈도수를 나타낸다.

 

<히스토그램>

 

예를들어 영상으로부터 히스토그램을 적성하기 위해서 도수분포표(frequency table)를 작성한 후 도수분포표로부터 히스토그램을 작성한다.

 

<도수분포표 작성 예시와 히스토그램>

앞에서 히스토그램을 통하여 영상의 픽셀값들에 대한 분포를 알 수 있었다.

 

아래 그림은 히스토그램과 영상과의 관계를 보여주고 있다. (a)와 (b)는 밝은 영상과 어두운 영상에서 히스토그램을 보여주고 있고, (c)와 (d)는 명암대비에 따른 히스토그램을 보여주고 있다.

 

(a)와 (b)에서처럼 어두운 영상일수록 작은 픽셀값 근처인 왼쪽 편에 픽셀값들이 많이 치우쳐있고 밝은 영상일수록 픽셀값이 큰 오른쪽 편에 많이 치우쳐 있다. (c)와 (d)에서 보듯이 명암대비가 낮은 영상은 픽셀값들이 좁은 영역에 분포되어 영상이 선명하지 않다. 명암대비다 낮은 영상은 픽셀값들이 좁은 영역에 분포되어 영상이 선명하지 않고 명암대비가 높은 영상은 넓은 범위에 걸쳐 골고루 분포되어 영상이 선명함을 알 수 있다. 

 

<각기 다른 히스토그램>

 

 


 

OpenCV를 이용하여 히스토그램을 작성하는 방법은 

1. cvCreateHist() 함수를 사용하여 작성할 히스토그램을 정의한다. 여기서는 히스토그램의 차원(dimension)과 히스토그램 차원의 크기를 지정한다. 여기서 차원이란, 채널의 수를 말하고 흑백영상이면 1차원, RGB 컬러영상이면 3차원이다. 차원의 크기는 색상을 몇 가지로 표현하느냐를 말한다. 

2. cvCalcHist() 함수를 이용하여 영상으로부터 히스토그램을 계산한다. 

3. 히스토그램을 작성하는데 있어서 막대(bin)의 높이를 조정하기 위해 cvGetMinMaxHistValue()함수를 이용하여 영상에서 최대 빈도수를 계산하고 cvScale()함수를 이용하여 최대 빈도수를 고려하여 막대의 높이를 조정한다. 히스토그램에서 높이 조절이 되지 않으면 영상의 분포를 정확히 파악할 수 없다.

4. 히스토그램에서 막대는 cvGetReal1D() 함수를 이용하여 빈도수를 구한다음 cvRectangle() 함수를 이용하여 표시한다. 

 

추가 설명)

 

1. cvCreateHist 함수

히스토그램을 정의하는데 사용하는 함수.

cvHistogram*cvCreateHist(int dims, int* sizes, int type, float** ranges=NULL, int uniform=1);

 

dims : 히스토그램 차원을 지정한다. 흑백영상 : 1차원, 컬러영상: 3차원

sizes : 히스토그램 차원의 크기를 나타내며 배열로 표시한다. 

예를 들어 1차원 256 흑백영상인 경우 int sizes[1] = {256}; 

3차원 컬러영상인 경우 int sizes[3] = {256, 256, 256};

type : 히스토그램 표현 형식을 타나낸다. 

ranges : 히스토그램의 x축 범위를 나타낸다.

uniform : 히스토그램에서 막대 간격을 같게 할 것인지 다르게 할 것인지 결정한다. 

uniform이 0이면 막대의 간격을 일정 간격으로 한다.

 

2. cvCalcHist 함수

영상으로부터 히스토그램을 계산하는데 사용하는 함수이다. 즉, 영상에서 cvCreateHist() 함수에 의해 이미 정의된 히스토그램을 계산한다.

void cvCalcHist( IplImage**img, CvHistogram*hist);