Fitting smooth closed spline to scattered 2D points

50 views (last 30 days)
Hi everyone,
I have a set of points scattered in a 2D plane. The points are scattered in a somwhat circular/elipptical way, but I would like to fit some arbitrarily (but smoothed) shaped spline. The points are distributed like:
To enable closing of a spline, the last and first data points are the same.
As said I would like to fit a closed smoothed spline to this curve. I've tried the cscvn-option giving me the below, but I would like something a bit more smoothened out (cscvn forces the spline to go exactly through each and every point):
Reading up in the help, csaps seem to enable smoothing (to be fair, I'm not really sure how), but if trying this on my data I get a smoothed non-closed curve like below:
The last option I've looked at is creating a new parameter to which I fit both my (x,y)-data (as suggested in an earlier thread: http://www.mathworks.com/matlabcentral/newsreader/view_thread/33868 ), but this actually gives me an even more jagged curve:
However I might be applying the parametrization in an incorrect way...
So, to my question. Does anyone have a good way of creating a closed smoothed spline to my data? Any suggestion or help would be very much appreciated. (P.S: I'm trying to create an automatized code, so I'm preferably looking for executable code than GUI in the curve fitting toolbox (but I understand that they are somewhat connected...)).
Thanks for the help!
/David

Accepted Answer

Image Analyst
Image Analyst on 21 Jun 2015
If you don't want or require the curve to go through every point exactly, you can use a Savitzky-Golay filter on the parameterized data.
% Now smooth with a Savitzky-Golay sliding polynomial filter
windowWidth = 35
polynomialOrder = 2
smoothX = sgolayfilt(x, polynomialOrder, windowWidth);
smoothY = sgolayfilt(y, polynomialOrder, windowWidth);
  8 Comments
Image Analyst
Image Analyst on 21 Jun 2015
David you can use activecontour() - do you know what active contours (also know as snakes or balloons or alpha shapes, or at least related to them) are? Attached is an example of active contour. You can use poly2mask() to turn your points into a solid mask, then use activecontour to create a smooth boundary. This uses an energy minimization method that perhaps you'll feel more comfortable with than polynomial regression (which is basically what sgolayfilt() is).
David
David on 22 Jun 2015
Hi again, thanks for coming with new suggestions.
No I'm not that familiar with active contours. I did some tries but seem not to find the right way of getting a smoother boundary. According to the help of activecontour(), an example command would be:
bw = activecontour(I, mask, 200, 'edge','SmoothFactor',1.5);
but when I try to perform the same (see code below) I get an error prompt:
if true
BW = poly2mask(xy(1,:),xy(2,:),120,120);
mask = zeros(size(BW));
mask(10:end-10,10:end-10) = 1;
bw = activecontour(BW,mask,'SmoothFactor',1.5);
Error message:
Error using activecontour>parse_inputs (line 287)
Too many input arguments were passed to activecontour.
So it seems like 'SmoothFactor' cannot be passed to the activecontour. Has this been changed in a new Matlab version (I'm running R2014a)? Or am I running the commands incorrectly?
Lastly: if I manage to get a smoothed contour map (i.e. binary image), can I then retrieve the edge points (i.e. going back to some spline/polygon shape) again?
Again, thanks for all the help.

Sign in to comment.

More Answers (1)

Praful Agrawal
Praful Agrawal on 29 Sep 2018
the original task can be achieved by converting the piecewise polynomial fit to bspline fit using fn2fm function:
X - set of points
pp = cscvn(X); bsp = fn2fm(pp, 'B-');

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!