前面几篇文章介绍的是图像的空间域滤波,其对像素的处理都是基于像素的某一邻域进行的。本文介绍的图像的灰度变换则不同,其对像素的计算仅仅依赖于当前像素和灰度变换函数。
灰度变换也被称为图像的点运算(只针对图像的某一像素点)是所有图像处理技术中最简单的技术,其变换形式如下:
s = T ( r )
其中,T 是灰度变换函数;r 是变换前的灰度;s 是变换后的像素。
图像灰度变换的有以下作用:
• 改善图像的质量,使图像能够显示更多的细节,提高图像的对比度(对比度拉伸)
• 有选择的突出图像感兴趣的特征或者抑制图像中不需要的特征
• 可以有效的改变图像的直方图分布,使像素的分布更为均匀
常见的灰度变换
灰度变换函数描述了输入灰度值和输出灰度值之间变换关系,一旦灰度变换函数确定下来了,那么其输出的灰度值也就确定了。可见灰度变换函数的性质就决定了灰度变换所能达到的效果。
用于图像灰度变换的函数主要有以下三种:
• 线性函数 (图像反转)
• 对数函数:对数和反对数变换
• 幂律函数:n次幂和n次开方变换
上图给出了几种常见灰度变换函数的曲线图,根据这几种常见函数的曲线形状,可以知道这几种变换的所能达到的效果。例如,对数变换和幂律变换都能实现图像灰度级的扩展/压缩,另外对数变换还有一个重要的性质,它能压缩图像灰度值变换较大的图像的动态范围(例如,傅立叶变换的频谱显示)。
线性变换
令 r 为变换前的灰度,s为变换后的灰度,则线性变换的函数:
s = a ⋅ r + b
其中,a 为直线的斜率,b 为在 y 轴的截距。选择不同的 a,b 值会有不同的效果:
• a > 1,增加图像的对比度
• a < 1,减小图像的对比度
• a = 1 且 b ≠ 0,图像整体的灰度值上移或者下移,也就是图像整体变亮或者变暗,不会改变图像的对比度。
• a < 0 且 b = 0,图像的亮区域变暗,暗区域变亮
• a = 1 且 b = 0,恒定变换,不变
• a = −1 且 b = 255,图像反转。
在进行图像增强时,上述的线性变换函数用的较多的就是图像反转了,根据上面的参数,图像反转的变换函数为:s = 255 − s。图像反转得到的是图像的负片,能够有效的增强在图像暗区域的白色或者灰色细节。其效果如下:
图像反转的实现是比较简单的,在 OpenCV 中有对 Mat 的运算符重载,可以直接 Mat r = 255 - img 或者 ~img 来实现。
对数变换
对数变换的通用公式是:
s = clog ( 1 + r )
其中,c 是一个常数,,假设 r ≥ 0,根据上图中的对数函数的曲线可以看出:对数变换,将源图像中范围较窄的低灰度值映射到范围较宽的灰度区间,同时将范围较宽的高灰度值区间映射为较窄的灰度区间,从而扩展了暗像素的值,压缩了高灰度的值,能够对图像中低灰度细节进行增强。;从函数曲线也可以看出,反对数函数的曲线和对数的曲线是对称的,在应用到图像变换其结果是相反的,反对数变换的作用是压缩灰度值较低的区间,扩展高灰度值的区间。
基于 OpenCV 的实现,其对数变换的代码如下:
float pixels[256]; for (int i = 0; i < 256; i++) pixels[i] = log(1 + i); Mat imageLog(image.size(), CV_32FC3); for (int i = 0; i < image.rows; i++) { for (int j = 0; j < image.cols; j++) { imageLog.at(i, j)[0] = pixels[image.at(i, j)[0]]; imageLog.at(i, j)[1] = pixels[image.at(i, j)[1]]; imageLog.at(i, j)[2] = pixels[image.at(i, j)[2]]; } } //归一化到0~255 normalize(imageLog, imageLog, 0, 255, CV_MINMAX); //转换成8bit图像显示 convertScaleAbs(imageLog, imageLog);
这使用的对数函数的底为10。由于灰度变换是灰度值之间的一对一的映射,而灰度值区间通常为[0,255],所以在进行灰度变换时,通常使用查表法。也就是,现将每个灰度值的映射后的结果计算出来,在变换时,通过查表得到变换后的灰度值。执行上面结果得到的结果如下:
左边为原图像,其拍摄环境较暗,无法分辨出很多的细节;右边为变换后的图像,整个图像明亮许多,也能分辨出原图中处于暗区域的狗狗的更多细节。
技术专区
- 介绍GPU与FPGA的几个方面和看法
- Android OpenGL ES开发:投影和相机视图创建和应用
- 软件开发过程中需要的十三类文档
- 图像处理之图像的灰度变换
- 一种基于ARM S3C2410X和Linux的嵌入式网络摄像机设计