Skip to content
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
Cannot retrieve contributors at this time
%% This function calculates the standard uncertainty from the cross-correlation plane using Moment of Correlation method.
% written by Sayantan Bhattacharya
% Inputs
%P21= cross-correlation plane in fourier domain
%f1= fft of window1/image1
%f2= fft of window2/image2
%Sx= window size Y
%Sy= window size X
%D= Approx Diameter of particle image (e.g. [2.8 2.8]), this is used to
%initialize the autocorrelation diameter estimation using subpixel fit
%cnorm= Matrix of ones of size Sx,Sy this is non unity if you want to
%correct for spatial winfow filtering
% fftindx,fftindy= fftshift indices I guess a simple fftshift can be used
% instead, but just to be consistent with prana functions
%G= Cross correlation plane of two windows
%region1, region2= spatially windowed image
%DXtemp,DYtemp= Cross correlation peak diameter estimated from 3pt subpixel
%fit on cross-correlation plane G
%MIest = If MI is already estimated then use that otherwise calculate MI
%Ixx=PDF diameter in X direction
%Iyy=PDF diameter in X direction
%biasx=bias uncertainty in X direction
%biasy=bias uncertainty in Y direction
%Neff=Effective number of particles
%Autod= Average Autocorrelation diameter
if MIest==-1
% If Mi has not been estimated
P11 = f1.*conj(f1);
P22 = f2.*conj(f2);
Auto1 = ifftn(P11,'symmetric');
Auto2 = ifftn(P22,'symmetric');
Auto1 = Auto1(fftindy,fftindx);
Auto2 = Auto2(fftindy,fftindx);
nAuto1 = Auto1-min(Auto1(:)); % Autocorrelation plane of image 1
nAuto2 = Auto2-min(Auto2(:)); % Autocorrelation plane of image 2
% 3 pt Gaussian fit to Autocorrelation Diameter
%Average Autocorrelation Diameter
Autod=mean([Diap1 Diap2]);
%MI Calculation
INTS1 = max(region1(:));
INTS2 = max(region2(:));
[MI,~,~,~,~,~] = MI_Cal_SCC(G,nAuto1,nAuto2,INTS1,INTS2,Dauto1x3,Dauto1y3,Dauto2x3,Dauto2y3,Sx,Sy,fftindx,fftindy);
% Use estimated MI
%Cross-correlation subpixel fit
% [U,V,~,~,DXtemp,DYtemp,~]=subpixel(G,Sx,Sy,cnorm,1,0,D);
if isnan(DXtemp)
if isnan(DYtemp)
% Estimate the diameter of the cross-correlation peak (with initiation of
% 3pt fit estimates of correlation diameter)
[~,~,~,~,dxc1,dyc1,alpha2]=subpixel(G,Sx,Sy,cnorm,3,0,(1/sqrt(2))*[DXtemp DYtemp]);
% Taking care of peak rotation
DCCx = sqrt( (cos(alpha2)^2*dxc1^2 + sin(alpha2)^2*dyc1^2) );
DCCy = sqrt( (sin(alpha2)^2*dxc1^2 + cos(alpha2)^2*dyc1^2) );
% If estimates are too big than the 3pt fit estimate then default to 3 pt
% fit estimate of the correlation diameter
if DCCx >sqrt(2)*DXtemp
if DCCy >sqrt(2)*DYtemp
%Use Cross-correlation diameter estimate to define convolving Gaussian Diameter
Dconv=(1/sqrt(2))*[DCCx DCCy];
% Finding the Phase correlation
W = ones(Sy,Sx);
Wden = sqrt(P21.*conj(P21));
W(Wden~=0) = Wden(Wden~=0);
R = P21./W; % This is effectively the fourier transform of the PDF
% constructing the gaussian which will be convolved with the pdf
Gfilt=abs(fftn(gfilt,[Sy Sx]));
%Convolving the PDF and the Gaussian
G1 = ifftn(R.*Gfilt,'symmetric');
G1 = G1(fftindy,fftindx);
G1 = abs(G1);
%subpixel estimation using least squres guassfit for the convolved plane G1
%find the PDF major and minor axis
Px=real(((dx1(1)^2 - 2*(Dconv(1))^2)).^0.5);
Py=real(((dy1(1)^2 - 2*(Dconv(2))^2)).^0.5);
%If the pdf diameter comes out to be zero or imaginary try 3point fit for
%the convolved plane G1
if Px==0 || Py==0
% if zero try 3point fit
Px=real(((dx1(1)^2 - 2*(Dconv(1))^2)).^0.5);
Py=real(((dy1(1)^2 - 2*(Dconv(2))^2)).^0.5);
%project major and minor axis to X and Y axes
Ixx = sqrt( 1/16 * (cos(alpha1)^2*Px^2 + sin(alpha1)^2*Py^2) );
Iyy = sqrt( 1/16 * (sin(alpha1)^2*Px^2 + cos(alpha1)^2*Py^2) );
% If not zero then continue
%project to axes
Ixx = sqrt( 1/16 * (cos(alpha1)^2*Px^2 + sin(alpha1)^2*Py^2) );
Iyy = sqrt( 1/16 * (sin(alpha1)^2*Px^2 + cos(alpha1)^2*Py^2) );
% The mean particle diameter is estimated from the mean cross-correlation
% peak diameter divided by sqrt(2)
part_dia=(1/sqrt(2))*mean([DCCx DCCy]);
% Effective number of pixels is MI times a circular blob of pixels with
% mean particle diameter
%Bias: This is the peak location of the convolved gaussian plane, typically
%this is done for multipass converged correlation plane in which case the
%peak should be at zero and any deviation is the bias. However this will
%not work for first pass.
% The gradient correction and scaling is done outside PIVwindowed as the
% gradient estimation requires the full velcoity field
% %Gradient correction using velocity gradient field Udiff and Vdiff
% Ixxt= real(sqrt(Ixx.^2 - (Autod.^2/16).*(Udiff).^2 ));
% Iyyt= real(sqrt(Iyy.^2 - (Autod.^2/16).*(Vdiff).^2 ));
% %MC uncertainty after scaling and bias correction
% MCx=sqrt(biasx^2+(Ixxt^2)/Neff);
% MCy=sqrt(biasy^2+(Iyyt^2)/Neff);
% JJC: this function is an exact duplicate of the external function.
% Is it necessary?
function [MI,Nim1,Nim2,INTS,Diapx,Diapy] = MI_Cal_SCC(G,nAuto1,nAuto2,INTS1,INTS2,Diap1x,Diap1y,Diap2x,Diap2y,Sx,Sy,fftindx,fftindy)
%[MI,INTS,DiaP] = MI_Cal_SCC(G,nAuto1,nAuto2,INTS1,INTS2,Sx,Sy,fftindx,fftindy)
%[MI,INTS,DiaP] = MI_Cal_SCC( region1,region2,Sx,Sy,fftindx,fftindy)
%This function is used to calculate the mutual information between two
%consecutive frames using SCC method
% region 1 and 2 are the particle image within the interrogation window.
% Sx and Sy are the correlation window size
% fftindx and fftindy are fftshift indicies
% We will first find the maximum intensity from the image, and average
% particle diameter from particle image autocorrelation. A standard
% gaussian particle is built based on these two parameter. Then the
% contritbution of one particle is caluclate by take the auotcorrelatio
% peak of stardard gaussian particle. The primary peak on correlation
% plane is a summation of the contribution of all correlated particles.
% MI is the ratio between contribution of all correlated particles and
% one particle.
% Diapx=(1/sqrt(2))*mean([Diap1x Diap2x]);
% Diapy=(1/sqrt(2))*mean([Diap1y Diap2y]);
%make analytical gaussian particle and calculate
%autocorrelaiton of the standard particle
xco = 1:Sx;xco = repmat(xco,[Sx,1]); % build X axis
yco = 1:Sy;yco = repmat(yco',[1,Sy]); % build Y axis
% INTS = (INTS1+INTS2)/2; % intensity of standard Gaussian particle is the mean (maximum) intensity of two frames
INTS = sqrt(INTS1*INTS2); % intensity of standard Gaussian particle is the mean (maximum) intensity of two frames
% % DiaP = (DiaP1+DiaP2)/2; % diameter of standard Gaussian particle is the mean diameter of two frames
% % fg = INTS*exp(-8*((xco-round(Sx/2)).^2+(yco-round(Sy/2)).^2)/DiaP^2); % build the particle intensity distribution based on 2D Gaussian distribution
fg = INTS*exp(-8*((xco-round(Sx/2)).^2/(Diapx^2)+(yco-round(Sy/2)).^2/(Diapy^2))); % build the particle intensity distribution based on 2D Gaussian distribution
fg = fftn(fg,[Sy,Sx]); %FFT
Pg = fg.*conj(fg); %FFT based correlation
Sp = ifftn(Pg,'symmetric'); % convert to time domain
Sp = Sp(fftindy,fftindx); % Sp is the autocorrelation of the standadrd Gaussian particle
%use cross correaltion plane to get MI
Gnorm = G-min(G(:)); %minimum correlation subtraction to elminate background noise effect
[~,Gind] = max(Gnorm(:)); % find the primary peak location
shift_locyg = 1+mod(Gind-1,Sy); % find the Y coordinate of the peak
shift_locxg = ceil(Gind/Sy); % find the X coordinate of the peak
GXshift = Sy/2+1-shift_locxg; % find the distance between the peak location to the center of correlation plane in X direction
GYshift = Sx/2+1-shift_locyg; % find the distance between the peak location to the center of correlation plane in Y direction
SGnorm = circshift(Gnorm,[GYshift,GXshift]); % shift the peak to the center of the plane
MI = max(SGnorm(:))/max(Sp(:)); % MI is the ratio between the contribution of all correlated particle and the contribution of one particle