Spatial filtering of cylindrical data
2 次查看(过去 30 天)
显示 更早的评论
I have a set of dimensional measurements of a tire that are stored in a 2D array. Each column consists of 4096 measurements that are evenly spaced around the tire. The columns are also evenly spaced across the tire's surface, so the values in the array are the r coordinates, the rows are theta, and the columns are Z.
Assuming the radius of the tire is 1 foot, the circumference would be ~6.28 feet and the circumferential measurements would be 0.018 inch apart. The columns are about 1 mm apart (0.0394 inch), so the x and Y spatial resolutions are different.
I would like to high-pass and low-pass filter the data, but I am struggling to define an appropriate filter. I would probably filter the rows over a length of 6 inches (325 rows), but
1) how do I define such a filter in dimensional terms?
To remove any edge effects of the filtering, I can extend the row data by about 30% on both ends by adding data from the opposite ends of the array (which I will remove again after filtering).
Initially, I would like to only filter the data in the row direction, without a phase-shift, so filtfilt would seem appropriate to me.
2) Is that the right tool to use?
It would also be nice to be able to filter the entire surface (e.g., filter2), but I'm again not sure how to define such a 2D filter given the different spatial resolutions.
3) suggestions?
I do not have data available to pad the columns, so:
4) how do I deal with the edge effects of the filter on the rows?
I do have the signal processing toolbox and the image processing toolbox installed.
2 个评论
Matt J
2025-5-12
the rows are theta, and the columns are Z.
Does that mean each row corresponds to a fixed theta, or does theta vary across each fixed row?
采纳的回答
William Rose
2025-5-12
I think filtfilt() is a reasonable idea if you do what you said, which is add a wrap-around from the other part of the tire, at the beginning and end of the circle.
First we simulate some data.
R=304.8; % tire radius (mm)
W=325; % tire width (mm)
N=4096; % number of angles
M=325; % number of z-values
theta=(0:N-1)*2*pi/N; % angle (vector, radians)
c=R*theta; % circumerential position (vector, mm)
z=linspace(-W/2,W/2,M); % axial position (vector, mm)
[C,Z]=meshgrid(z,theta); % size(C)=size(Z)=(4096,325)
Xz=1-(2*z/W).^2; % tread height=parabolic function of z
% Xz=0 (fully worn) on the edges, =1 (not worn at all) in the middle.
Xt=1.5+cos(3*theta)+0.5*sin(360*theta); % tread height as a function of theta
% Tread height has a large variation that repeats every 120 degrees around
% the tire, and a smaller variation that repeats every 1 degree around.
X=Xt'*Xz; % total tread height = product of circumferential and axial
figure
subplot(311), plot(z,Xz,'-r')
xlabel('Axial Position (mm)'); ylabel('Height Factor')
grid on; title("Tread Height vs Axial Pos.")
subplot(312), plot(c,Xt,'-r')
xlabel('Circumferential Position (mm)'); ylabel('Height Factor')
grid on; title("Tread Height vs Circum.")
subplot(313), surf(z,c,X,'EdgeColor','None');
xlabel('Axial'); ylabel('Circum (mm)'); zlabel('Tread')
colorbar; view(90,90); title('X=Tread Height')
(There appears to be aliasing, probably related to plot resolution, in the surface plot above, which causes some unexpected color changes in the horizontal direction. This aliasing does not happen when I run the script in regular Matab on my nortebook computer, rather than the Matlab Answers window.)
Make an augmented data array = [last half circumference; full tire circumference; first half circumference].
Xaug=[X(N/2+1:end,:);X;X(1:N/2,:)]; % size(Xaug)=8192x325
Filter the data going circumferentially around the tire with a zero-phase low-pass filter with a cutoff frequency corresponding to 150 mm (6").
dc =2*pi*R/N; % circumferential sampling interval (mm)
fs=1/dc; % sampling rate (1/mm)
fco=1/150; % cutoff frequency (1/mm)
[b,a]=butter(2,fco/(fs/2)); % 2nd order lowpass Butterworth
Yaug=zeros(size(Xaug)); % allocate array
for j=1:M
Yaug(:,j)=filtfilt(b,a,Xaug(:,j));
end
Y=Yaug(N/2+1:3*N/2,:); % extract central part of filtered signal
Plot the filtered signal. Use "axis equal" to display with true aspect ratio.
figure
subplot(211)
surf(z,c,Y,'EdgeColor','None');
xlabel('Axial (mm)'); ylabel('Circumference (mm)');
title('Y=Circumferential Lowpass Filter');
axis equal; colorbar; view(90,90)
The lowpass filtered signal, Y, doesn't look much different than the plot of the original signal, X. (Aliasing makes them look diferent here, but the surface plots look quite simlar when I run it in regular Matab.) We can see the effect of lowpass filtering more clearly if we plot X versus circumference, on the axial centerline, for one third of the tire, before and after filtering.
subplot(212);
plot(c(1:1360),X(1:1360,(M+1)/2),'-r',c(1:1360),Y(1:1360,(M+1)/2),'-b')
legend('Raw','Filtered'); grid on;
xlabel('Circumferential Position (mm)'); ylabel('Tread Height')
title('Tread Height along Axial Centerline for 1/3 Circumference')
5 个评论
William Rose
2025-5-14
@Jim McIntyre, you're welcome. It looks to me like you're doing great with this.
更多回答(1 个)
Matt J
2025-5-12
编辑:Matt J
2025-5-12
Using padarray you can pad circularly in theta and symmetrically in z and then filter with 'valid' shape flags. If you are filtering separably, you can also do fft-based convolution along the columns (in lieu of padding), which will be equivalent to a circulant filter in theta.
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Spectral Estimation 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!