直方图均衡化原理及c++代码

时间:2021-04-15 02:04:57

 图像直方图变换的基本原理

设变量r代表图像中像素的灰度级,直方图变换就是假定一个变换式:

直方图均衡化原理及c++代码                            (1-1)

也就是,通过上述变换,每个原始图像的像素灰度级r都会产生一个s值。变换函数T(r)应满足以下条件:

(1)       T(r)在区间直方图均衡化原理及c++代码中为单值且单调递增;

(2)       当 直方图均衡化原理及c++代码时,直方图均衡化原理及c++代码,即T(r)的取值范围与r相同。

2. 直方图均衡化:

对于离散值,我们处理其概率与求和,而不是概率密度函数与积分。一幅图像中灰度级rk出现的概率近似为

直方图均衡化原理及c++代码                                                (1-2)

其中,n是图像中像素的总和, 是灰度级 的像素个数,L为图像中可能的灰度级总数。

直方图均衡化原理及c++代码

                                               (1-3)

         上式中变换函数的离散形式为:    

直方图均衡化原理及c++代码

                                             (1-4)

         式(1-4)给出的变换(映射)称为直方图均衡化或直方图线性化。

//***************************************************************************************************************************************

//c++实现

BOOL CDibImage::InteEqualize(LPSTR lpDIBBits, LONG lWidth, LONG lHeight)
{
unsigned char*lpSrc; // 指向源图像的指针
LONG lTemp;// 临时变量
LONG i;// 循环变量
LONG j;
BYTE bMap[256];// 灰度映射表
LONG lCount[256];// 灰度映射表
LONG lLineBytes;// 图像每行的字节数

lLineBytes = WIDTHBYTES(lWidth * 8);// 计算图像每行的字节数

for (i = 0; i < 256; i ++)// 重置计数为0
{
lCount[i] = 0;
}

// 计算各个灰度值的计数
for (i = 0; i < lHeight; i ++)
{
for (j = 0; j < lWidth; j ++)
{
lpSrc = (unsigned char *)lpDIBBits + lLineBytes * i + j;
lCount[*(lpSrc)]++;
}
}

// 计算灰度映射表
for (i = 0; i < 256; i++)
{
lTemp = 0;
for (j = 0; j <= i ; j++)
{
lTemp += lCount[j];
}

// 计算对应的新灰度值
bMap[i] = (BYTE) (lTemp * 255 / lHeight / lWidth);
}

for(i = 0; i < lHeight; i++)// 每行
{
for(j = 0; j < lWidth; j++)// 每列
{
// 指向DIB第i行,第j个象素的指针
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;
// 计算新的灰度值
*lpSrc = bMap[*lpSrc];
}
}

return TRUE;
}

处理前图像

直方图均衡化原理及c++代码

处理后图像

直方图均衡化原理及c++代码