(day1)数字图像处理与机器视觉啃书随笔
一、BMP位图的结构
BMP由位图文件头、位图信息头、调色板、实际位图数据这一顺序四部分组成。
其中位图信息头包含了位图的宽高像素数、是否压缩、图像大小、是否压缩等信息,是与设备无关的。
规定位图的左上角是图像原点,且位图的每一行占用的字节数必须是4字节的整数倍。
二、灰度直方图
1.归一化直方图
归一化是遍历图像,按照灰度值分类,以此来累加灰度值计数器。为了归一化,最后要用各个等级的灰度值除图像总面积。 代码如下(示例):BOOL CImgProcess::GenHist(double * pdHist, int n)
{
// 首先检查图像的类型,这里的m_pBMIH保存位图的信息头
if (m_pBMIH->biBitCount!=8) return false;
// 检查n范围
if ((n<=0)||(n>256)) return false;
// 计算分段因子
double dDivider;
memset(pdHist, 0, n * sizeof(double));
dDivider = 256.0 / (double)n;
BYTE bGray; // 临时变量,存储当前光标像素的灰度值
for (int i=0; i<m_pBMIH->biHeight; i++)
{
for (int j=0; j<m_pBMIH->biWidth; j++)
{
bGray = GetGray(j, i);//GetGray函数定义在Imp.cpp中,功能是获取指定坐标的灰度值
pdHist[(int)(bGray / dDivider)]++; // 指定的灰度区间自加
}
};
UINT square = m_pBMIH->biWidth * m_pBMIH->biHeight;
for (int k=0; k<n; k++)
{
pdHist[k]=pdHist[k]/square;
}
return true;
}
注:RGB转灰度图像的原理
double dGray = (0.30*r + 0.59*g + 0.11*b);//RGB值和灰度的转换,实际上是人眼对于彩色的感觉到亮度感觉的转换,这是一个心理学研究结果
2.灰度的线性变换
灰度的线性变换函数:
f (x) = kx + d
其中,改变k即改变图像对比度,改变b即改变图像整体亮度。
代码如下:
BOOL CImgProcess::LinTran(CImgProcess* pTo, double dFa, double dFb)
{
// 首先检查图像是否是8位灰度图像
if (m_pBMIH->biBitCount!=8) return false;
BYTE gray; // 临时变量,存储当前光标像素的灰度值
int target; // 临时变量,存储当前光标像素的目标值
for (int i=0; i<m_pBMIH->biHeight; i++)
{
for (int j=0; j<m_pBMIH->biWidth; j++)
{
gray = GetGray(j, i);
target = int (dFa * gray + dFb);
if (target < 0) target = 0;
if (target > 255) target = 255;
// 写入目标图像
pTo->SetPixel(j, i, RGB(target, target, target));
}
};
return true;
}
3.灰度的对数变换
灰度的对数变换函数:
T(r)=clog(r+1)
其中,c是变换尺度,r是原值。
对数变换可以增强图像中暗处的细节,因此广泛用于频谱图像的显示中,典型就是傅里叶频谱。傅里叶变换后,动态范围极大,会丢掉大量暗处细节,因此要先用对数变换处理。
target = int (dC * log( (double)(gray + 1) ));
4.灰度的伽马变换
又称指数变换或幂指变换,灰度的伽马变换函数:
y=(x+esp)^γ
伽马变换可以选择增强图像的暗处或亮处的对比度。
当γ>1时,图像的高灰度区域对比度得到增强
当γ<1时,图像的低灰度区域对比度得到增强
当γ=1时,相当于线性变换,图像的对比度不得到增强
target = int (pow( (gray+comp)/255.0, gamma ) * 255);
4.灰度的阈值变换
灰度的阈值变换函数:
0 x<T
ƒ(x)= (T为指定的阈值)
255 x>=T
又称二值变换
void CImgProcess::Threshold(CImgProcess *pTo, BYTE bThre)
{
int i, j;
BYTE bt;
for(j = 0; j < m_pBMIH->biHeight; j ++)
{
for(i=0; i<m_pBMIH->biWidth; i++)
{
bt = GetGray(i, j);
if(bt<bThre)
bt = 0;
else
bt = 255;
pTo->SetPixel(i, j, RGB(bt, bt, bt));
}
}
}