Computer Vision

히스토그램 평활화(Histogram Equalization)

익플루 2014. 6. 9. 21:09
반응형

히스토그램 평활화에 대해 살펴보자

평활화 하는 이유를 알아야 한다.

 

 

히스토그램 평활화는 원본영상을 개선하기 위한 작업이지만,

추가적으로 데이터를 더 첨가 하지는 않는다. 다만, 히스토그램의 형상을 분석하여 밝기 분포가 특정한 부분으로 치우친 것을 어느정도 넓은 영역에 걸쳐 밝기 분포를 넓히는 것이다.

--> 존재하는 데이터의 총 양은 변하지 않는다.

 

why 평활화?

인간의 눈은 영상의 절대적 밝기의 크기보다 대비가 증가할 때 인지도가 증가한다.

 

 

 

AVE256.RAW

이런 영상이 있다. 전체적으로 어두우며 이 영상의 히스토그램은.

 result.raw

 

히스토그램 평활화를 해보자

 

 

#include <math.h>
#include <windows.h>
#include <stdio.h>
using namespace std;


int main()
{
 
 int height= 256;
 int width=256;
 int i,j,vmax,vmin;
 int m_HistoArr[256];
 unsigned char OrgImg[256][256];
 

 FILE *infile= fopen("AVE256.raw","rb");
 if(infile==NULL){printf("error!");return 0;}
 fread(OrgImg, sizeof(char),256*256,infile);
 fclose(infile);
  

 
 /// histogram연산을 위해 사용할 배열메모리를 할당
 unsigned int *histogram = new unsigned int [256];
 unsigned int *sum_hist = new unsigned int [256];

 /// histogram배열을 초기화
 for(i=0; i<256; i++) histogram[i]=0;

 /// 영상의 histogram을 계산
 for(i=0; i<height; i++)
 {
  for(j=0; j<width; j++) histogram[OrgImg[i][j]]++;
 }

 /// histogram의 정규화된 합을 계산
 int sum=0;
 float scale_factor=255.0f/(float)(height*width);

 for(i=0; i<256; i++)
 {
  sum += histogram[i];
  sum_hist[i] =(int)((sum*scale_factor) + 0.5);
 }

 /// LUT로써 sum_hist배열을 사용하여 영상을 변환
 for(i=0; i<height; i++)
 {
  for(j=0; j<width; j++) OrgImg[i][j]=sum_hist[OrgImg[i][j]];
 }

 // 메모리를 해제
 delete []histogram; delete []sum_hist;


 FILE *outfile = fopen("result.raw","wb");
 fwrite(OrgImg,sizeof(char),256*256,outfile);
 fclose(outfile);
 

 return 0;
}

 

히스토그램 평활화의 단계

1) 원시 입력영상의 밝기값에 대한 히스토그램을 생성한다.
2) 생성된 히스토그램을 정규화합 히스토그램으로 변형한다.
3) 정규화합 히스토그램을 이용하여 입력영상을 다시 매핑한다.

 

평활화한 결과는

AVE256_2.raw(왼쪽)

result.raw(오른쪽)

영상의 밝기가 전체적으로 밝아진다고 해서 가시도가 높은 것이 아니고

위 오른쪽 영상의 히스토그램처럼 공고루 밝기값이 존재하는 것이 사람이 인식하기가 쉬워진다.(가시도가 증가한다)

 

*참고*

 평활화 된 히스토그램은

h(i) = G/N * H(i)

h(i) : 보정값
G : 최대 밝기
N : 영상 크기(존재 픽셀의 수)
H(i) : 히스토그램 빈값

을 따른다.

 

반응형