【问题标题】:Color image boundary based on local curvature基于局部曲率的彩色图像边界
【发布时间】:2018-08-18 07:43:47
【问题描述】:

我正在寻找执行此操作的算法(使用 OpenCV C 或 C++):

给定边界图像,我想找到所有点的局部曲率并对其进行颜色映射,这就是上面显示的图像中所做的。我从Wikipedia 获得了这张图片,但一直无法找到以这种方式为边界着色的方法。请让我知道如何做到这一点。

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

如何做到这一点?

编辑

只是为了让您了解两天以来我是如何尝试这样做的:

我使用了 openCV 函数 convexHullconvexityDefects,但意识到我走错了方向。我只需要处理二值图像的轮廓/边界。

【问题讨论】:

  • 如果有人选择关闭这个问题,请告诉我原因。我已经花了 2 天时间,但仍然无法弄清楚如何在边界中找到局部曲率。
  • 要检测边界,您可以使用一些“*卷积矩阵”。曲率可以通过通过三个点找到圆周的半径来计算。网上有很多信息。
  • 是的,我也可以使用openCV函数findContours来检测边界。在那之后?在此之后我无法继续。如何找到计算曲率半径的三个点?我是这个概念的新手。

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


【解决方案1】:

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

[详细]

边界由 x、y 像素中心的点列表组成,每个点 1px 或根 2 px 形成列表中的下一个。您需要使用 Schnider 在 Graphics Gems 中的技术(Gems 1,pp 612,An algorithm for Fitting digitized curve)来拟合平滑三次 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));

    }

【讨论】:

  • 您能详细说明一下吗?
【解决方案2】:

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

要通过三点得到圆周的半径,网络上有很多信息。因为只需要半径,不需要中心,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
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-19
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 2020-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多