function [peaks,criterion] = pickpeaks(V,select,display) % ------------------------------------------------------------- % Scale-space peak picking % ------------------------ % This function looks for peaks in the data using scale-space theory. % % input : % * V : data, a vector % * select : either: % - select >1 : the number of peaks to detect % - 0 1 w=max(eps,sin(2*pi*(0:(horizon-1))/2/(horizon-1))); w=w/sum(w); %V=conv(V(:),w(:),'same'); V = real(ifft(fft(V(:),n+horizon).*fft(w(:),n+horizon))); V = V(1+floor(horizon/2):end-ceil(horizon/2)); end %find local maxima tempMat(2:end,1) = V(1:end-1); tempMat(:,2) = V(:); tempMat(1:end-1,3) = V(2:end); [~,posMax] =max(tempMat,[],2); I = find(posMax==2); I = I(:)'; %initialize buffer newBuffer = zeros(size(buffer)); if is == 1 % if first iteration, keep all local maxima newBuffer(I) = Vorig(I); else old = find(buffer); old = old(:)'; %Now, for each element of I, find the closest element in %old along with its distance. The few nice lines below were %written by Roger Stafford in a forum post available here: %http://www.mathworks.fr/matlabcentral/newsreader/view_thread/243878 nI = size(I,2); nOld = size(old,2); [~,p] = sort([I,old]); q = 1:nI+nOld; q(p) = q; t = cumsum(p>nI); r = 1:nOld; r(t(q(nI+1:nI+nOld))) = r; s = t(q(1:nI)); id = r(max(s,1)); iu = r(min(s+1,nOld)); [d,it] = min([abs(I-old(id));abs(old(iu)-I)]); iOld = id+(it-1).*(iu-id); %done, now select only those that are sufficiently close neighbours = iOld(dselect); else sorted = find(criterion>1E-3); [~,order] = sort(criterion(sorted),'descend'); peaks = sorted(order(1:min(length(sorted),select))); end if display %display clf plot(Vorig,'LineWidth',2); hold on plot(criterion*max(Vorig),'r'); hold on plot(peaks,Vorig(peaks),'ro','MarkerSize',10,'LineWidth',2) grid on title('Scale-space peak detection','FontSize',16); legend('data','computed criterion','selected peaks'); end end