%Function to compute a power density spectrum estimate of a single grayscale image %using the Welch method of averaging modified periodograms. %Eric Dubois 2017-12-11 function WelchPDS = WelchPDS_est(A,N) % A is a grayscale image in double format % N x N is the block size. N should be a power of 2. Usually N=64 % WelchPDS is the N x N power density spectrum estimate on a linear scale % It is computed at normalized frequencies ux=-1/2:1/N:1/2-(1/N); vx=ux; % % Remove the mean from the image [I, J]=size(A); prodsize=I*J; mean=sum(sum(A))/prodsize; Az=A-mean; % Compute the 2D separable window (4-term Harris-Nutall Window) n=0:1:N-1; wd=zeros(N,1); a0=0.40217; a1=0.49703; a2=0.09892; a3=0.00183; wd(n+1)=a0-a1*cos(2*pi*n/N)+a2*cos(2*pi*2*n/N)-a3*cos(2*pi*3*n/N); W=wd*wd'; V = sum(sum(W.*W)); % total power of the window % % Compute the spectral estimate using an x and y overlap of N/4 PDS=zeros(N,N); shx=N/4; % x overlap shy=N/4; % y overlap % Number of blocks in x and y direction Mx=floor((I-N)/(N-shx)); My=floor((J-N)/(N-shy)); for i=0:1:Mx for j=0:1:My PDS=PDS+(abs(fft2(W.*Az(i*(N-shx)+1:i*(N-shx)+N,j*(N-shy)+1:j*(N-shy)+N))).^2); end end %Compute the average PDS=PDS/V/((Mx+1)*(My+1)); WelchPDS=[]; %Shuffle the FFT blocks to put the origin at the center WelchPDS=[PDS(N/2+1:N,N/2+1:N) PDS(N/2+1:N,1:N/2);PDS(1:N/2,N/2+1:N) PDS(1:N/2,1:N/2)];