如何检测图像上某些点的坐标

时间:2018-03-21 20:17:27

标签: c++ image-processing computer-vision

enter image description here

我使用ORB算法来检测并获取图像中显示的绳索交叉点的坐标,该坐标由红点表示。我想检测由蓝点代表的交叉点周围的四个点的坐标。所有四个点与红点的距离相同。 任何想法如何通过使用红点坐标获得他们的坐标。 提前谢谢

1 个答案:

答案 0 :(得分:1)

虽然您正在使用ORB,但您仍然需要一种算法来从背景中分割绳索,或者至少需要一些技术来识别属于绳索的图像块并且与之相等红点。有许多选择可供探索。

考虑照明和照明是非常重要的。如果这是一个真实世界的应用,那么成像就是要解决的独立问题。对于课程而言,这看起来有点像问题,而不是您销售和支持的应用程序,但您仍应考虑照明:

  • 当光照水平降低时,您的算法是否仍然有效?
  • 相对于绳索所在表面的相机姿势变化会如何影响检测?
  • 如果您正在检测"黑色"绳子,算法也会被要求检测不同颜色的绳索吗?脏绳子?绳子在不同的背景上?

由于你感兴趣的对象是绳索,你必须考虑一类适用于检测非刚性物体的算法。始终首先考虑最简单的解决方案!

已连接的组件 连接组件标签是一种传统的图像处理算法,仍然适合作为许多应用的起点。最后我知道,这是在OpenCV中实现的findContours()。这也可以被称为" blob finding"或其中的一些变体。

https://en.wikipedia.org/wiki/Connected-component_labeling

https://docs.opencv.org/2.4/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=findcontours

根据光线的不同,在运行连接的组件之前,您可能需要采取不同的步骤来对图像进行二值化。首先,将彩色图像转换为灰度,这将显着简化任务。

  1. 尝试手动阈值,因为您可以快速测试多个值以查看效果。如果二进制化不是很正确,就不要气馁 - 这通常可以通过预处理来解决。
  2. 如果一系列手动阈值有效(例如8位灰度范围内的52-76),那么使用一种自动为您计算阈值的算法:Otsu,基于熵的方法等,都将提供相似的表现。无论哪种技术效果最好,都可以进一步调整代码/算法以优化您的绳索应用。
  3. 如果阈值处理和二值化不起作用 - 对于你的绳索应用似乎不太可能,至少你如何呈现它 - 然后转而思考基于梯度(基于边缘,基于能源的技术。
  4. 但假设您可以将绳索与背景分开,您仍然需要一种方法从红点[绳索内]开始并将相等的距离移动到蓝点。在讨论了其他绳索分割方法后,更多关于此事。

    注意:连接组件标签可以在不仅仅是将黑色和黑色二值化的情况下工作。白色图像。如果您可以创建纹理字段或图像的某些其他2D表示,以便将黑色绳索与相对较亮的背景区分开,则可以使用连接组件算法。 (找到一个更复杂的"或者#34;更现代的"算法并不一定是正确的方法。)

    在二值化图像中,blob可以嵌套:在白色背景上,你可以有几个黑色斑点,其中一个或多个是白色斑点,里面是黑色斑点等。早期版本的OpenCV处理这个相当不错。 (OpenCV是一个不错的起点,也是许多人的接触点,但由于种种原因,它并不总是与其他开源和商业软件包相媲美;尽管普及,但OpenCV存在一些问题。)

    一旦你有一个" blob" (2D数字图像中的4个连接像素区域),您可以将blob视为对象,此时您有多个选项:

    • 边缘跟踪:围绕blob的内边缘和外边缘进行跟踪。根据我的记忆,OpenCV确实(或者至少应该)有一些相对简单的方法来获得优势。
    • 将blob拆分为组件blob,每个blob都可以单独处理
    • 将blob转换为多边形
    • ...

    如果你有一个非刚性对象,连接组件算法应该在要检查的技术列表中占据很高的位置。

    布尔操作 一旦将绳索作为连接组件(甚至可能没有这个),您可以使用布尔图像操作来查找图像中蓝点的点:

    1. 在数据中创建圆形区域,甚至在图像中创建
    2. 找到圆圈(环形)和代表绳索的黑色区域的交点。使用原始图像,您应该有四个区域。
    3. 找到交叉区域的中心点。
    4. 您甚至可以在不使用连接组件的情况下尝试此操作,但使用连接组件作为解决方案的一部分可以使其更加强大。

      多边形简化 如果你有一个blob,它在你的应用程序中是一组连接的黑色像素,表示地板上的绳索,那么你可以考虑将这个blob转换为一个或多个多边形以便进一步处理。使用多边形是有好处的。

      如果仅考虑绳索的外边界,则可以看到定义边界的像素集表示多边形。它是一个有很多点的多边形,不是凸多边形,而是一个多边形。

      要简化多边形,可以使用Ramer-Douglas-Puecker等算法:

      https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm

      一旦有了简化的多边形,就可以尝试一些技术来渲染多边形

      中的有用数据
      • Angle Bisector Network
      • 三角测量(例如使用耳朵剪裁)

      三角测量通常取决于初始条件,因此产生的三角测量用于轻微不同的多边形(即,绳索 - > blob - >多边形 - >简化多边形)。因此,在您的应用中,对黑暗绳索区域进行三角测量,然后将一个三角形的中心连接到下一个最近三角形的中心可能是有用的。您还必须处理交叉点,例如绳索重叠。最终,这可以产生一个"骨架化"绳子说到哪......

      <强>骨架化 如果绳索问题是作为课堂练习提出的,那么它可能是尝试骨架化的提示。你可以在这里阅读:

      https://en.wikipedia.org/wiki/Topological_skeleton

      骨架化和细化有其自身需要解决的问题,但你应该深入研究它们并自己看看这些问题。

      Medial Axis Transform(MAT)是一个相关的概念。那里有长篇故事。

      基于边缘的技术 有许多技术可以生成边缘图像&#34;基于边缘强度,能量,熵等,使它们健壮需要花费一点力气。如果您在图像处理方面接受过学术培训,您可能听说过Harris,Sobel,Canny和类似的处理方法 - 没有一个是魔法子弹,但它们简单可靠,并且会产生数据你需要。

      &#34;边缘图像&#34;由表示图像梯度强度[有时是梯度方向]的像素组成。人们可能会把这个边缘图像称为别的东西,但它是重要的概念。

      您对边缘数据的处理完全是另一个主题。但是考虑边缘图像(或至少是对象边界)的一个原因是它减少了算法需要处理的信息量。

      平均转换(及相关) 要回到连接组件一节中提到的分段,还有其他方法可以从背景中分割数字:K-means,mean shift等。你可能不会需要其中任何一个,但它们很整洁,值得学习。

      笔画宽度变换 这是一种有趣的技术,用于从嘈杂的背景中提取文本。虽然它适用于OCR,但它可以用于绳索,因为绳索宽度相对恒定,绳索形状不同,有交叉等等。

      简而言之,简化了一点,您可以将SWT视为寻找&#34;笔画的手段。 (粗线)通过找到彼此反平行的梯度。在笔划(或线)的任一侧,边缘渐变指向垂直于对象边缘。笔划一侧的法线指向与笔划另一侧的法线方向相反的方向。通过在彼此一定距离内过滤像素梯度对,您可以隔离某些笔划 - 甚至是自动的。对于您的示例,表示绳索边缘对的点集合将比其他点对更加常见。

      非刚性匹配 有一些匹配非刚性形状的技术,但它们不值得探索。如果您不熟悉我上面提到的任何技术,请在尝试任何更高级的算法之前先探索其中的一些技术。

      CNN,机器学习等 我们甚至不认为这些方法是一个起点。

      其他注意事项 如果这是一个行业,安全或诸如此类的应用程序,那么您必须确定图像处理在所有环境因素下的工作情况。这不是一项简单的任务,并且可以在“#34;工作&#34;在实验室和实际工作中的设置。

      我希望有所帮助。如果我感到困惑,或者想要更详细地探索一些想法,请随时发布回复。虽然我试图触及一些常见的(ish)技术,但我没有提到解决这个问题的所有不同方法。

      简而言之:一旦你有一个骨架,点网络,或任何代表绳索和红点(已识别的特征)的简化数据集,可以使用一些技巧来找到蓝点上的项目:

      • 对于骨架,沿着每个分支追踪&#34;从知道向外的绳索直到测地距离或直线2D距离是你想要的距离D.
      • 要使用几何图形,请创建宽度为1 - 2像素的圆。找到那个圆和绳子的交点。找到圆和绳索交叉点的中心点。 (也在上面描述。)
      祝你好运!