灰度直方圖(histogram)是灰度級的函數,它表示圖象中具有每種灰度級的象素的個數,反映圖象中每種灰度出現的頻率。灰度直方圖的橫坐標是灰度級,縱坐標是該灰度級出現的頻率。
直方圖均衡化是通過灰度變換將一幅圖像轉換為另一幅具有均衡直方圖,即在每個灰度級上都具有相同的象素點數的過程。
對于離散圖像,轉換公式為
D = f( d ) = ( H0 + H1 + H2 + ... + Hd ) * Dmax / A0;
其中 Hi為第 i 級灰度的像素個數,A0 為圖像面積,Dmax 為最大灰度值。

原圖

原圖灰度直方圖

均衡化后

均衡化后灰度直方圖
1
/**//*
2
ProcessGrayZ.h
3
4
Copyright (C) 2011, coreBugZJ, all rights reserved.
5
6
256級灰度圖處理(灰度直方圖,直方圖均衡化)。
7
*/
8
9
10
#ifndef __PROCESSGRAY_Z_H_INCLUDED__
11
#define __PROCESSGRAY_Z_H_INCLUDED__
12
13
14
#include "TypeZ.h"
15
#include "ClassImageZ.h"
16
17
18
#define GRAY_NUM_Z 256
19
20
21
/**//* 獲得灰度直方圖數據 */
22
/**//* 參數 hist 要求數組大小至少256個元素 */
23
PublicFuncZ R32 getHistogramZ( cImageZ src, U32 hist[] );
24
/**//* 創建 256 * 256 黑白圖像,為繪制好的灰度直方圖 */
25
PublicFuncZ ImageZ createImageHistogramZ( cImageZ src );
26
/**//* 創建 直方圖均衡化 后的新圖像 */
27
PublicFuncZ ImageZ createImageHistogramEqualizationZ( cImageZ src );
28
29
30
#endif /* __PROCESSGRAY_Z_H_INCLUDED__ */
31
1
/**//*
2
ProcessGrayZ.c
3
4
Copyright (C) 2011, coreBugZJ, all rights reserved.
5
6
256級灰度圖處理(灰度直方圖,直方圖均衡化)。
7
*/
8
9
10
#include "stdafx.h"
11
#include "ProcessGrayZ.h"
12
13
#include <string.h>
14
15
16
PublicFuncZ R32 getHistogramZ( cImageZ src, U32 hist[] )
{
17
U32 i, x, y;
18
if ( (NULL == hist) || (!isImageValidZ(src)) || (GRAY_NUM_Z != src->colorNum) )
{
19
return RERR;
20
}
21
for ( i = 0; i < GRAY_NUM_Z; ++i )
{
22
hist[ i ] = 0;
23
}
24
for ( y = 0; y < src->height; ++y )
{
25
for ( x = 0; x < src->width; ++x )
{
26
++hist[ *( src->pPixel + src->linePitch * y + x ) ];
27
}
28
}
29
return ROK;
30
}
31
32
PublicFuncZ ImageZ createImageHistogramZ( cImageZ src )
{
33
ImageZ img = NULL;
34
U32 hist[ GRAY_NUM_Z ], mh, x, y;
35
ColorZ color;
36
37
if ( ROK != getHistogramZ( src, hist ) )
{
38
return NULL;
39
}
40
41
img = createImageZ( GRAY_NUM_Z, GRAY_NUM_Z, 2 );
42
if ( NULL == img )
{
43
return NULL;
44
}
45
46
color.r = color.g = color.b = 0;
47
color.a = 0;
48
putImagePaletteColorZ( img, 0, &color );
49
color.r = color.g = color.b = 255;
50
color.a = 0;
51
putImagePaletteColorZ( img, 1, &color );
52
53
memset( img->pPixel, 1, img->linePitch * img->height );
54
55
mh = 0;
56
for ( x = 0; x < GRAY_NUM_Z; ++x )
{
57
if ( mh < hist[ x ] )
{
58
mh = hist[ x ];
59
}
60
}
61
for ( x = 0; x < GRAY_NUM_Z; ++x )
{
62
y = hist[ x ] * GRAY_NUM_Z / mh;
63
y = GRAY_NUM_Z - y;
64
while ( GRAY_NUM_Z > y )
{
65
*( img->pPixel + y * img->linePitch + x ) = 0;
66
++y;
67
}
68
}
69
return img;
70
}
71
72
PublicFuncZ ImageZ createImageHistogramEqualizationZ( cImageZ src )
{
73
U32 hist[ GRAY_NUM_Z ], lut[ GRAY_NUM_Z ], x, y, i;
74
F64 cdf[ GRAY_NUM_Z ], size, sum, tf, t0, t255;
75
ImageZ img = NULL;
76
77
if ( ROK != getHistogramZ( src, hist ) )
{
78
return NULL;
79
}
80
81
MOV_F64_U32_Z( size, src->width );
82
MUL_F64_U32_Z( size, size, src->height );
83
84
MOV_F64_U32_Z( sum, 0 );
85
MOV_F64_U32_Z( t255, 255 );
86
MOV_F64_U32_Z( t0, 0 );
87
for ( i = 0; i < GRAY_NUM_Z; ++i )
{
88
ADD_F64_U32_Z( sum, sum, hist[ i ] );
89
DIV_F64_Z( cdf[ i ], sum, size );
90
MUL_F64_Z( tf, cdf[ i ], t255 );
91
MIN_F64_Z( tf, tf, t255 );
92
MAX_F64_Z( tf, tf, t0 );
93
MOV_U32_F64_Z( lut[ i ], tf );
94
}
95
96
img = createImageFromImageInfoZ( src );
97
if ( NULL == img )
{
98
return NULL;
99
}
100
if ( ROK != copyImagePaletteZ( img, src ) )
{
101
destroyImageZ( img );
102
return NULL;
103
}
104
for ( y = 0; y < img->height; ++y )
{
105
for ( x = 0; x < img->width; ++x )
{
106
*( img->pPixel + y * img->linePitch + x ) =
107
( (U08)( lut[ * ( src->pPixel + y * src->linePitch + x ) ]
108
)
109
);
110
}
111
}
112
return img;
113
}
114