变换是将一个域的特征变换到另一个域,可能使在一个域不突出的特征在另一个域突出。这有助于对有用信号的提取与应用。
一、傅里叶变换
傅里叶变换是一种将时域信号转换到频域的方式,其在图像处理和分析方面有很多优势。
对于一幅图像,
图像中灰度变化缓慢的区域对应于较低的频率,而灰度变化较快的区域对应高频信息。因此,在频域图像中能量主要集中在低频部分,只有小部分的能量在高频部分。这一点在直观上也比较好理解,频率反映的是
信号变化的快慢,变化快的频率高,变化慢的频率低,在图像中边缘的信号变化明显,这样才能与周围对比度增强,因此边缘的多对于高频。
1、基本原理
图像的傅里叶变换与一般信号的变化类似。而在实际应用中,傅里叶变换的计算量很大,在处理图像时效率很低,所以引入了快速傅里叶变化。
2、代码实现
void fft2D(unsigned char* imgBuf, int width, int height)
{
int i, j, u, v;
float *buf = new float[width*height * 2];
for (i = 0; i<width*height; i++){
buf[i * 2 + 0] = imgBuf[i];
buf[i * 2 + 1] = 0;
}
float *array = new float[height * 2];
for (u = 0; u<width; u++){
for (v = 0; v<height; v++){
array[v * 2 + 0] = buf[v*width * 2 + u * 2 + 0];
array[v * 2 + 1] = buf[v*width * 2 + u * 2 + 1];
}
fft1D(array, width);
for (v = 0; v<height; v++){
buf[v*width * 2 + u * 2 + 0] = array[v * 2 + 0];
buf[v*width * 2 + u * 2 + 1] = array[v * 2 + 1];
}
}
delete[]array;
for (v = 0; v<height; v++){
fft1D(buf + v*width * 2, width);
}
//频域数据保存至fftBuf
fftBuf = buf;
//修改频域数据
int off;
//显示需要
float *buf1 = new float[width*height];
for (i = 0; i<width*height; i++)
buf1[i] = sqrt(buf[i * 2 + 0] * buf[i * 2 + 0] + buf[i * 2 + 1] * buf[i * 2 + 1]);
int mo = 2000;//模值
for (i = 0; i<width*height; i++){
if (buf1[i] / mo>255)
imgBuf[i] = 255;
else imgBuf[i] = buf1[i] / mo;
}
delete[]buf1;
}
3、算法应用
(1)、频率滤波
图像中边缘和噪声多对应于频率的高频部分,所以可以设计合适的低通滤波器对图像进行低通滤波,去掉图像的高频部分。
(2)、显著性检测
在
X,Hou &L,Zhang. Saliency Detection: A spectral residual approach. IEEE Conference on Computer Vision and Pattern Recognition, 2007, pp.1-8
这篇文章中,提出了频率分析图像显著性的方法,是一种不错的思路,虽然作者自己后来说了该文中的错误,不过也从数学公式上证明了理论的可行性。
二、K-L变换
K-L变换也叫做特征矢量、主分量变换。我们都知道在数理统计中,可以将多个相关的因素通过一组相互独立的变量来重新表示。
1、基本原理
首先看一个简单例子:假设x=(x1,x2)的四次观测点分别为(2,2)
(1,1)(-1,-1)(-2,-2),求其K-L变换。