【studyLog】数字图像处理 C++实现一些图像增强和处理技术
图像增强技术概览
图像灰度变换增强
线性灰度增强
通过改变灰度值的范围改变图像的亮度:当范围区间越靠近黑色时,图像亮度越低;当范围区间越大时,图像亮度越高。
*lpDst = (BYTE)(((float)(gMax-gMin)/255)*pixel+gMin+0.5);//像素值的计算
//BYTE gMin-变换后目标图像的最小灰度值
//BYTE gMax-变换后目标图像的最大灰度值
效果对比:
分段线性灰度增强
分段线性变换函数来增强图像对比度的方法实际是增强原图各部分的反差,即增强输入图像中感兴趣的灰度区域,相对抑制那些不感兴趣的灰度区域。
if (pixel < gSrc1)//像素值的计算
{
*lpDst = (BYTE)((float)(gDst1 / gSrc1))*pixel;
}
else if (pixel <= gSrc2)
{
*lpDst = (BYTE)(((float)((gDst2 - gDst1) / (gSrc2 - gSrc1)))*(pixel - gSrc1) + gDst1);
}
else if (pixel <= 255)
{
*lpDst = (BYTE)(((float)((255 - gDst2) / (255 - gSrc2)))*(pixel - gSrc2) + gDst2);
}
//BYTE gSrc1, BYTE gSrc2-原图像灰度区间分段点
//BYTE gDst1, BYTE gDst2-变换后的目标图像灰度区间分段点
效果:
非线性灰度增强
指数函数变换
增强高灰度值,抑制低灰度值,经过指数变换后的图像细节丢失,对比度强。
*lpDst = (BYTE)(pow(b, c*(pixel - a)) - 1 + 0.5);//像素值的计算
//double a -调整曲线的位置
//double b, double c-调整曲线的形状
效果:
对数函数变换:
增强低灰度值,压缩高灰度值,经过对数变换后的图像的较暗区域得到增强。适用于:夜晚拍摄的过暗的夜景照片。可以增强其细节。
*lpDst = (BYTE)((log((double)(pixel+1)))/(b*log(c))+a+0.5);//像素值的计算
//double a -调整曲线的位置
//double b, double c-调整曲线的形状
效果:
直方图增强
直方图均衡化
效果
噪声添加
效果
图像平滑
均值滤波
更适用于处理高斯噪声,不能去掉很突出的噪声,只会中和掉他们,且处理后的图像有模糊化的趋势。
效果
中值滤波
更适用于处理椒盐噪声,可以把图像中很突出的噪声点去掉,且处理后的图像不会很模糊。
效果
算术运算
加法和减法运算
实现图像的融合和分离,考虑到图片大小不一定一致的问题
交互内容;设置融合的位置和透明度
效果
基本几何变换
平移变换
效果
镜像变换
效果
旋转变换
效果
缩放变换
效果
基本知识
1、BMP图像的坐标系:图像左下角为原点
2、判断BMP图像是灰度图还是彩色图:获取单个像素所占的位数。对于256色位图,1个像素的颜色值占1个字节;对于真彩色位图,一个像素的颜色值占3个字节。
3、真彩色位图RGB存放的顺序:B G R
4、LPBYTE:指向一个字节的指针
5、memcpy()、memset()的操作单位都是字节,不是像素。
未解决的BUG:断点问题
“触发断点”问题
这个出现在了旋转变换(需要扩大图像,即内存改变)、缩放变换(需要扩大或缩小图像,即内存大小改变)、拼接图像(需要扩大图像,即内存改变),非常头疼。开始以为是内存复制越界了,比如在memset()时出现错误。但再三检查后排除了这个可能;后来猜测是不是开辟的内存空间不够,因为处理灰度图像的时候没有出现这个问题,只要一处理彩色图像就出现了断点错误。查阅资料发现可能是LocalAlloc()有问题。因为该函数用于从局部堆中分配内存供程序使用,由于每个进程的局部堆很小,所以在局部堆中分配内存会受到空间的限制。但是换成GlobalAlloc()或者VirtualAlloc()还是报同样的错误。
解决方法:
在对彩色图像进行旋转变换和缩放变换中,注意图像的大小(彩色图像中一个像素占三个字节),必要的时候先对彩色图像进行缩小变换,再旋转/放大就不会报错“出现断点”了。在图像拼接中,使用了Opencv的函数直接对两个图像进行拼接。