在频域中过滤

时间:2015-04-03 15:06:20

标签: matlab image-processing dft

我必须将prewit过滤器应用于频域中的图像。这是我正在遵循的程序。

1)通过填充零将图像的NxN矩阵转换为2 * Nx2 * N矩阵

2)通过将图像与(-1)^(x + y)

相乘来使图像变换居中

3)计算图像矩阵的DFT

4)创建尺寸为2Nx2N的滤波器和坐标为(N,N)

的中心

5)将图像矩阵与滤波器矩阵相乘

6)计算它的逆DFT并提取结果的实部。

7)通过乘以(-1)^(x + y)

来分散结果

8)最后提取所得矩阵的左上NxN部分

我的代码如下:

% mask=[-1,0,1;-1,0,1;-1,0,1];

%read image
signal=imread('cman.pgm');
signal=double(signal);

% image has NxN dimensions
l=size(signal,1);

pad_signal=zeros(2*l,2*l);

pad_signal(1:l,1:l)=signal;

m=size(mask,1);

mask_f=zeros(2*l,2*l);

for i=-1:1
   mask_f(l+i,l-1)=-1;

   mask_f(l+i,l+1)=1;
end

x=1:2*l;

[x y]=meshgrid(x,x);

% Multiply each pixel f(x,y) with (-1)*(x+y)
pad_signal=pad_signal.*((-1).^(x+y));
mask_f=myDFT(mask_f);

%find the DFT of image
signal_dft=myDFT(pad_signal);

%multiply the filter with image
res=mask_f*signal_dft;

% find the inverse DFT of real values of result
res=real(myIDFT(res));

res=res.*((-1).^(x+y));

%extract the upper left NxN portion of the result
res=res(1:l,1:l);

imshow(uint8(res)); 

上述方法来自图像处理书。我感到困惑的是,我应该使用3x3的窗口作为prewitt过滤器是3x3还是我目前使用过滤器的方法是正确的? (即通过将滤波器值置于2Nx2N滤波器矩阵的中心并将所有其他索引值设置为0)。 如果不是它们中的任何一个,那么应该如何形成滤波器以与图像的dft相乘。

2 个答案:

答案 0 :(得分:1)

您当前将滤镜填充为与图像大小相同的方式基本上是正确的。我们经常松散地谈论用长度为3的滤波器过滤长度为M的信号,但隐含的假设是我们填充长度为M,或者长度为M + 3-1。

您的方法的一些细节使事情变得复杂:

1)乘以(-1)^(x + y)只是翻译DFT并且不需要。 (参见Foundations of Signal Processing表3.7和#34;频率的循环移位"对于1D情况。在该表示法中,您让k_0为N / 2,因此左列中的W_N项只是在两者之间切换-1和1.)

2)由于Prewitt滤波器仅具有3x3非零支持,因此您的输出仅需要N + 2大小为N + 2。这里要记住的公式是长度(信号)+长度(过滤器) - 1。

以下是我如何做到这一点:

clear
x = im2double(imread('cameraman.tif'));
[M, N] = size(x);

h = [-1 0 1;
    -1 0 1;
    -1 0 1];

P = M + size(h,1) - 1;
Q = N + size(h,2) - 1;

xPadded = x;
xPadded(P, Q) = 0;

hPadded = h;
hPadded(P,Q) = 0;

hShifted = circshift(hPadded, [-1 -1]);

H = fft2(hShifted);
X = fft2(xPadded);

Y = H .* X;
y = ifft2(Y);

yCropped = y(1:M, 1:N);
imshow(yCropped,[]);

答案 1 :(得分:1)

以下是我解决问题的方法。我首先从算法中删除了第2步和第7步。然后通过在水平和垂直方向上交换索引的前半部分和后半部分来使变换居中。我这样做是为了使图像的变换居中。然后,在计算得到的矩阵的逆DFT之后,我解除了这个。我不确定为什么我的上述方法不起作用,但它现在就这样做了。

1)通过填充零将图像的NxN矩阵转换为2 * Nx2 * N矩阵

2)计算图像矩阵的DFT

3)通过交换行和列的前半部分和后半部分使图像变换居中。

4)创建尺寸为2Nx2N的滤波器和坐标为(N,N)

的中心

5)将图像矩阵与滤波器矩阵相乘

6)计算它的逆DFT并提取结果的实部。

7)通过在结果矩阵上重新应用步骤3来分散结果

8)最后提取所得矩阵的左上NxN部分

以上是我在应用过滤时遵循的修改版步骤。 这是我的代码(编辑/新版本)

function res=myFreqConv(signal,mask)
    signal=double(signal);

    l=size(signal,1);

    % padding the image matrix with zeros and making it's size equal to
    % 2Nx2N
    pad_signal=zeros(2*l,2*l);
    pad_signal(1:l,1:l)=signal;
    m=size(mask,1);
    mask_f=zeros(2*l,2*l);

    % Creating a mask of 2Nx2N dims where the prewitt filter values are  
    at 
    % the center of the mask i.e. the indices are like this 
    % [(N-1,N-1), (N-1,N), (N-1,N+1);(N,N-1), (N,N), (N,N+1); (N+1,N-1), 
    (N+1,N), (N+1,N+1)] 
    for i=-1:1
       mask_f(l+i,l-1)=-1;
       mask_f(l+i,l+1)=1;
    end

    % calculate DFT of mask
    mask_f=myDFT(mask_f);

    signal_dft=myDFT(pad_signal);

    % shifting the image transform to center
    indices=cell(1,2);
    indices{1}=[2*l/2+1:2*l 1:2*l/2];
    indices{2}=[2*l/2+1:2*l 1:2*l/2];
    signal_dft=signal_dft(indices{:});

    %multiply mask with image
    res=mask_f.*signal_dft;
    res=real(myIDFT(res));

    % shifting the image transform back to original
    res=res(indices{:});
    res=res(1:l,1:l);
end