image thumbnail

mpiv

by

 

20 Sep 2002 (Updated )

PIV method in MATLAB

func_findpeak2( f, i_opt );
function [ ip_x, ip_y, SNR, MMR, PPR ] = func_findpeak2( f, i_opt );
%========================================================================
%
% version 0.55
%
%
% 	func_findpeak2.m
%
%
% Description:
%
%	To find the location of the peak of a 2D array
%	  - with optional Gaussian subpixel fit
%
% Variables:
%
%	Input;
%	f		2d array (double precision)
%	i_opt		= 1: normal algorism
%			= 2: subpixel fit
%
%	Output;
%	ip_x, ip_y	location of peak
%	SNR		signal to noise ratio 
%			(ratio of peak value to mean value of f)
%	MMR		max to mean ratio 
%	PPR		1st peak to 2nd peak ratio 
%
%
%=======================================================================
%
% Terms:
%
%       Distributed under the terms of the terms of the BSD License
%
% Copyright:
%
%       Nobuhito Mori
%           Disaster Prevention Research Institue
%           Kyoto University, JAPAN
%           mori@oceanwave.jp
%
%========================================================================
%
% Update:
%	0.56	2009/07/01 BSD License applied
%	0.55	2006/12/08 Fixed minor bug for iopt=1
%	0.50	2006/09/12 NM Depress waring errors of Log(0) 
%	0.40	2003/07/01 Definition of MMR has been inserted.
%	0.30	2003/07/01 Definition of SNR has been modified
%	0.20	2003/06/11 Definition of SNR has been modified
%	0.10	2002/12/04 first version
%
%========================================================================

% i_plot = 1     -> plot during piv process with pause for check
%        = other -> void
i_plot = 9;

%
% --- initialization
%

nx = size(f,1);
ny = size(f,2);
n  = nx*ny;

n0 = size(f(~isnan(f)),1);

%
% --- remove abnormal conditions
%

if ( n0 == 0 ) | ( n==0 ) | ( max(max(f))==0 )
  ip_x = NaN;
  ip_y = NaN;
  SNR  = NaN;
  MMR  = NaN;
  PPR  = NaN;
  return
end

%
% --- peak search 1: normal
%

ip_x = -1;
ip_y = -1;

f_max = f(1,1);
for iy=1:ny
  g = f(:,iy);
  [g_max ig] = max( g );
  if g_max >= f_max 
    f_max = g_max; 
    ip_x  = ig;
  end
end

f_max = f(1,1);
for ix=1:nx
  g = f(ix,:);
  [g_max ig] = max( g );
  if g_max >= f_max 
    f_max = g_max; 
    ip_y  = ig;
  end
end

% for second peak search
h     = f(ip_x,ip_y);
ip_x0 = ip_x;
ip_y0 = ip_y;

%
% --- peak search 2: subpixel seach using Gaussian
%

if abs(i_opt) == 2

  if ( ip_x == -1 ) | ( ip_y == -1 )
     ip_x = NaN;
     ip_y = NaN;
     return
  end

  % calculate x-subpixel peak
  g = f(:,ip_y);
  [h ih] = max( g );
  g = g/h;
  if ih == 1
    ix_subpeak = 1;
  elseif ih == nx
    ix_subpeak = nx;
  else
    % v0.50
    if g(ih+1)~=0 & g(ih)~=0 & g(ih-1)~=0
      ix_subpeak = ih - 0.5*( log(g(ih+1)) - log(g(ih-1)) ) / ...
                  ( log(g(ih+1)) -2*log(g(ih)) + log(g(ih-1)) );
    else
      ix_subpeak = NaN;
    end
  end

  % calculate y-subpixel peak
  g = f(ip_x,:);
  [h ih] = max( g );
  g = g/h;
  if ih == 1
    iy_subpeak = 1;
  elseif ih == ny
    iy_subpeak = ny;
  else
    % v0.50
    if g(ih+1)~=0 & g(ih)~=0 & g(ih-1)~=0
      iy_subpeak = ih - 0.5*( log(g(ih+1)) - log(g(ih-1)) ) / ...
                    ( log(g(ih+1)) -2*log(g(ih)) + log(g(ih-1)) );
    else
      iy_subpeak = NaN;
    end
  end

  ip_x0 = ip_x;
  ip_y0 = ip_y;
  ip_x  = ix_subpeak;
  ip_y  = iy_subpeak;

end

%
% --- find second peak
%

% maximum value of 1st peak
C1=h;
g =f;
% Search for 2nd peak (outside dia_peak from the 1st peak)
dia_peak = round(sqrt(3*nx)/2.5);
%dia_peak = 5;

lx1 = ip_x0 - dia_peak;
lx2 = ip_x0 + dia_peak;
ly1 = ip_y0 - dia_peak;
ly2 = ip_y0 + dia_peak;
if lx1 < 1
  lx1 = 1;
elseif lx2 > nx
  lx2 = nx;
end
if ly1 < 1
  ly1 = 1;
elseif ly2 > ny
  ly2 = ny;
end
g(lx1:lx2,ly1:ly2) = 0;
C2 = max(max(g));

%ip2_x = -1;
%ip2_y = -1;
%g_max = g(1,1);
%for iy=1:ny
%  [h_max ih] = max( g(:,iy) );
%  if h_max >= g_max 
%    g_max = h_max; 
%    ip2_x  = ih;
%  end
%end
%g_max = g(1,1);
%for ix=1:nx
%  [h_max ih] = max( g(ix,:) );
%  if h_max >= g_max 
%    g_max = h_max; 
%    ip2_y  = ih;
%  end
%end

%
% --- post process
%

% Signal-to-Noise Ratio
if i_opt > 1
  g = f;
else
  g = f(find(f));
end
if max(size(g)) > 2
  f_max   = max(max(g));
  f_std   =    std2(g);
  f_mean  =   mean2(g);
  f_amean = mean2(abs(g));
else
  f_max   = NaN;
  f_std   = NaN;
  f_mean  = NaN;
  f_amean = NaN;
end

MMR = f_max/f_amean;
SNR = (f_max-f_mean)/f_std;

% Peak-to-Peak Ratio
if C2~=0
  PPR = C1/C2;
else
  PPR = Inf;
end

%
% --- check plot
%

if i_plot == 1

  contour( f', 25 );
%  surf( double(f)', 25 );
  hold on
    plot( ip_x, ip_y, 'bo', ...
	         'MarkerSize', 8, ...
	         'MarkerFaceColor', 'b', ...
	         'MarkerEdgeColor', 'k' );
    if abs(i_opt) == 2
    plot( ip_x0, ip_y0, 'ro', ...
	         'MarkerSize', 8, ...
	         'MarkerFaceColor', 'r', ...
	         'MarkerEdgeColor', 'k' );
%    plot( ip2_x, ip2_y, 'go', ...
%	         'MarkerSize', 8, ...
%	         'MarkerFaceColor', 'g', ...
%	         'MarkerEdgeColor', 'k' );
    end
  hold off
  pause
end

Contact us