【问题标题】:How to judge the contour is line or curve by opencv?opencv如何判断轮廓是直线还是曲线?
【发布时间】:2017-04-01 19:27:14
【问题描述】:

伙计们。该图像有两个轮廓。我可以使用 opencv findcontour 函数找到两者。我想知道的是如何判断哪个轮廓是直线,哪个轮廓是曲线?谁能告诉我该怎么做?任何建议将被认真考虑。提前致谢。

【问题讨论】:

  • 在等高线的第一个点和最后一个点之间定义一条线,并测量所有其他点到该线的平均距离。如果等高线是一条线,则平均距离接近于 0。
  • 你可以做的是使用轮廓的第一个和最后一个点拟合一条线,并检查其他点是否落在它上面。您无需检查所有点来确定这一点,您只需选择每个“第 n 个”点即可。
  • 为什么复杂?从两点定义线很简单。计算点到给定线的距离也很简单。您只需将距离相加并除以点数。
  • 如果没有填充形状(即它们是曲线),您可以使用moments 找到轮廓的质心,然后使用pointPolygonTest 对质心进行点在轮廓测试.对于这条线,测试会说它在轮廓内。当然,仅此一点对于复杂的轮廓是不可靠的。

标签: image algorithm opencv image-processing image-segmentation


【解决方案1】:

首先假设您有一条线,然后应用一些基本代数。

首先找到直线的斜率和 y 截距。直线的斜率定义为 y 的变化除以 x 的变化。所以给定两个点 (x0,y0), (x1,y1):

slope = (y0-y1) / (x0-x1)

使用斜率截距方程(y=mx+b) 求出 y 截距并求解 b:

y = mx + b
b = y - mx

所以

y_intercept = y0 - slope * x0

一旦你有了斜率和 y 轴截距,你只需要遍历你的轮廓的点,看看所有的点是否都落在同一条线上。如果他们这样做,你有一条线;如果他们不这样做,你就有了曲线。

由于我不知道你使用的是什么语言,这里是伪代码的整个过程:

// First assume you have a line - find the slope and y-intercept
slope = (point[0].y - point[1].y) / (point[0].x - point[1].x);
y_intercept = point[0].y - (slope * point[0].x);

// Using slope-intercept (y = mx + b), see if the other points are on the same line
for (n = 0 to numPoints)
{
    if ((slope * point[n].x + y_intercept) != point[n].y)
    {
        // You've found a point that's not on the line - as soon as you
        // find a point that's not on the line, you know that the contour
        // is not a straight line
    }
}

请注意,您将在此处处理浮点数,因此您必须在 if 条件中考虑到这一点 - 您无法直接比较浮点数是否相等,因此您将需要将它们四舍五入到某种可接受的准确度。为了使伪代码简单,我把它省略了。

【讨论】:

  • 几点:使用前两个点来定义线可能会产生很大的噪音,因为它们非常接近。使用第一点和最后一点应该会更好。使用一维斜率和截距不适用于垂直线。所以最好用二维向量(起点和方向)定义直线,然后计算点到直线的实际距离。
【解决方案2】:

迟到的答案,但记录在案:

将第一个点和最后一个点之间的距离与轮廓长度进行比较。 如果它们很接近,则轮廓为线状,否则为曲线。

【讨论】:

    猜你喜欢
    • 2012-12-28
    • 1970-01-01
    • 2015-11-15
    • 2021-11-12
    • 2018-01-11
    • 2020-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多