# Create line of best fit from a plot

2 views (last 30 days)
Sean on 10 Dec 2014
Commented: Image Analyst on 11 Dec 2014
Attached is a plot which comes from an image, the plot represents pixels across various columns(1024) in an image which are less than the pixel value 200 (graycale). Can anyone help me or show me how to create a line of best fit with this data? Ive been trying the polyfit function but can't quite get it working.

Star Strider on 11 Dec 2014
What do you want to fit? A general trend or the most significant of the oscillations?
The polyfit function will do best for a general trend.
For the oscillations, I would start with a fft of it to find one or more of the most significant frequencies. Then use one of the nonlinear curve fitting functions with an objective function:
fs = @(b,x) b(1) + b(2).*sin(b(3).*x + b(4)) + b(5).*sin(b(6).*x + b(7));
I would not use more terms or parameters. Two terms is probably the most you can hope to fit successfully, and that may be optimistic.
##### 2 CommentsShowHide 1 older comment
Star Strider on 11 Dec 2014
My pleasure!
That’s different from the first plot, which looked at least quasi-periodic. The latest looks essentially random to me. It would be extremely difficult to fit a polynomial to it without getting significant end-effects that are characteristic of high-degree polynomial fits, and could significantly compromise the fit itself. That would be true even if you scaled and shifted it.
I would use a low-order (~5) polynomial fit, and simply live with the approximation error.

Image Analyst on 11 Dec 2014
See attached demo of polyfit.
If you tell us WHY you want this fit, we might be able to offer good advice. Like for example, is it for background correction (flat field correction)?
##### 2 CommentsShowHide 1 older comment
Image Analyst on 11 Dec 2014
What I would do is to first extract the largest blob using my attached function. Then you can try smoothing the border with imclose() (Image Processing Toolbox) . Or, if you have the Signal Processing Toolbox , you can extract the top line and bottom line then use a moving polynomial filter called the Savitzky-Golay filter (demo attached), done by sgolayfilt().
[rows, columns] = size(binaryImage);
for col = 1 : columns
thisColumn = binaryImage(:, col);
topLine(col) = find(thisColumn, 1, 'first');
bottomLine(col) = find(thisColumn, 1, 'last');
end
smoothedTop = sgolayfilt(topLine, 15, 2);
smoothedBottom = sgolayfilt(bottomLine, 15, 2);