对我来说曲率是:
其中t是轮廓内的位置,x(t)和. y(t)返回相关的x resp. y值.见here.
所以,根据我对曲率的定义,可以这样实现:
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;
}
它也适用于非闭合点列表.对于闭合轮廓,您可能希望更改边界行为(对于第一次迭代).
更新:
衍生物的解释:
连续1维函数f(t)的导数是:
但是我们处于离散空间并且具有两个离散函数f_x(t)和f_y(t),其中t的最小步长是1.
二阶导数是一阶导数的导数:
使用一阶导数的近似值,得出:
衍生品还有其他近似值,如果你谷歌它,你会发现很多.