Transfer from http://www.billauer.co.il/peakdet.html
peakdet:peak detection using MATLAB
Peakdet : using MATLAB The peak detection
Here's a problem I encounter in several fields:find the local maxima and minima in some noisy signal, which typically loo KS like the following graph:
in several field , I encountered a problem : found in some noise signal Local maximum and minimum values , It usually looks like the following figure :
The local maxima and minima is plotted as red and green stars on the graph. To the eye it's so obvious where they is, but making a computer find them can turn out tricky.
the maximum and minimum values of the interval are plotted as red and green stars on the graph. It is obvious where they are with the eyes , but they are programmed to find that they are Tricky .
Let's start with a what does not: Using the well-known zero-derivate method. Due to the noise, which are always there in real-life signals, accidental zero-crossings of the first derivate occur, yield ing false detections. The typical solution is to smooth the curve with some low-pass filter, usually killing the original signal at the same Tim E. The result is usually, the algorithm goes horribly wrong where it's so obvious to the eye.
In many cases, we don ' t really care about maxima and minima in the mathematical sense. We can see the peaks and valleys, and we want the computer to find them. This is the "Peakdet" does.
The trick are to realize, which a peak is the highest point betweem "valleys". What makes a peak was the fact that there was lower points around it. This strategy was adopted by ' Peakdet ': Look for the highest point, around which there was points lower by X on both sides.
Let's see a example:first, let's create the graph shown in the figure above:
>>t=0:0.001:10;>>x=0.3*sin (t) + sin (1.3*t) + 0.9*sin (4.2*t) + 0.02*RANDN (1, 10001);>>figure; Plot (x);
T=0:0.001:10; X=0.3*sin (t) + sin (1.3*t) + 0.9*sin (4.2*t) + 0.02*RANDN (1, 10001); Figure Plot (x); Now we'll find the peaks and valleys: (You'll need to copy the "Peakdet" function from the bottom of this page and put it In your working directory or a directory in the MATLAB search path):
>> [Maxtab, Mintab] = Peakdet (x, 0.5);>> hold on; Plot (Mintab (:, 1), Mintab (:, 2), ' g* ');>> plot (Maxtab (:, 1), Maxtab (:, 2), ' r* ');
[Maxtab, Mintab] = Peakdet (x, 0.5); Hold on; Plot (Mintab (:, 1), Mintab (:, 2), ' g* '); Plot (Maxtab (:, 1), Maxtab (:, 2), ' r* ');
Note the call to Peakdet (): The first argument are the vector to examine, and the second are the peak threshold:we require A difference of at least 0.5 between a peak and its surrounding in order to declare it as a peak. Same goes with valleys.
The returned vectors "Maxtab" and "Mintab" contain the peak and valley points, as evident by their plots (note the colors) .
The vector ' s x-axis values can be passed as a third argument (thanks to Sven Billiet for he contribution on this), in WHI CH Case Peakdet () returns these values instead of indices, as shown in the following example:
>> figure; Plot (t,x);>> [Maxtab, Mintab] = Peakdet (x, 0.5, T);
Figure Plot (t,x); [Maxtab, Mintab] = Peakdet (x, 0.5, T);
And from this we continue like before, but note that the X axis represents "T" and not indices.
>> hold on; Plot (Mintab (:, 1), Mintab (:, 2), ' g* ');>> plot (Maxtab (:, 1), Maxtab (:, 2), ' r* ');
Hold on; Plot (Mintab (:, 1), Mintab (:, 2), ' g* ');p lot (Maxtab (:, 1), Maxtab (:, 2), ' r* ');
As for the implementation of the "function:the work" is do with a for-loop, which are considered lousy practice in MATLAB . Since i ' ve never needed this function for anything else than pretty short vectors (< 100000 points), I also never bothe Red to try speeding it up. Compiling to MEX is a direct solution. I ' m not sure if it's possible to vectorize the algorithm in MATLAB. I ' ll be glad to hear suggestions.
A final note:if you happen to prefer Python, you could try this (someone have been kind enough to convert this function). There is also aversion in C by the Hong Xu and aversion in FORTRAN, by Brian McNoldy. I Haven ' t verified any of these.
And here is the function. Copy and save it as ' peakdet.m '. It ' s released to the public domain:
function [Maxtab, Mintab]=peakdet (V, Delta, x)%peakdet Detect peaks in a vector% [Maxtab, Mintab] = Peakdet (V, delt A) finds the local% maxima and minima ("peaks") in the vector v.% Maxtab and mintab consists of both columns. Column 1% contains indices in V, and column 2 The found values.% percent with [maxtab, mintab] = Peakdet (V, DELTA, X) the indices% in Maxtab and Mintab is replaced with the corresponding% x-values.%% A Point is considered a maximum peak if it have the maximal% value, and was preceded (to the left) by a value lower by% delta.% Eli Billauer, 3.4.05 (explicitly not copyrighted). Percent This function was released to the public domain; Allowed.maxtab = [];mintab = [];v = V (:);% Just in case this wasn ' t a proper vectorif Nargin < 3 x = (1:le Ngth (v)) '; else x = x (:); If Length (v) ~= Length (x) error (' Input vectors v and x must has same length '); EndEnd if (Length (delta (:))) >1 error (' INPUT argument delta must be a scalar '), endif Delta <= 0 error (' Input argument DELTA must be positive '); endmn = INF; mx =-inf;mnpos = NaN; Mxpos = Nan;lookformax = 1;for I=1:length (v) this = V (i); If this > mx, mx = this; Mxpos = x (i); End If this < MN, MN = this; Mnpos = x (i); End If Lookformax if this < Mx-delta maxtab = [Maxtab; mxpos MX]; MN = this; Mnpos = x (i); Lookformax = 0; End else If this > Mn+delta mintab = [Mintab; Mnpos MN]; MX = this; Mxpos = x (i); Lookformax = 1; End EndEnd
Peakdet:peak detection using MATLAB peak identification