如何通过opencv计算提取轮廓的曲率? [英] How can I calculate the curvature of an extracted contour by opencv?

查看:1334
本文介绍了如何通过opencv计算提取轮廓的曲率?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我确实使用了findcontours()方法从图像中提取轮廓,但是我不知道如何从一组轮廓点计算曲率.有人可以帮我吗?非常感谢你!

解决方案

对我来说,曲率是:

其中,t是轮廓内的位置,x(t)分别是轮廓内的位置. y(t)返回相关的x响应. y值.请参见此处.

因此,根据我对曲率的定义,可以通过以下方式实现它:

std::vector< float > 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;
}

它也适用于非封闭点列表.对于闭合轮廓,您可能希望更改边界行为(对于第一次迭代).

更新:

衍生产品说明:

连续一维函数f(t)的导数为:

但是我们处于离散空间中,有两个离散函数f_x(t)f_y(t),其中t的最小步长为1.

二阶导数是一阶导数的导数:

使用一阶导数的近似值,得出:

对于导数还有其他近似值,如果用Google搜索,会发现很多.

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:

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< float > 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:

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.

The second derivative is the derivative of the first derivative:

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

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

这篇关于如何通过opencv计算提取轮廓的曲率?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆