This is an interesting problem!
It took me a while to figure out the correct approach, however it is deceptively simple, and uses only core MATLAB functions (although it requires R2017b or later for the ischange function). The essence of it is to use the 'linear' option of ischange to get the slopes of the various line segments, then use hiscounts to find the most numerous slopes, corresponding to the linear baseline of your Raman signal data. After that, it¹s just a polyfit call to calculate the slope of the line to be detrended. It requires a bit of interaction at the outset to do the initial thresholding, with the rest taking care of itself. The Code —
D = csvread('raman-1 week.csv');
x = D(:,1);
y = D(:,2);
x = x(y >= 1E+4);
y = y(y >= 1E+4);
[Cp,Sl,Ic] = ischange(y,'linear');
[Cts,Edg,Bin] = histcounts(Sl, 50);
[Max,Binmax] = max(Cts);
LinearRegion = (Bin==Binmax);
B = polyfit(x(LinearRegion), y(LinearRegion), 1)
L = polyval(B, x);
yc = y - L;
figure
plot(x, yc)
grid
The Plot —
That’s likely as close as it’s possible to get. I encourage you to experiment with it to fine-tune it to your requirements.
For comparison, the original signal is:
Best Answer