【问题标题】:OpenCV edge based object detection C++基于 OpenCV 边缘的对象检测 C++
【发布时间】:2020-04-27 23:25:39
【问题描述】:

我有一个应用程序,我必须检测场景中是否存在某些项目。这些项目可以旋转并稍微缩放(更大或更小)。我尝试过使用关键点检测器,但它们不够快速和准确。所以我决定首先使用 Canny(或更快的边缘检测算法)检测模板和搜索区域中的边缘,然后匹配边缘以找到找到的匹配的位置、方向和大小。

所有这些都需要在不到一秒钟的时间内完成。

我尝试过使用matchTemplate()matchShape(),但前者不是缩放和旋转不变的,后者不适用于实际图像。旋转模板图像以进行匹配也很耗时。

到目前为止,我已经能够检测到模板的边缘,但我不知道如何将它们与场景匹配。

我已经完成了以下操作,但无法让它们工作(他们要么使用旧版本的 OpenCV,要么只是不使用演示中的图像之外的其他图像):

https://www.codeproject.com/Articles/99457/Edge-Based-Template-Matching

Angle and Scale Invariant template matching using OpenCV

https://answers.opencv.org/question/69738/object-detection-kinect-depth-images/

有人可以建议我解决这个问题吗?或者尽可能截取相同的代码?

这是我的示例输入图像(要检测的部分用红色标记)

这些是一些正在执行此操作的软件,也是我想要的:

【问题讨论】:

  • 第三种带有粉色轮廓的情况,似乎是所有这些中最简单的,因为可以使用cv2.inrange() 使用简单的颜色分割从背景中分割对象,然后使用cv2.findContours 然后利用轮廓的属性,例如area/perimeter 比率、矩等,这将帮助您检测几何相似的形状。
  • 对于第一种和第二种情况,我建议训练自定义 haar 级联,就像我们为 Face 使用 haar 级联一样。 OpenCV 还提供了用于训练自定义 haar 特征检测器的 API,并且 haar 特征是 scale 独立的,我不确定旋转独立,但我认为您可以通过提供各种方向的训练图像来训练它。
  • 最后一个可以用我的方法解决:stackoverflow.com/questions/59428540/… 如果你能很好地分割形状,你可以在很多情况下使用 minAreaRecht (我认为你示例中的工具图像可能会解决方式,或与关键点匹配)。对旋转不变关键点描述符进行一些研究,以了解如何达到旋转不变性。也许你可以使用它。不过,对于您的特殊情况,可能没有给定的解决方案。
  • @Micka 问题是要检测的项目将由用户设置(它可以是矩形、圆形或任何随机形状)。我将如何找出是哪种情况,然后尝试相应地找到?这是我考虑基于边缘的主要原因。我什至可以使用基于轮廓的检测(如果速度很快的话),但在大多数图像(如第一张和第二张)中很难检测到最外层的轮廓
  • 倒角匹配是一种很好的基于边缘的方法,但您必须使其缩放和旋转不变(例如,为旋转准备不同的模板并使用金字塔方法进行缩放)。通用方法是关键点匹配(筛选/冲浪/球),但它通常需要一些纹理对象。如果您可以识别出一些可重现的边缘,例如角、圆等,那么通过 RANSAC 进行单应性猜测,然后对所有边缘进行内部/外部测试可能会很好。

标签: c++ opencv visual-c++ object-detection template-matching


【解决方案1】:

你的图像质量很差,光线条件很差,所以你只有两种方法: 1. 使用过滤器 -> 二元阈值 -> find_contours -> matchShape。但是对于您的对象类型和图像质量,这种算法非常不稳定。你会得到很多错误的轮廓并且很难过滤它们。 2. Haarcascades -> 剪切边界框 -> 检查里面的形状

所有“特殊点/边缘匹配”算法都不会在如此恶劣的条件下工作。

【讨论】:

    【解决方案2】:

    这个主题是我在一个项目上实际处理的一年。因此,我将尝试解释我的方法是什么以及我是如何做到的。我假设您已经完成了预处理步骤(滤镜、亮度、曝光、校准等)。并确保清除图像上的噪音。

    注意:在我的方法中,我从参考图像上的轮廓收集数据,这是我想要的对象。然后我将这些数据与大图像上的其他轮廓进行比较。

    1. 使用精明的边缘检测并在参考上找到轮廓 图片。你需要在这里确定它不应该错过某些部分 轮廓。如果它错过了,可能预处理部分应该有一些 问题。另一个重要的一点是,你需要找到一个 findContours 的适当模式,因为每种模式都有 不同的属性,因此您需要找到适合您的属性 案子。最后,您需要消除好的轮廓 给你。

    2. 从参考获取轮廓后,可以找到 每个轮廓使用 findContours() 的 outputArray。你可以比较 这些值在您的大图像上并消除轮廓 如此不同。

    3. minAreaRect 精确地为 每个轮廓。就我而言,这个功能非常好用。我是 使用此函数获取 2 个参数:

      a) 计算拟合矩形的短边和长边并比较 与大图上其他轮廓的值。

      b) 计算黑度或白度的百分比(如果您的图像是 灰度,获得接近白色或黑色像素的百分比)和 最后比较一下。

    4. matchShape 可以在最后应用于其余轮廓,或者您也可以应用于所有轮廓(我建议第一种方法)。每个轮廓只是一个数组,因此您可以将参考轮廓保存在一个数组中,并在最后将它们与其他轮廓进行比较。完成 3 个步骤然后应用 matchShape 对我来说非常好。

    5. 我觉得matchTemplate不好直接用。我将每个轮廓绘制到不同的垫零图像(空白黑色表面)作为模板图像,然后与其他轮廓进行比较。直接使用参考模板图像效果不佳。

    6. OpenCV 在找圆、凸度等方面有一些很好的算法。如果你的情况与它们有关,你也可以使用它们作为一个步骤。

    7. 最后,您只需获取所有数据、值,然后您就可以在脑海中制作一个表格。剩下的就是统计分析。

    注意:我认为最重要的部分是预处理部分。因此,请确保您拥有干净且几乎没有噪音的图像和参考。

    注意:如果您只想知道对象是否存在,则培训可能是您的一个很好的解决方案。但如果你想为工业应用做点什么,这是完全错误的方式。我多次尝试了 YOLO 和 haarcascade 训练算法,还用它们训练了一些对象。我得到的经验是:他们几乎可以正确找到物体,但即使您的校准正确,中心坐标、旋转结果等也不会完全正确。另一方面,训练时间和收集数据很痛苦。

    【讨论】:

    • 我正在开发一个工业应用程序,您有什么建议? yolo 或 haarcascade 是否适用于这些小对象?
    • 我不建议您将培训用于工业应用程序。如果您认为它可以解决您的问题,我建议首先使用 haarcascade,因为与 YOLO 相比,训练时间非常短(2000 pos. 5-6 小时,平均处理器中 10 阶段的 1000 neg.images)。您可以使用 createSample 函数进行标记并快速获取正面图像。收集更多更好的数据,您将获得更好的结果。
    猜你喜欢
    • 1970-01-01
    • 2012-08-12
    • 2017-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多