목차
1. 우선 비트맵 파일에 대해 자세히 알아보자
2. 비트맵 사용시 주의할 사항
3. 히스토그램 평활화 (Histogram equalize)
4. 주요 알고리즘
5. source code
6. 결과 화면
7. 결과
2. 비트맵 사용시 주의할 사항
3. 히스토그램 평활화 (Histogram equalize)
4. 주요 알고리즘
5. source code
6. 결과 화면
7. 결과
본문내용
{
double min, a;
if((r<=g) && (r<=b))
min = r;
else if((g<=r) && (g<=b))
min = g;
else
min = b;
i=(r+g+b) / 3.0;
if((r==g) && (g==b)){
s = 0.0;
h = 0.0;
return;
}
else
{ s = 1.0-(3.0/(r+g+b))*min;
a = (r-0.5*g-0.5*b)/sqrt((r-g)*(r-g)+(r-b)*(g-b));
h = acos(a);
h *= 57.29577951; }
if(b>g)
h = 360-h;
}
// HIS를 RGB형식으로 변환하는 함수
void HIS_to_RGB(double &r, double &g,double &b, double h, double s, double i)
{
double size, a1, a2 ;
//명도
if(i == 0){
r = 0;
g = 0;
b = 0;
return;}
//채도
if(s == 0){
r = i;
g = i;
b = i;
return;}
//색상 (변환 알고리즘은 소스참조했습니다.)
if(h<0.0)
h += 360;
size = 3.0 * i;
if(h<=120)
{
a1 = (h * 0.017453293);
a2 = ((60.0 - h)*0.017453293);
b = ((1.0 - s) / 3.0);
r = ((1.0 + (s*cos(a1) / cos(a2))) /3.0);
g = (1.0 - r - b);
b *= size;
r *= size;
g *= size;
}
else if((h>120) && (h<= 240))
{
h -= 120;
a1 = (h * 0.017453293);
a2 = ((60.0 - h) * 0.017453293);
r = ((1.0 - s) / 3.0);
g = ((1.0 + (s * cos(a1) / cos(a2))) /3.0);
b = (1.0 - r - g);
r *= size;
g *= size;
b *= size;
}
else
{
h -= 240;
a1 = (h*0.017453293);
a2 = ((60.0 - h) * 0.017453293);
g = ((1.0-s)/3.0);
b = ((1.0 + (s * cos(a1) / cos(a2))) / 3.0);
r = (1.0 - g - b);
r *= size;
g *= size;
b *= size;
}
}
// 히스토그램 평활화 함수
void Equalize(double *buffer, unsigned long pixnum)
{
unsigned long value[256]; // 히스토그램 이미지 저장
unsigned long value_sum[256]; // 히스토그램 합 저장
unsigned long i; // 인덱스 변수
unsigned long sum; // 히스토그램의 합을 증가시키는 변수
double factor; // 스케일 팩터
for(i=0; i<256; i++) // 히스토그램을 0으로 클리어 시킨다.
value[i] = 0;
for(i=0; i
value[(int)buffer[i]]++;
//calculate normalized sum of hist
sum = 0;
factor = 255.0 / pixnum; // factor 값은은 더블형으로 선언되었다.
// 255 / pixnum 하면 이상 결과 출력
for(i = 0; i<256; i++) {
sum += value[i];
value_sum[i] = (unsigned long)((sum * factor) + 0.5);}
// transform image using new sum_hist as a LUT
for(i=0; i
buffer[i] = value_sum[(int)buffer[i]];
}
/************************************************************************************ * bmpfile view function *
************************************************************************************/void Viewing_BMP(char bmpfilename[])
{
#ifdef WINDOWS
ShellExecute(
NULL,
/* HWND hwnd * 윈도위의 부모 윈도우를 두구 열때.. 부모의 핸들을 넘긴다.
*/
"open", /* LPCTSTR lpOperation
* "open" 실행 파일 열때
* "print" 파일을 프린트 할때
* "explore" 디랙토리 탐색형으로 열때(탐색기 열때)
"mspaint", /* LPCTSTR lpFile
* 실행 파일명..
* 도스 쉘상테에서 HTTP://www.daum.net으로 치면 인터넷 익스플로러 뜸.
*/
bmpfilename, /* LPCTSTR lpParameters
* 파일을 오픈할때 사용할 파라미터..
*/
NULL, /* LPCTSTR lpDirectory
* 사용할 디렉터리..(실행시킬 프로그램의 위치 )
*/
SW_SHOW /* INT nShowCmd
* SW_HIDE SW_MAXIMIZE SW_MINIMIZE SW_RESTORE
* SW_SHOW SW_SHOWDEFAULT SW_SHOWMAXIMIZED
* SW_SHOWMINIMIZED SW_SHOWMINNOACTIVE
* SW_SHOWNA SW_SHOWNOACTIVATE SW_SHOWNORMAL
*/
);
#else
char temp[_MAX_PATH]; // stdlib.h 파일의 가장긴 path 길이를 얻는다.
sprintf(temp,"mspaint %s",bmpfilename);
system(temp);
#endif
}
결과 화면
sample.bmp
result.bmp
결과
히스토그램을 나타낸 것은 평활화의 과정을 보이기위해 다른 응용프로그램에 BMP 파일을 넣어 얻어낸 것입니다. 위에서 보면 알수있듣이 명압값 분포가 넓어진 것을 확인할 수 있습니다.
double min, a;
if((r<=g) && (r<=b))
min = r;
else if((g<=r) && (g<=b))
min = g;
else
min = b;
i=(r+g+b) / 3.0;
if((r==g) && (g==b)){
s = 0.0;
h = 0.0;
return;
}
else
{ s = 1.0-(3.0/(r+g+b))*min;
a = (r-0.5*g-0.5*b)/sqrt((r-g)*(r-g)+(r-b)*(g-b));
h = acos(a);
h *= 57.29577951; }
if(b>g)
h = 360-h;
}
// HIS를 RGB형식으로 변환하는 함수
void HIS_to_RGB(double &r, double &g,double &b, double h, double s, double i)
{
double size, a1, a2 ;
//명도
if(i == 0){
r = 0;
g = 0;
b = 0;
return;}
//채도
if(s == 0){
r = i;
g = i;
b = i;
return;}
//색상 (변환 알고리즘은 소스참조했습니다.)
if(h<0.0)
h += 360;
size = 3.0 * i;
if(h<=120)
{
a1 = (h * 0.017453293);
a2 = ((60.0 - h)*0.017453293);
b = ((1.0 - s) / 3.0);
r = ((1.0 + (s*cos(a1) / cos(a2))) /3.0);
g = (1.0 - r - b);
b *= size;
r *= size;
g *= size;
}
else if((h>120) && (h<= 240))
{
h -= 120;
a1 = (h * 0.017453293);
a2 = ((60.0 - h) * 0.017453293);
r = ((1.0 - s) / 3.0);
g = ((1.0 + (s * cos(a1) / cos(a2))) /3.0);
b = (1.0 - r - g);
r *= size;
g *= size;
b *= size;
}
else
{
h -= 240;
a1 = (h*0.017453293);
a2 = ((60.0 - h) * 0.017453293);
g = ((1.0-s)/3.0);
b = ((1.0 + (s * cos(a1) / cos(a2))) / 3.0);
r = (1.0 - g - b);
r *= size;
g *= size;
b *= size;
}
}
// 히스토그램 평활화 함수
void Equalize(double *buffer, unsigned long pixnum)
{
unsigned long value[256]; // 히스토그램 이미지 저장
unsigned long value_sum[256]; // 히스토그램 합 저장
unsigned long i; // 인덱스 변수
unsigned long sum; // 히스토그램의 합을 증가시키는 변수
double factor; // 스케일 팩터
for(i=0; i<256; i++) // 히스토그램을 0으로 클리어 시킨다.
value[i] = 0;
for(i=0; i
//calculate normalized sum of hist
sum = 0;
factor = 255.0 / pixnum; // factor 값은은 더블형으로 선언되었다.
// 255 / pixnum 하면 이상 결과 출력
for(i = 0; i<256; i++) {
sum += value[i];
value_sum[i] = (unsigned long)((sum * factor) + 0.5);}
// transform image using new sum_hist as a LUT
for(i=0; i
}
/************************************************************************************ * bmpfile view function *
************************************************************************************/void Viewing_BMP(char bmpfilename[])
{
#ifdef WINDOWS
ShellExecute(
NULL,
/* HWND hwnd * 윈도위의 부모 윈도우를 두구 열때.. 부모의 핸들을 넘긴다.
*/
"open", /* LPCTSTR lpOperation
* "open" 실행 파일 열때
* "print" 파일을 프린트 할때
* "explore" 디랙토리 탐색형으로 열때(탐색기 열때)
"mspaint", /* LPCTSTR lpFile
* 실행 파일명..
* 도스 쉘상테에서 HTTP://www.daum.net으로 치면 인터넷 익스플로러 뜸.
*/
bmpfilename, /* LPCTSTR lpParameters
* 파일을 오픈할때 사용할 파라미터..
*/
NULL, /* LPCTSTR lpDirectory
* 사용할 디렉터리..(실행시킬 프로그램의 위치 )
*/
SW_SHOW /* INT nShowCmd
* SW_HIDE SW_MAXIMIZE SW_MINIMIZE SW_RESTORE
* SW_SHOW SW_SHOWDEFAULT SW_SHOWMAXIMIZED
* SW_SHOWMINIMIZED SW_SHOWMINNOACTIVE
* SW_SHOWNA SW_SHOWNOACTIVATE SW_SHOWNORMAL
*/
);
#else
char temp[_MAX_PATH]; // stdlib.h 파일의 가장긴 path 길이를 얻는다.
sprintf(temp,"mspaint %s",bmpfilename);
system(temp);
#endif
}
결과 화면
sample.bmp
result.bmp
결과
히스토그램을 나타낸 것은 평활화의 과정을 보이기위해 다른 응용프로그램에 BMP 파일을 넣어 얻어낸 것입니다. 위에서 보면 알수있듣이 명압값 분포가 넓어진 것을 확인할 수 있습니다.