[英]Bandpass Filter for 4D image in Matlab
I have implemented in Matlab a bandpass filter for a 4D image (4D matrix). 我已经在Matlab中实现了用于4D图像(4D矩阵)的带通滤波器。 The first three dimensions are spatial dimensions, the last dimension is a temporal one.
前三个维度是空间维度,最后一个维度是时间维度。 Here is the code:
这是代码:
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
I'm not sure if the implementation is correct. 我不确定实施是否正确。 Could somebody verify it or does somebody find a failure?
有人可以验证它还是有人发现失败?
Edit: Thanks to SleuthEye it now kind of works when I'm using bandpass_img = filter(fltr, 1, img, [], 4);
编辑:感谢SleuthEye,当我使用
bandpass_img = filter(fltr, 1, img, [], 4);
时,它现在可以工作了bandpass_img = filter(fltr, 1, img, [], 4);
. 。 But there is still a minor problem.
但是仍然存在一个小问题。 My images are of size 80x35x12x350, ie there are 350 time points.
我的图像尺寸为80x35x12x350,即有350个时间点。 I have plotted the average time series before and after applying the bandpass filter.
我已经绘制了应用带通滤波器前后的平均时间序列。
Before bandpass filtering: 带通滤波之前:
After bandpass filtering: 带通滤波后:
Why is this peak at the very beginning of the filtered image? 为什么这个峰值出现在过滤图像的最开始?
Edit 2 : There is now a peak at the beginning and at the end. 编辑2 :现在在起点和终点都有一个峰值。 See:
看到:
I have made a second plot where I marked each point with a *. 我做了第二个图,在每个图上用*标记。 See:
看到:
So the first and last two time points seem to be lower. 因此,第一个和最后两个时间点似乎更低。
It seems that I have to remove 2 time points at the beginning and also 2 time points at the end, so in total I will loose 4 time points. 看来我必须在开始时删除2个时间点,并在结尾时删除2个时间点,因此总共我将删除4个时间点。
What do you think? 你怎么看?
Filtering a concatenation of all the elements using the 1-D filter
function as you are doing is likely going to result in a distorted image as the smoothing makes the end of each row blend into the beginning of the next one. 在执行操作时,使用一维
filter
功能过滤所有元素的串联可能会导致图像失真,因为平滑处理会使每一行的末尾融合到下一行的开始。 Unless you are trying to obtain a psychedelic rendition of your 4D data, this is unlikely to do what you are expecting it to. 除非您尝试获取4D数据的迷幻再现,否则这不可能实现您期望的效果。
Now, according to Matlab's filter documentation : 现在,根据Matlab的过滤器文档 :
y = filter(b,a,x,zi,dim)
acts along dimensiondim
.y = filter(b,a,x,zi,dim)
沿维度dim
起作用。 For example, ifx
is a matrix, thenfilter(b,a,x,zi,2)
returns the filtered data for each row.例如,如果
x
是矩阵,则filter(b,a,x,zi,2)
返回每一行的过滤数据。
So, to smooth out the 3D images over time (which you indicated is the fourth dimension of you matrix img
), you should use 因此,要使3D图像随时间平滑(您指出的是矩阵
img
的第四维),应使用
bandpass_img = filter(fltr, 1, img, [], 4);
Used as such, the signal would starts a 0 because that's the default initial state of the filter and the filter takes a few samples to ramp up. 照此使用,信号将开始为0,因为这是滤波器的默认初始状态,并且滤波器需要几个采样来进行加速。 If you know the value of the initial state you can specify that with the
zi
argument (the 4th argument): 如果知道初始状态的值,则可以使用
zi
参数(第4个参数)指定该值:
bandpass_img = filter(fltr, 1, img, zi, 4);
Otherwise, a typical order N
linear FIR filter has a delay of N/2
samples. 否则,典型的
N
阶线性FIR滤波器的延迟为N/2
样本。 To get rid of the initial ramp up you can thus just discard those N/2
initial samples: 为了摆脱初始加速,您可以仅丢弃这些
N/2
初始样本:
bandpass_img = bandpass_img(:,:,:,(N/2+1):end);
Similarly, if you want to see the output corresponding to the last N/2
input values, you'd have to pad your input with N/2
extra samples (zeros will do): 同样,如果要查看与最后
N/2
输入值相对应的输出,则必须用N/2
额外的采样填充输入(零将起作用):
img = padarray(img, [0 0 0 N/2], 0, 'post');
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.