Group Abstract Group Abstract

Message Boards Message Boards

Find the curvature of an object from an image

Attachments:
POSTED BY: Ali Hashmi
5 Replies

Some comments:

  • A spectral method to compute derivatives is built-in
  • The Gaussian is built-in as the PDF of the NormalDistribution
  • GaussianMatrix gives a matrix that corresponds to a Gaussian kernel of radius $r$
  • Since the package uses Interpolation, after smoothing, one could use this to compute derivatives and curvature directly
  • The work of Bart ter Haar Romeny’s group is relevant to this topic
POSTED BY: Paul Abbott

Sure. It’s worth noting that the curvature given by that method is the curvature of the shape smoothed by the Gaussian of a given width. It’s sometimes easier to interpret in terms of the smoothed curve instead of the original points.

POSTED BY: Matthew Sottile

Thanks. This is an awesome method. Do you mind if I add your code to my GitHub repository with your name?

POSTED BY: Ali Hashmi

Interesting! An alternative way to do this is using convolution with Gaussian functions to take the derivatives and second derivatives around the curve and use the formula for signed curvature:

k = (xu*yuu - xuu*yu)/((xu^2 + yu^2)^(3/2))

Where xu is the derivative of the x coordinates, xuu is the second derivative of the x coordinates, and yu and yuu are the same for the y coordinates. Computing the derivatives like this is the basis of the Curvature Scale Space image introduced in the mid-1980s, which is a method for characterizing the curvature of a shape at different scales (where the scale corresponds to the width, sigma, of the Gaussian).

We can define the Gaussian and its derivatives as:

gaussian[x_, \[Sigma]_] := 1/(\[Sigma]*Sqrt[2*\[Pi]]) * Exp[-(x^2)/(2*\[Sigma]^2)]
dgaussian[x_, \[Sigma]_] := D[gaussian[y, \[Sigma]], y] /. y -> x
ddgaussian[x_, \[Sigma]_] := D[dgaussian[y, \[Sigma]], y] /. y -> x

These can be used to generate the convolution kernel for a sequence of points pts and a given sigma value:

makeKernel[f_, pts_, \[Sigma]_] := Table[f[x, \[Sigma]], {x, -Length[pts]/2, Length[pts]/2}]

The curvature then can be defined as:

k[pts_, \[Sigma]_] := Module[
   {xu, xuu, yu, yuu},
   xu = ListConvolve[makeKernel[dgaussian, pts, \[Sigma]], pts[[;; , 1]], 1];
   xuu = ListConvolve[makeKernel[ddgaussian, pts, \[Sigma]], pts[[;; , 1]], 1];
   yu = ListConvolve[makeKernel[dgaussian, pts, \[Sigma]], pts[[;; , 2]], 1];
   yuu = ListConvolve[makeKernel[ddgaussian, pts, \[Sigma]], pts[[;; , 2]], 1];
   (xu*yuu - xuu*yu)/(((xu^2) + (yu^2))^(3/2))];

Using your image and the points derived from the boundary of the shape with a sigma value of 20, we get this:

\[Kappa] = k[pts, 20];

col = ColorData["Rainbow"] /@ Rescale[\[Kappa], MinMax[\[Kappa]], {0, 1}];

g = Graphics[{PointSize[0.018], MapThread[Point[#1, VertexColors -> #2] &, {pts, col}]}]

The result doesn't look exactly the same as yours, but is roughly similar.

Image with curvature coloring

An alternative method to this that I've used in the past is to use a spectral method to compute the derivatives. Unfortunately I only have that code in Matlab and haven't ported it to Mathematica.

POSTED BY: Matthew Sottile

enter image description here - Congratulations! This post is now a Staff Pick as distinguished by a badge on your profile! Thank you, keep it coming, and consider contributing your work to the The Notebook Archive!

POSTED BY: EDITORIAL BOARD
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard