基于局部曲率的彩色图像边界

时间:2018-03-09 17:09:15

标签: c++ algorithm opencv image-processing opencv3.0

我正在寻找一种算法(使用OpenCV C或C ++)来做到这一点:

enter image description here

给定边界图像,我想在所有点找到局部曲率并对其进行颜色映射,这是在上面显示的图像中完成的。我从Wikipedia得到了这张图片,但是却无法通过这种方式找到一种为边界着色的方法。请告诉我如何做到这一点。

如果观察边界,则红色表示边界具有高斜率,黄色表示边界几乎是线性的。

如何做到这一点?

修改

只是为了让你了解我两天后如何尝试这样做:

我使用了openCV函数convexHullconvexityDefects,但意识到我的方向是错误的。我只能在二进制图像的轮廓/边界上工作。

2 个答案:

答案 0 :(得分:0)

您可以通过将三次贝塞尔曲线的路径拟合到边界,然后分析地获取曲率来解决问题。

[阐述]

边界由像素中心的x,y中的点列表组成,每个点1px或根2 px构成列表中的下一个点。您需要使用Schnider在Graphics Gems(Gems 1,pp 612,一种算法来拟合数字曲线)中使用平滑的三次Bezier路径。

沿着曲线的步骤采取始终为子像素的微小步骤,和 使用

取曲率
double BezierCurve::Curvature(double t) const
    {
        // Nice mathematically perfect formula
        //Vector2 d1 = Tangent(t);
        //Vector2 d2 = Deriv2(t);
        //return (d1.x * d2.y - d1.y * d2.x) / pow(d1.x * d1.x + d1.y * d1.y, 1.5);

        // Get the cubic coefficients like this, I store them in the Bezier
        // class
        /*
        a = p3 + 3.0 * p1 - 3.0 * p2 - p0;
        b = 3.0 * p0 - 6.0 * p1 + 3.0 * p2;
        c = 3.0 * p1 - 3.0 * p0;
        d = p0;
        */


        double dx, dy, ddx, ddy;

        dx = 3 * this->ax * t*t + 2 * this->bx * t + this->cx;
        ddx = 6 * this->ax * t + 2 * this->bx;
        dy = 3 * this->ay * t*t + 2 * this->by * t + this->cy;
        ddy = 6 * this->ay * t + 2 * this->by;

        if (dx == 0 && dy == 0)
            return 0;

        return (dx*ddy - ddx*dy) / ((dx*dx + dy*dy)*sqrt(dx*dx + dy*dy));

    }

答案 1 :(得分:0)

与mode = CV_RETR_EXTERNAL和method = CV_CHAIN_APPROX_NONE一起使用的OpenCV findContours将为您提供所有有序的边界像素,例如两个后续点是邻居。

要获得圆周半径三个点,Web中有很多信息。因为您只需要半径而不是中心,this stackexchange answer很快。

在伪代码中:

vector_of_points = OpenCV::findContours(...)
p1 = vector start
p2, p3 are next points in vector

//boundary is circular, so in the first loop pass we must adjust
p2 = next point
p3 = last point

//Use p1 as our iterator
while ( p1 <= vector.end )
{
    //curvature    
    radius = calculateRadius(p1, p2, p3)
    //set color for pixel p2
    setColor(p, radius)

    increment p1, p2, p3
    adjust for start point = end point
}