How to cut out specific segment from findpeaks function?
Mostrar comentarios más antiguos
Hi All,
I am trying to figure out how to cut out the specific segment of the signal where I draw the border using findpeaks function.
I am using example of findpeaks link below:
x = linspace(0,1,1000);
Pos = [1 2 3 5 7 8]/10;
Hgt = [4 4 2 2 2 3];
Wdt = [3 8 4 3 4 6]/100;
for n = 1:length(Pos)
Gauss(n,:) = Hgt(n)*exp(-((x - Pos(n))/Wdt(n)).^2);
end
PeakSig = sum(Gauss);
plot(x,Gauss,'--',x,PeakSig)
grid

Then, using findpeaks function,
findpeaks(PeakSig,x,'Annotate','extents','WidthReference','halfheight')
title('Signal Peak Widths')

I want to cut the segment of the border into 3 segment.

The method I am thinking is find the X value corresponding the Y value, which is not an effective way to do it.
Respuesta aceptada
Más respuestas (3)
Well, I kind of needed exactly this feature so I ventured and fought with the findpeaks code, luckily I found what I needed. I attached the modified version of the findpeaks function (now called Findpeaks.m).
Note: It seems that because MATLAB recognized that this is a custom function, the plotting features are not working, but that's no issue, because you can simply use the orginial function and that'll do, this mod is just to extract the x position for the borders.
I'm going to include here a small example using the previous presented case.
x = linspace(0,1,1000);
Pos = [1 2 3 5 7 8]/10;
Hgt = [4 4 2 2 2 3];
Wdt = [3 8 4 3 4 6]/100;
for n = 1:length(Pos)
Gauss(n,:) = Hgt(n)*exp(-((x - Pos(n))/Wdt(n)).^2);
end
PeakSig = sum(Gauss);
findpeaks(PeakSig,x,'Annotate','extents','WidthReference','halfheight');
Now, let's use the modified version of the findpeaks function to get the borders x values. Please note the use of the pair parameters 'BorderExtraction' and logical 1. Basically, logical 1 to get the x values for borders in the loc output variable position and logical 0 to tell it to behave exactly the same as the original findpeaks function.
[~,X] = Findpeaks(PeakSig,x,'Annotate','extents','WidthReference','halfheight','BorderExtraction',1)
And now let's use this to get the second peak just for fun.
plot(PeakSig(x>=X(2) & x<=X(3)))
Hope this helps
A94 out.
2 comentarios
Image Analyst
el 18 de En. de 2022
Helps me anyway. I never knew findpeaks() had those nice annotation lines available for display.
Giacomo Echevers
el 18 de En. de 2022
Glad to hear that! Just noticed those borders, literally yesterday and got quite triggered that it didn't have a native way to extract those x coordinates.
João
el 7 de Feb. de 2019
Try this,
[pks,locs] = findpeaks(PeakSig,x,'Annotate','extents','WidthReference','halfheight')
The variable locs have the indexes of the peaks found. Use them like this to remove a specific peak (your case the third):
PeakSig(locs(3)) = [];
3 comentarios
Matlaber
el 8 de Feb. de 2019
João
el 8 de Feb. de 2019
I didn't notice your were using x in findpeaks. You need to find the index that corresponds to locs. Do it like this then:
[pks,locs] = findpeaks(PeakSig,x,'Annotate','extents','WidthReference','halfheight')
peakToFind = 1; % the peak you want to delete (in this case the first one)
% where you get the postion in x corresponding to locs
idx_x = find(x==locs(peakToFind));
PeakSig(idx_x) = [];
Matlaber
el 9 de Feb. de 2019
Image Analyst
el 9 de Feb. de 2019
The borders appear to be available in findpeaks() at line 558 (in R2018b version):
% get the x-coordinates of the half-height width borders of each peak
[wxPk,iLBh,iRBh] = getPeakWidth(yFinite,x,iPk,bPk,iLB,iRB,refW);
See it with edit, then search for border
>> edit findpeaks.m
Make a copy of findpeaks.m and call it findpeaksandborders() in some utilities folder on your path with all your other m-files. BE SURE NOT TO ALTER THE ORIGINAL ONE!!!
Then have findpeaksandborders() return the borders (iLB and iRB) in the list of output arguments.
7 comentarios
Matlaber
el 9 de Feb. de 2019
Image Analyst
el 9 de Feb. de 2019
Well the quick way is to just declare it global and send it out. Down at line 558:
% get the x-coordinates of the half-height width borders of each peak
global iLB;
global iRB;
[wxPk,iLBh,iRBh] = getPeakWidth(yFinite,x,iPk,bPk,iLB,iRB,refW);
Then at line 1 of findpeaksandborders.m:
function [Ypk,Xpk,Wpk,Ppk, iLB, iRB] = findpeaksandborders(Yin,varargin)
global iLB;
global iRB;
Then when youi call findpeaksandborders() just make sure you accept all 6 returned variables.
Matlaber
el 11 de Feb. de 2019
Image Analyst
el 11 de Feb. de 2019
You're not allowed to change anything under Program Files. That's a Windows rule.
You'll have to save a copy of the m-file where you have the rest of your m-files, and edit it there.
Matlaber
el 11 de Feb. de 2019
Image Analyst
el 14 de Feb. de 2019
Looks like you got it working since you've accepted an answer.
Categorías
Más información sobre Measurements and Feature Extraction en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!








