히스토그램 평활화에 대해 살펴보자
평활화 하는 이유를 알아야 한다.
히스토그램 평활화는 원본영상을 개선하기 위한 작업이지만,
추가적으로 데이터를 더 첨가 하지는 않는다. 다만, 히스토그램의 형상을 분석하여 밝기 분포가 특정한 부분으로 치우친 것을 어느정도 넓은 영역에 걸쳐 밝기 분포를 넓히는 것이다.
--> 존재하는 데이터의 총 양은 변하지 않는다.
why 평활화?
인간의 눈은 영상의 절대적 밝기의 크기보다 대비가 증가할 때 인지도가 증가한다.
이런 영상이 있다. 전체적으로 어두우며 이 영상의 히스토그램은.
히스토그램 평활화를 해보자
#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) : 히스토그램 빈값
을 따른다.
'Computer Vision' 카테고리의 다른 글
가우시안 스무딩(gaussian smoothing) (1) | 2014.06.12 |
---|---|
명암대비 히스토그램 스트레칭(contrast stretching) (0) | 2014.06.11 |
히스토그램(histogram building) (12) | 2014.06.06 |
보간(Interpolation)이란 (0) | 2014.04.09 |
openCV를 사용한 그림자 합성 shadow add shadow sum (0) | 2014.03.13 |