Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding curvature from a noisy set of data points using 2d/3dsplines? (C++)

I am trying to extract the curvature of a pulse along its profile (see the picture below). The pulse is calculated on a grid of length and height: 150 x 100 cells by using Finite Differences, implemented in C++.

Pulse profile with varying curvature

I extracted all the points with the same value (contour/ level set) and marked them as the red continuous line in the picture below. The other colors are negligible.

red line = dataset of points with the same value

Then I tried to find the curvature from this already noisy (due to grid discretization) contour line by the following means:

(moving average already applied)

1) Curvature via Tangents
Curvature Approximation from two Points P and N

The curvature of the line at point P is defined by:

tangents of 2 points = curvature at one point

So the curvature is the limes of angle delta over the arclength between P and N. Since my points have a certain distance between them, I could not approximate the limes enough, so that the curvature was not calculated correctly. I tested it with a circle, which naturally has a constant curvature. But I could not reproduce this (only 1 significant digit was correct).

2) Second derivative of the line parametrized by arclength

I calculated the first derivative of the line with respect to arclength, smoothed with a moving average and then took the derivative again (2nd derivative). But here I also got only 1 significant digit correct. Unfortunately taking a derivative multiplies the already inherent noise to larger levels.

3) Approximating the line locally with a circle

Since the reciprocal of the circle radius is the curvature I used the following approach:

Approximating the curvature with a circle

This worked best so far (2 correct significant digits), but I need to refine even further. So my new idea is the following:

Instead of using the values at the discrete points to determine the curvature, I want to approximate the pulse profile with a 3 dimensional spline surface. Then I extract the level set of a certain value from it to gain a smooth line of points, which I can find a nice curvature from.

So far I could not find a C++ library which can generate such a Bezier spline surface. Could you maybe point me to any?

Also do you think this approach is worth giving a shot, or will I lose too much accuracy in my curvature?

Do you know of any other approach?

With very kind regards, Jan

edit: It seems I can not post pictures as a new user, so I removed all of them from my question, even though I find them important to explain my issue. Is there any way I can still show them?

edit2: ok, done :)

like image 557
JannaJ Avatar asked Nov 04 '12 11:11

JannaJ


1 Answers

There is ALGLIB that supports various flavours of interpolation:

  • Polynomial interpolation
  • Rational interpolation
  • Spline interpolation
  • Least squares fitting (linear/nonlinear)
  • Bilinear and bicubic spline interpolation
  • Fast RBF interpolation/fitting

I don't know whether it meets all of your requirements. I personally have not worked with this library yet, but I believe cubic spline interpolation could be what you are looking for (two times differentiable).

In order to prevent an overfitting to your noisy input points you should apply some sort of smoothing mechanism, e.g. you could try if things like Moving Window Average/Gaussian/FIR filters are applicable. Also have a look at (Cubic) Smoothing Splines.

like image 107
moooeeeep Avatar answered Oct 13 '22 16:10

moooeeeep