图像直方图变换的基本原理:
设变量r代表图像中像素的灰度级,直方图变换就是假定一个变换式:
(1-1)
也就是,通过上述变换,每个原始图像的像素灰度级r都会产生一个s值。变换函数T(r)应满足以下条件:
(1) T(r)在区间中为单值且单调递增;
(2) 当 时,,即T(r)的取值范围与r相同。
2. 直方图均衡化:
对于离散值,我们处理其概率与求和,而不是概率密度函数与积分。一幅图像中灰度级rk出现的概率近似为
(1-2)
其中,n是图像中像素的总和, 是灰度级 的像素个数,L为图像中可能的灰度级总数。
(1-3)
上式中变换函数的离散形式为:
(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;
}
处理前图像
处理后图像