Spatial Frequency (FFT) estimation from image intensity profiles
조회 수: 7 (최근 30일)
이전 댓글 표시
Hi,
I would like to estimate spatial frequency based on FFT from the attached image intensity data. The findpeaks() does the job though, but for some other reason I still need to find the frequency from FFT.

댓글 수: 0
채택된 답변
Mathieu NOE
2025년 4월 22일
hello and welcome back
let's try it with fft (have a doubt you will get a more accurate result though)
the results are in accordance with the other post (we obtained spatial period around 38 pixels so spatial freq = 1/38 = 0.026... (unit = 1/pixel)
here we get :
spatial_period_pixels = 36.5714
spatial_freq = 0.0273 +/- 0.0039
(frequency resolution is given by : df = Fs/nfft = 1/256 = 0.0039 pixel^-1
load('matlab.mat')
figure,
plot(s1)
% fft
% first some high pass filtering
[b,a] = butter(1,0.1,'high');
s1 = filtfilt(b,a,s1);
Fs = 1;
N = 256;
[X,freq]=positiveFFT(detrend(s1),N,Fs);
figure,
semilogy(freq,X)
% xlim([1e-2 1])
ylim([1e-4 1])
hold on
[PKS,LOCS] = findpeaks(X,'MinPeakHeight',max(X)/5);
plot(freq(LOCS),PKS,'dr')
hold off
spatial_freq = freq(LOCS(1)) % first dominant (non DC) peak, unit = 1/pixel
spatial_period_pixels = 1/spatial_freq % unit = pixel
%%% yet another fft function %%%%%%%%%%%%
function [X,freq]=positiveFFT(x,N,Fs)
%N=length(x); %get the number of points
k=0:N-1; %create a vector from 0 to N-1
T=N/Fs; %get the frequency interval
freq=k/T; %create the frequency range
X=abs(fft(x))*2/N; % make up for the lack of 1/N in Matlab FFT
%only want the first half of the FFT, since it is redundant
cutOff = ceil(N/2);
%take only the first half of the spectrum
X = X(1:cutOff);
freq = freq(1:cutOff);
end
댓글 수: 7
Mathieu NOE
2025년 4월 23일
ok so I tried this method , selecting the 3 dominant peaks obtained via fft and doing the gaussian fit
the frequency obtained is : fpeak_fit = 0.0379 (pixels^-1)
which would correspond to a period of : 1/fpeak_fit = 26.4056 pixels
load('matlab.mat')
figure,
plot(s1)
%% fft
% first some high pass filtering
[b,a] = butter(1,0.1,'high');
s1 = filtfilt(b,a,s1);
Fs = 1;
N = 256;
[X,freq]=positiveFFT(detrend(s1),N,Fs);
figure,
semilogy(freq,X)
ylim([1e-4 1])
hold on
[PKS,LOCS] = findpeaks(X,'SortStr','descend','NPeaks',3);
fpeaks = freq(LOCS);
plot(fpeaks,PKS,'dr')
%% gaussian fit of the 3 dominant peaks
f = linspace(0.7*min(fpeaks),1.2*max(fpeaks),1000);
pf = my_gauss_fit(fpeaks,PKS,f);
semilogy(f,pf,'g')
[newpeak,ind] = max(pf);
fpeak_fit = f(ind)
plot(fpeak_fit,newpeak,'*r');
hold off
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function yfit = my_gauss_fit(x,y,xfit)
% Define g(x) = a*exp(-(x-mu)^2/(2*sigma^2)):
g = @(A,X) A(1)*exp(-(X-A(2)).^2/(2*A(3)^2));
%% ---Fit Data: Analitical Strategy---
% Cut Gaussian bell data
ymax = max(y); xnew=[]; ynew=[];
ind = y > 0.05*ymax;
xnew = x(ind);
ynew = y(ind);
% Fitting
ylog=log(ynew); xlog=xnew; B=polyfit(xlog,ylog,2);
% Compute Parameters
sigma=sqrt(-1/(2*B(1))); mu=B(2)*sigma^2; a=exp(B(3)+mu^2/(2*sigma^2));
% Plot fitting curve
A=[a,mu,sigma];
yfit = g(A,xfit);
end
%%% yet another fft function %%%%%%%%%%%%
function [X,freq]=positiveFFT(x,N,Fs)
%N=length(x); %get the number of points
k=0:N-1; %create a vector from 0 to N-1
T=N/Fs; %get the frequency interval
freq=k/T; %create the frequency range
X=abs(fft(x))*2/N; % make up for the lack of 1/N in Matlab FFT
%only want the first half of the FFT, since it is redundant
cutOff = ceil(N/2);
%take only the first half of the spectrum
X = X(1:cutOff);
freq = freq(1:cutOff);
end
추가 답변 (0개)
참고 항목
카테고리
Help Center 및 File Exchange에서 Fourier Analysis and Filtering에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!




