对图像数据采用各种图像增强算法,提高图像的目视效果,方便人工解译、图像分类中的样本选取等。图像增强的主要目的根据特定的应用需求增强图像,以便于增强后的图像比原图像更适合于这种应用需求。
空间域增强处理是通过直接改变图像中的单个像元及其相邻像元的灰度值来增强图像。这种增强方式往往是有目的的,例如增强图像中线状地物细部部分或者主干部分等。
在物理电路中,有一种硬件称为滤波器,这种滤波器只允许某种特定的电流通过,而阻止其它电流,例如低通滤波器可以从电流中去除高频部分。滤波应用到图像处理中,可以对图像进行去噪声、增强特征或者探测图像中对象边缘。
卷积滤波是通过消除特定的空间频率来增强图像的方法,根据增强类型,可以分为低通滤波、带通滤波、高通滤波。此外,还有增强某些方向特征的方向滤波等。它们的核心部分是卷积核。卷积核一般是一个3×3或者5×5的数组,也可以是非等行列数数组。卷积运算的过程可以视为移动窗口分析。将卷积核置于待卷积分析的图像上,卷积核中间对应的像素值等于其他各个像元值和对应的卷积核的值之间的数学运算结果。
卷积运算首先将卷积核放在图像左上角的位置,如下图所示,然后根据一定的需求将卷积核的值与对应的图像的像元值进行运算,得出新的值后将该值赋予卷积核中心对应的像元。例如平滑运算,卷积核各值都是1,设C1,1为行列号为(1,1)处的初始像素值,则卷积运算后该位置的像素值C1,1’为:
C1,1’= (C0,0×1+C1,0×1+C2,0×1+C0,1×1+C1,1×1+C2,1×1+C0,2×1+C1,2×1+C2,2×1)/9
计算完成后,将卷积核(向右)移动到下一个位置,如下图所示。直到所有的值计算完毕。
scipy是一个用于数学、科学、工程领域的常用软件包,可以处理插值、积分、优化、图像处理、常微分方程数值解的求解、信号处理等问题。它用于有效计算Numpy矩阵,使Numpy和Scipy协同工作,高效解决问题。在scipy中有一个包称为ndimage,其中有许多方法可以用来处理滤波的问题,其中scipy.ndimage.filters.convolve可以用来进行卷积滤波操作,其形式及参数含义如下。scipy.ndimage.filters.convolve(input,weights, output=None, mode="reflect", cval=0.0, origin=0)
其参数含义为:
• input : 输入的图像数组。
• weights : 滤波器,或卷积核
• output : 输出的变量,可选;
• mode : 可选值,值的范围为{‘reflect’,’constant’,’nearest’,’mirror’, ‘wrap’},用来说明图像最外边的边界如何处理。从上面的图中可以看出,在进行卷积时,图像的最外面一圈像元无法进行滤波计算,如果要对最外层的像元进行滤波计算,必须将图像向外扩展,如果是3×3的滤波器,需要图像向外扩展1个像元,即原图像的左右边各增加1列,在图像的上下方各增加1行,如果是5×5的滤波器,则需要各增加2行或2列。但是增加的像元的值如何确定呢,这里的mode就是用来说明如何这些像元的值。默认是 ‘reflect’。下面以下图为例说明各个mode,浅灰色为3×3的滤波器所增加的像元,深灰色和浅灰色像元是为5×5的滤波器所增加的像元。
– reflect,(d c b a | a b c d | d c b a),反射模式, 以图像边界为对称轴向外延伸对称元素。例如下图中,所扩展的像元值以原图像的边界为对称轴与原图像的像元值形成轴对称。
– ’constant’, (k k k k | a b c d | k k k k),常数模式,在图像最外面增加一圈或若干圈像元,所增加的像元的值为一个常数,默认值为0,可以通过cval参数进行设置。例如下面图中所扩展的像元值设定为cval=1.
– ’nearest’, (a a a a | a b c d |d d d d),最近模式, 扩展的像元所填充的像元值为原始图像离边界最近的像元的值,如下图所示。
– ’mirror’, (d c b | a b c d | cb a),镜像模式, 所扩展的像元值以原图像的最外一圈像元为对称轴与原图像的内侧像元值形成轴对称,如下图所示。
– ‘wrap’ (a b c d | a b c d | a b c d),该模式中,在图像一侧所扩展的第一个像元值与该图像另一侧的第一个像元值一致。所扩展的第二个像元值与另一侧内部的第二个像元值一致,依次类推,如下图所示。
• cval : 如果mode为 ‘constant’的时候图像边界像元值的大小,默认是0.0
• origin : 卷积核在刚开始运算时候的位置,默认是0。
返回值为ndarray
下面举一个scipy帮助文档里面的例子解释卷积滤波的计算原理:
假设下图中左侧为图像的像元值矩阵,右侧为滤波器,使用该函数进行滤波操作的形式为:import numpy as npfrom scipy import ndimagea = np.array([[1, 2, 0, 0],[5, 3, 0, 4],[0, 0, 0, 7],[9, 3, 0, 0]])k = np.array([[1,1,1],[1,1,0],[1,0,0]])result = ndimage.convolve(a, k, mode="constant", cval=1.0)print(result)
输出结果为:
第二行引入scipy的ndimage包,第4行定义源数据矩阵变量,第8行定义滤波器,第11行使用滤波函数执行滤波操作。该滤波函数的计算步骤为:
(1) 先对原图像进行扩展,如本例中使用constant,即常数模式,设定扩展的像元值为1,即cval=1,则扩展后的图像为:
(2) 将滤波器旋转180°,
(3) 开始滤波计算,将滤波器移动到扩展后的图像左上角,
按照对应的元素开始计算:
0×1+0×1+1×1+0×1+1×1+1×2+1×1+1×5+1×3=13,
则原始图像左上角第一个像元的值变为13,
(4) 将滤波器向右移动一个像元,开始计算第二个像元的值。依次类推,直到所有像元值计算完毕。计算的新值如下。
下面使用一个Envi自带的实验影像数据进行高通卷积滤波处理。ENVI中高通滤波使用的是中心值为8,周围值为-1的3×3卷积核,即:
下面是代码:import osfrom osgeo import gdalimport numpy as npfrom scipy import ndimageos.chdir(r"F:/")bandfile = "can_tmr.img"dataset = gdal.Open(bandfile)mband = dataset.GetRasterBand(1)xsize = mband.XSizeysize = mband.YSizek = np.array([[-1,-1,-1],[-1,8,-1],[-1,-1,-1]])driver = gdal.GetDriverByName("GTiff")outDataset = driver.Create("image1.tif",xsize,ysize,6,gdal.GDT_Int16)for i in range(1,7):mband = dataset.GetRasterBand(i)data = mband.ReadAsArray().astype(np.int16)data = ndimage.convolve(data, k)outBand = outDataset.GetRasterBand(i)outBand.WriteArray(data)outDataset.SetGeoTransform(dataset.GetGeoTransform())outDataset.SetProjection(dataset.GetProjection())del dataset
代码中第14行开始定义一个高通卷积核,第18、19行定义新的tiff文件来存储卷积运算后的数据,因为原始数据有6个波段,所以在driver.Create方法中创建了6个波段,并且需要注意的是设置新数据集的数据类型为gdal.GDT_Int16,而不是使用原始数据的GDT_Byte,因为计算后的值会超过GDT_Byte的范围,造成卷积结果不正确。第21行到第26行开始逐波段对原始数据中的6个波段进行卷积运算。其中需要注意的是在第23行通过ReadAsArray将原始波段中的数据读出来后,要进行数据类型的转换,即在后面加上.astype(np.int16),将其值域范围进行扩展,否则也会造成卷积结果不正确。后面的代码都是常规功能,不再解释。
下面三幅图分别是原始图像、ENVI卷积结果和上面代码的卷积结果,基本一致。
原始图像
ENVI卷积结果
Scipy卷积结果
除了ndimage.convolve外,scipy还有其他的滤波器,例如:
• generic_filter:通用滤波器,用户可以自定义函数进行各种简单或复杂的操作;
• gaussion_filter:高斯滤波器,通过一个指定大小的高斯卷积函数对图像进行滤波;
• laplace:拉普拉斯算子,边缘增强滤波,它不考虑边缘的方向,强调图像中的最大值。
• maximum_filter:最大值滤波器,定义为图像局部区域内所有像素的最大值。通常应用于图像消除负的异常噪声。
• median_filter:中值滤波器,在保留大于卷积核的边缘的同时平滑图像,用于消除椒盐噪声或斑点。
• minimum_filter:最小值滤波器,该函数采用非线性最小滤波方法对图像进行滤波,通常应用于图像去除正的离群值噪声。
• prewitt:Prewitt算子是一阶微分算子的边缘检测,利用像素点上下、左右邻点的灰度差,在边缘处达到极值检测边缘,去掉部分伪边缘,对噪声具有平滑作用。
• sobel:Sobel滤波器,非线性边缘性增强滤波器。它考虑了水平、垂直和2个对角共计4个方向对的梯度加权求和,是一个3×3各向异性的梯度算子。
• uniform_filter,均值滤波器,可以去除均匀噪声和高斯噪声,但会对图像造成一定程度的模糊。
• percentile_filter,百分位滤波器。
• rank_filter:等级滤波
• ……
不列举了,详见scipy包。