Fitting a Curve to an Uncurling Object

2 views (last 30 days)
Hello all, I am currently conducting video analysis on an uncurling object and would like to fit a curve to the object along its path as it straightens to later calculate curvature along the object's length over time. I am currently using Matlab's cscvn and smooth functions from the Curve Fitting Toolbox to try to achieve my goal, however I've found that for certain frames my code seems to work like I want it to (i.e fitting a curve to the object along its path), while for other frames the fitted curve does not match the path of the image. I've attached some examples comparing the processed image and the fitted curves (the blue circles represents the coordinates of the white pixels in the image, while the orange line represents the fitted curve).
Below is the accompanying code I created to make these curves, and I've also attached a link to the full code. One potential reason I've found for the poor fit has to do with the indexing of the white pixels which are later fed into the smooth and cscvn functions, however I don't know how I would address this. Am I approaching this problem the correct way, or should I be using different functions to try to create these curves? I feel like I'm starting to approach a wall with this, but at the same time it feels like I'm very close to achieving my goal with this problem.
%Reading image with some extra cropping%
%I = sprintf('%i.jpeg',i);
I = sprintf('3500.jpeg');
img = imread(I);
img = imbinarize(img);
img(764:end,668:end) = 0;
img = img(:,232:end);
%imshow(img)
%figure
%Indexing every white pixel from the image%
[row,col] = size(img);
xcoor = [];
ycoor = [];
for j = 1:col
for k = 1:row
if img(k,j) == 1
xcoor = [xcoor, j];
ycoor = [ycoor, -1*k];
end
end
end
%Smoothing Data and Curve Fitting%
[xcoor, ii] = sort(xcoor);
ycoor = ycoor(ii);
yout = smooth(xcoor,ycoor,.1,'rloess');
curve = cscvn([xcoor;yout']);
subplot(2,1,1)
scatter(xcoor,ycoor)
hold on
fnplt(curve);
  2 Comments
Abhay Iyer
Abhay Iyer on 29 Jul 2020
As a clarification, I'd like to fit these curves iteratively as my code iterates through a series of frames from a video of the object uncurling.
Abhay Iyer
Abhay Iyer on 29 Jul 2020
Here are downloads to the above binary images if needed.

Sign in to comment.

Accepted Answer

Abhay Iyer
Abhay Iyer on 12 Aug 2020
Edited: Abhay Iyer on 12 Aug 2020
%Reading image%
I = sprintf('%i.jpg',i);
img = imread(I);
img = imbinarize(img);
%Get Endpoints%
bwskel = bwmorph(img,'skel');
bwend = bwmorph(bwskel,'endpoints');
B = bwboundaries(bwend);
b = numel(B);
ep = [];
for i = 1:b
a = B{i,1};
point = [a(1,2);a(1,1)];
ep = [ep, point]; %Get endpoints from bwend%
end
last = ep(:,1);
start = ep(:,2);
%Index Points Along the Curve%
r = start(2);
c = start(1);
contour = bwtraceboundary(img,[r c],'N',8); %Obtain coordinates of white pixels%
[ii,jj] = unique(contour,'rows'); %Obtain indices of unique coord. to remove repeats%
new = contour(sort(jj),:); %Removes repeats%
x = new(:,2);
y = new(:,1);
windowWidth = 169;
polynomialOrder = 2;
smoothX = sgolayfilt(x, polynomialOrder, windowWidth); %Smooth points using Savitzky-Golay filter for curve fitting%
smoothY = sgolayfilt(y, polynomialOrder, windowWidth); %Smooth points using Savitzky-Golay filter for curve fitting%
curve = [smoothX,smoothY];
The above code achieves my goal. Previously I used a double for loop to index the white pixels from my binary images, however this presented the problem of having the points being in a seemingly random sequence rather than following the path of the curve, leading to inconsistent curve fitting. Instead, I utilized MATLAB's bwboundaries, bwmorph, and bwtraceboundary functions to index the white pixels along the path of the curve, mainly referring to this previous answer. After I successfully indexed my pixels, I applied a Savitzky-Golay filter to smooth my points to create a smooth curve, which I'll later fit an equation to for curvature calculations using something like cscvn or John D'Errico's interparc function from the File Exchange.

More Answers (1)

John D'Errico
John D'Errico on 29 Jul 2020
Edited: John D'Errico on 29 Jul 2020
The curve fitting toolbox assumes the functions are SINGLE VALUED. There can only be ONE value of y for any x. If that is not true, for example, if you have replicates, then this is presumed to be noise. Therefore, you cannot directly use the curve fitting toolbox to model a function that is not single valued. Relationships (I won't call them functions, unless you are willing to call them implicit functions) that have an infinite slope are also not viable for the curve fitting toolbox. A curve that wraps over as you show is such an implicit function.
  6 Comments
Wesley
Wesley on 23 Nov 2020
Hello, have you solved this problem? I also encountered a similar problem and would like to discuss it with you.

Sign in to comment.

Products


Release

R2020a

Community Treasure Hunt

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

Start Hunting!