STEP 1
使用函数tofloat把输入图像转换为浮点图像:
[f,revertclass] = tofloat(f);
此函数的定义如下:
function [out,revertclass] = tofloat(in)
%TOFLOAT convert image to floating point.
%通过适当的比例因子,将logical、unit8、unit16、int16类的图像变换成single类
%函数句柄是一种数据类型,故table中可以使用,并且句柄可以在函数体内定义,不用再单独写一个函数
identity=@(x) x;
tosingle=@im2single;
table={'uint8',tosingle,@im2unit8
'uint16',tosingle,@im2unit16
'int16',tosingle,@im2int16
'logical',tosingle,@logical
'double',identity,identity
'single',identity,identity};
classIndex=find(strcmp(class(in),table(:,1)));
if isempty(classIndex)
error('Unsupport input image class.');
end
out=table{classIndex,2}(in);
revertclass = table{classIndex,3};
具体为什么要用tofloat,书上写的是不必设计缩放问题,在使用fft2时,数据类型会变为double,但若原数据类型为single,则不变,所以在ifft2时,使用revertclass比较方便。
新知识:经过实验,若不使用tofloat,当fft2后再使用ifft2,会导致图像显示错误。
![](https://img-blog.csdnimg.cn/direct/7800d08387784ede90448bb76ebdbd67.png)
![](https://img-blog.csdnimg.cn/direct/aecc59a87f994a86916d1df0a27c723b.png)
STEP 2
使用paddedsize获得填充参数
function PQ = paddedsize(AB, CD, PARAM) %PARAM是形参
if nargin == 1
PQ=2*AB;
elseif nargin == 2 && ~ischar(CD)
PQ = AB+CD-1;
PQ = 2*ceil(PQ/2);
elseif nargin == 2
m=max(AB);
P=2^nextpow2(2*m);
PQ=[P,P];
elseif(nargin==3)&&strcmp(PARAM,'pwr2')
m=max([AB CD]);
P=2^nextpow2(2*m);
PQ=[P,P];
else
error('Wrong number of input.')
end
通过paddedsize可以避免折叠误差,在使用imfilter时会默认使用0来填充图像边框。
就像时域卷积需要补零一样,频域也需要填充,只要按照具体的填充规则就能避免误差,至于为什么这样做,可能需要进一步的学习才能解答。
STEP 3
F = fft2(f,PQ(1),PQ(2));
STEP 4
生成一个大小为PQ(1)*PQ(2)的滤波器函数(这里指傅里叶变换后的函数),具体生成方法会单独写一篇文章
STEP 5
G=H.*F
此处采用.*,意为对应元素相乘。
STEP 6
对G进行傅里叶逆变换
STEP 7
将左上部的矩形裁剪为原始大小
STEP 8
需要时,将滤波后的图像转换为输入图像的类。
总结
上述DFT滤波可使用一个M函数实现,本函数中的h为滤波器函数,满足以下条件
1.h为频域函数
2.假定滤波器函数大小已被适当调节
function g = dftfilt(f,h,classout)
[f,revertClass]=tofloat(f);
F=fft2(f,size(h,1),size(h,2));
g=ifft2(F.*h);
g=g(1:size(f,1),1:size(f,2));
if nargin ==2 ||strcmp(classout,'original')
g=revertClass(g);
elseif strcmp(classout,'fltpoint')
return
else
error('wrong classout')
end
疑问fftshift
Y = fftshift(X)
通过将零频分量移动到数组中心,重新排列傅里叶变换 X
。
如果 X
是矩阵,则 fftshift
会将 X
的第一象限与第三象限交换,将第二象限与第四象限交换。
X = ifftshift(Y)
将进行过零频平移的傅里叶变换 Y
重新排列回原始变换输出的样子。换言之,ifftshift
就是撤消 fftshift
的结果。
如果 Y
是矩阵,则 ifftshift
会将 Y
的第一象限与第三象限交换,将第二象限与第四象限交换。
若矩阵行列均为偶数,则ff和iff可以互换使用,若否,则不能互换,因为两个函数区分1,2,3,4象限的规则有所不同。
用处:
1.展示频谱
S=fftshift(log(1+abs(F))); % log使得展示更加明显
2.频域滤波
个人的一点理解
在频域相乘时,保持滤波器原点位于频率矩形的左上角,只有当需要被滤波的图像fftshift后,才需要把滤波器居中,一般二维矩阵在fft2后得到的频谱为不居中的。
频域中的滤波器可称为传递函数,如果将此传递函数h独立理解,不等于被滤波的图像F,拿低通滤波举例,若F未居中处理,则h也要求不居中,通过fftshift可以将中间突起的传递函数更改为四角突起的传递函数,此处不考虑fftshift将0频分量移至中心,仅考虑
讲的太混乱了,清明之后接着往下学习,理理思路,希望能讲清。