kookoo121 - 3 months ago 73
C++ Question

How can I calculate the curvature of an extracted contour by opencv?

I did use the

findcontours()
method to extract contour from the image, but I have no idea how to calculate the curvature from a set of contour points. Can somebody help me? Thank you very much!

For me curvature is:

$|K|&space;=&space;\sqrt{&space;\frac{&space;\left(\frac{d^2y(t)}{dt^2}\frac{dx(t))}{dt}-\frac{d^2x(t)}{dt^2}\frac{dy(t)}{dt}&space;\right&space;)^2&space;}{&space;\left(&space;\frac{d^2x(t)}{dt^2}+\frac{d^2y(t)}{dt^2}&space;\right&space;)^{3}&space;}&space;}$

where t is the position inside the contour and x(t) resp. y(t) return the related x resp. y value. See here.

So, according to my definition of curvature, one can implement it this way:

std::vector< cv::Point2f > vecCurvature( vecContourPoints.size() );

cv::Point2f posOld, posOlder;
cv::Point2f f1stDerivative; f2ndDerivative;
for (size_t i = 0; i < vecContourPoints.size(); i++ )
{
const cv::Point2f& pos = vecContourPoints[i];

if ( i == 0 ){ posOld = posOlder = pos; }

f1stDerivative.x =   pos.x -        posOld.x;
f1stDerivative.y =   pos.y -        posOld.y;
f2ndDerivative.x = - pos.x + 2.0f * posOld.x - posOlder.x;
f2ndDerivative.y = - pos.y + 2.0f * posOld.y - posOlder.y;

float curvature2D = 0.0f;
if ( std::abs(f2ndDerivative.x) > 10e-4 && std::abs(f2ndDerivative.y) > 10e-4 )
{
curvature2D = sqrt( std::abs(
pow( f2ndDerivative.y*f1stDerivative.x - f2ndDerivative.x*f1stDerivative.y, 2.0f ) /
pow( f2ndDerivative.x + f2ndDerivative.y, 3.0 ) ) );
}

vecCurvature[i] = curvature2D;

posOlder = posOld;
posOld = pos;
}


It works on non-closed pointlists as well. For closed contours, you may would like to change the boundary behavior (for the first iterations).

UPDATE:

Explanation for the derivatives:

A derivative for a continuous 1 dimensional function f(t) is:

$f'(t)=\lim\limits_{n&space;\rightarrow&space;0}{\frac{f(t+n)-f(t))}{t+n-x}}&space;=&space;\lim\limits_{n&space;\rightarrow&space;0}{\frac{f(t+n)-f(t))}{n}}$

But we are in a discrete space and have two discrete functions f_x(t) and f_y(t) where the smallest step for t is one.

$f_x'(t)=\lim\limits_{n&space;\rightarrow&space;0}{\frac{f_x(t+n)-f_x(t))}{t+n-x}}&space;=&space;\lim\limits_{n&space;\rightarrow&space;0}{\frac{f_x(t+n)-f_x(t))}{n}}&space;\approx&space;\frac{f_x(t+1)-f_x(t))}{1}$

The second derivative is the derivative of the first derivative:

$f_x''(t)=\lim\limits_{n&space;\rightarrow&space;0}{\frac{f_x'(t+n)-f_x'(t))}{t+n-x}}&space;=&space;\lim\limits_{n&space;\rightarrow&space;0}{\frac{f_x'(t+n)-f_x'(t))}{n}}&space;\approx&space;\frac{f_x'(t+1)-f_x'(t))}{1}$

Using the approximation of the first derivative, it yields to:

$f_x''(t)=(f_x(t+2)-f_x(t+1))&space;-&space;(f_x(t+1)-f_x(t))&space;=&space;f_x(t+2)&space;-&space;2f_x(t+1)&space;+&space;f_x(t)$

There are other approximations for the derivatives, if you google it, you will find a lot.