Finding MATLAB Peaks

I have a vector that contains gray levels of pixels in one line of an image. vec=IM(:,65);

I have shown the parts of the array that I want to detect. These pieces will be the pickles of my objects.

How can I determine these object pixels?

Plot vec: enter image description here Vector here: vec

+3


source to share


2 answers


This can be easily solved using the findpeaks

signal processing toolbar. Specifically for your data, I had to call it like this:

[pks, locs] = findpeaks(max(vec)-vec, 'minpeakdistance', 160, 'minpeakheight', 22);

      

findpeaks

detects only positive peaks (local highs). Thus, we need to make sure that all local lows become local highs. I did this by taking the maximum value of the vector and subtracting with the vector. Since there are so many local peaks, the field minpeakdistance

allows you to find peaks that are at least separated between these peaks. I set it to 160. Also, the minimum peak height detects peaks greater than a certain number, which I set to 22. pks

finds the actual peaks, and locs

gives you the locations of the peaks in your signal. We need to uselocs

to find the actual peak data, because we did this on a specular reflected version of your signal. So, to get the actual peak data, do the following:

pks_final = vecs(loc);

      

As a demonstration, let's plot this signal as well as the peaks located at findpeaks

:



plot(1:numel(vec), vec, locs, vec(locs), 'r.');

      

The raw data is shown in blue and the detected peaks are shown in red. This is what I get:

enter image description here


Good luck!

+4


source


There are different ways to find local peaks, here I use the deviation from the local mean, then dividing the areas and looking at each area for a minimum.

clear
close all

load a

std_a=std( a(a~=0) );

SMOOTH_SIZE=131;% depend on data size
THRESHOLD=0.7*std_a;

smooth_a = conv(a,ones(SMOOTH_SIZE,1)/SMOOTH_SIZE,'same'); %ma filter

deviation_a=a-smooth_a; 
negdev_a=deviation_a.*(deviation_a<-THRESHOLD); %deviation in negative region (minimum)

negdev_a_left=[negdev_a(2:end) 0]; % helper to find starting index point
negdev_a_right=[0 negdev_a(1:end-1)]; % helper to find end index point

negdev_a(1)=0; negdev_a(end)=0; % make sure that we have zero point
indfrom=find(negdev_a==0 & negdev_a_left~=0); %start index per region
indto=find(negdev_a==0 & negdev_a_right~=0); %start index per region

if(length(indfrom)~=length(indto)), error('error in regions');end

peak_indexes=zeros(1,length(indfrom)); %number of regions
peak_counter = 0;

for i=1:length(indfrom)
  [center_min, min_idx]=min( a( indfrom(i):indto(i) ) );
  real_min_idx=indfrom(i)-1+min_idx; % convert back to original array index
  if( real_min_idx==indfrom(i) || real_min_idx==indto(i) ), continue; end
  left_max=max(a( indfrom(i):real_min_idx-1)); %helper to check for real minimum
  right_max=max(a( real_min_idx+1:indto(i)));  %helper to check for real minimum

  if(center_min<left_max && center_min<right_max) % check if this is real minimum
       peak_counter=peak_counter+1;
       peak_indexes(peak_counter)=real_min_idx;
  end
     % if you need subpixel accuracy you can do some weighted average in the min region
end
peak_indexes=peak_indexes(1:peak_counter); %narrow to found indexes

figure; plot(a); hold on; plot(smooth_a, 'k'); hold off;
figure; plot(deviation_a);hold on;  plot(negdev_a,'r.');hold off;
figure; plot(a);hold on; plot(peak_indexes, a(peak_indexes),'rO');hold off; %result

      



Result Hope this help mendy

+3


source







All Articles