9 views (last 30 days)

Show older comments

I have a two dimensional multi modal spatial signal generated from a MATLAB code using sinusoidal functions of different wave numbers, amplitudes and phases. What I want to know is that if I have the amplitude vs wave number plot of that signal, how can I extract the wavelength of the different spatial structures. For 1D signal and 1D FFT I know that it is possible to extract the wavelength from the amplitude vs wavenumber plot by simply taking the reciprocals of the wave numbers with non zero amplitudes. But how can it be done for 2D signal and 2D FFT? I am attaching my code below.

Ws=160; % Sampling wavenumber @ 160 Hz

L=10; % Length of domain = 10cm

N = L*Ws; % Length of signal

x = (0:N-1)*(1/Ws); % Space vector

y = [(0:N-1)*(1/Ws)]'; % Space vector

x = repmat(x,1600,1); % Space matrix

y = repmat(y,1,1600); % Space matrix

V = sin((4*pi*x)/L)+sin((4*pi*y)/L); % Function in the spatial domain

fx = linspace((-Ws/2),Ws/2,N); % computing wavenumber vector fx

fy = [linspace((-Ws/2),Ws/2,N)]'; % computing wavenumber vector fy

fx = repmat(fx,1600,1); % computing wavenumber matrix fx

fy = repmat(fy,1,1600); % computing wavenumber matrix fy

T = fft2(V); % 2D FFT

subplot(1,2,1)

pcolor(x,y,V) %%%% Contour plot in spatial domain

ax = gca;

ax.LineWidth = 2;

colormap jet

colorbar

shading interp

pbaspect([1 1 1])

xlabel('X(cm)-->.')

ylabel('Y(cm)-->.')

title('V = sin((4*pi*x)/L)+sin((4*pi*y)/L)')

subplot(1,2,2)

pcolor(fx,fy,abs(fftshift(T))) % Contour plot of FFT amplitude vs wavenumber

lin = zeros(1,N);

hold on

plot(lin,fy(1:1600),'b') % Vertical line passing through (0,0) in fft amplitude plot

hold on

plot(fx(1:1,1:1600),lin,'k') % Horizontal line passing through (0,0) in fft amplitude plot

colormap jet

colorbar

shading interp

pbaspect([1 1 1])

xlabel('Wx(cm^{-1})')

ylabel('Wy(cm^{-1})')

title('FFT amplitude')

I am attaching the plot which I got as well. Any help would be greatly appreciated.

David Goodmanson
on 9 May 2021

Hello SB,

I am speculating that the issue is the offset from the correct frequencies in the fequency domain plot. The culprit is the linspace statements, which define the frequency grid with slightly incorrect spacing.

The code below takes up where your linspace statements are, and defines the frequencies in a similar manner as you did for the spacial array. In fig(2) the frequency peaks are now centered exactly where they should be, i.e. (0, .2), (0, -.2), (-.2, 0) and (.2, 0). In case you don't like the look of the funny hexagonal spots, which are due to some manipulation by pcolor, fig(3) shows individual pixels of abs(fftshift(T)), which are in the correct locations.

The two repmat statements can be replaced by a single meshgrid statement as below. In that case fyy can be defined as a row vector because meshgrid will accept either row or column.

fxx = ((-N/2:N/2-1)/N)*Ws;

fyy = ((-N/2:N/2-1)/N)*Ws;

[fx fy] = meshgrid(fxx,fyy);

% fx = repmat(fxx,1600,1); % computing wavenumber matrix fx

% fy = repmat(fyy,1,1600); % computing wavenumber matrix fy

T = fft2(V); % 2D FFT

figure(2) % (leaving out the extra lines)

pcolor(fx,fy,abs(fftshift(T))) % Contour plot of FFT amplitude vs wavenumber

colormap jet

colorbar

shading interp

pbaspect([1 1 1])

xlabel('Wx(cm^{-1})')

ylabel('Wy(cm^{-1})')

title('FFT amplitude')

xlim([-.4 .4])

ylim([-.4 .4])

figure(3)

imagesc(fxx,fyy,abs(fftshift(T)))

colormap spring

colorbar

xlim([-.4 .4])

ylim([-.4 .4])

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!