Matlab中{4}图像的带通滤波器

时间:2015-07-31 00:09:55

标签: matlab filtering signal-processing lowpass-filter highpass-filter

我在Matlab中实现了4D图像(4D矩阵)的带通滤波器。前三个维度是空间维度,最后一个维度是时间维度。这是代码:

function bandpass_img = bandpass_filter(img)
% Does bandpass filtering on input image
%
% Input:
%   img: 4D image
%
% Output:
%   bandpass_img: Bandpass filtered image

TR = 1; % Repetition time
n_vols = size(img,3);
X = [];

% Create matrix (voxels x time points)
for z = 1:size(img,3)
    for y = 1:size(img,2)
        for x = 1:size(img,1)
            X = [X; squeeze(img(x,y,z,:))']; %#ok<AGROW>
        end
    end
end

Fs = 1/TR;
nyquist = 0.5*Fs;

% Pass bands
F = [0.01/nyquist, 0.1/nyquist];
type = 'bandpass';

% Filter order
n = floor(n_vols/3.5);

% Ensure filter order is odd for bandpass
if (mod(n,2) ~= 0), n=n+1; end
fltr = fir1(n, F, type);

% Looking at frequency response
% freqz(fltr)

% Store plot to file
% set(gcf, 'Color', 'w');
% export_fig('freq_response', '-png', '-r100');

% Apply to image
X = filter(fltr, 1, X);

% Reconstructing image
i = 1;
bandpass_img = zeros(size(img));
for z = 1:size(img,3)
    for y = 1:size(img,2)
        for x = 1:size(img,1)
            bandpass_img(x,y,z,:) = X(i,:)';
            i = i + 1;
        end
    end
end

end

我不确定实施是否正确。有人可以验证它还是有人发现失败了?

编辑:感谢SleuthEye,我现在可以使用bandpass_img = filter(fltr, 1, img, [], 4);。但仍有一个小问题。我的图片大小为80x35x12x350,即有350个时间点。我已经绘制了应用带通滤波器之前和之后的平均时间序列。

带通滤波之前:

before bandpass

带通滤波后:

after bandpass

为什么在过滤后的图像的最开始处出现此峰值?

编辑2 :现在在开头和结尾都有一个高峰。参见:

enter image description here

我制作了第二个图,我用*标记每个点。参见:

enter image description here

所以第一个和最后两个时间点似乎更低。

似乎我必须在开始时删除2个时间点,最后还要删除2个时间点,所以总共会有4个时间点。

您怎么看?

1 个答案:

答案 0 :(得分:0)

使用1-D filter函数过滤所有元素的串联可能会导致图像失真,因为平滑会使每行的末尾混合到下一个的开头一。除非您试图获取您的4D数据的迷幻再现,否则这不太可能达到您期望的效果。

现在,根据Matlab's filter documentation

  

y = filter(b,a,x,zi,dim)沿维度dim行事。例如,如果x是矩阵,则filter(b,a,x,zi,2)会返回每行的过滤数据。

因此,要随着时间的推移平滑3D图像(您指出的是矩阵img的第四维),您应该使用

bandpass_img = filter(fltr, 1, img, [], 4);

如此使用,信号将从0开始,因为这是滤波器的默认初始状态,滤波器需要一些采样才能提升。如果您知道初始状态的值,则可以使用zi参数(第4个参数)指定该值:

bandpass_img = filter(fltr, 1, img, zi, 4);

否则,典型的顺序N线性FIR滤波器的延迟为N/2个样本。为了摆脱最初的提升,你可以放弃那些N/2初始样本:

bandpass_img = bandpass_img(:,:,:,(N/2+1):end);

同样,如果您想查看与上一个N/2输入值相对应的输出,则必须使用N/2个额外样本填充您的输入(零将执行):

img = padarray(img, [0 0 0 N/2], 0, 'post');