我正在寻找检测标记的距离和方向的方法。标记为L形;宽度和高度相等的两条线相连以形成L形。

为了检测方向和距离,我需要将相机上捕获的L形分成两行。

考虑到代码每帧需要运行多次,什么是轻量级的方法?

我已经使用此处描述的算法http://www.labbookpages.co.uk/software/imgProc/blobDetection.html实现了斑点检测。

我曾考虑过使用霍夫变换,但我担心执行每一帧都需要大量处理能力。最重要的是,我认为这不是这种情况下最准确的方法。我已经进行了适当的分析,以从单行中提取准确的 vector ,但是不确定如何将L形切成两行。

下图是相机如何捕捉L形的不同结果的图片。

opencv - 将L形分成两行-LMLPHP

我当时以为我可以分割L形,方法是用一条穿过质心和边界框中心的线将其分开,但这是行不通的。

关于如何实现的粗略头脑 Storm 草图:

opencv - 将L形分成两行-LMLPHP

最佳答案

扫描线!

请参阅Python 中的(更新的)演练here,其中包含图像以可视化方式显示我的数据之旅:)

跳到最后的“Scanlines”解决方案

opencv - 将L形分成两行-LMLPHP
opencv - 将L形分成两行-LMLPHP

扫描线

基本

假设条件

我假设您的示例图片中存在这些限制

  • 您的图像中有(几个)L形。
  • 您可以轻松地将它们分段(没有重叠的形状,没有将一个L延续到另一个...)
  • 您知道Ls
  • 中线条的确切宽度

    标记您的二进制图像

    您想首先知道哪个像素是哪个L的一部分,这是通过“标记”二进制图像完成的。

    还计算每个体积的边界框,如下所示:

    旋转坐标系

    现在,真正的技巧是将每种形状从x / y正交系统更改为“L形参考”。

    可以将其重新定义为X轴作为L的一个分支,将Y轴重新定义为另一分支。
    一旦我们计算了一个到另一个的转换 vector ,我们就很安全了!

    让我们考虑一下PCA方式

    我们现在面临的问题(“估计数据集变化的最大轴”)是可以使用协方差特征 vector 的时刻。

    我不会太深入地介绍它,但是您可以查看intro to PCA帖子以了解它。

    该问题通常在更高的维度上定义(“给定50维数据集,计算出其中10个最大的变化轴”),但可以通过单独考虑每种形状并指出每个像素来扩展到2D点云问题属于L的点是2D空间中的一个点。

    但是,这将浪费计算能力,因为与PCA的常规情况相比,您的L点位置已经受到限制(它们在一条线上,没有随机分散)。这个问题涉及的线性代数的野兽在这个小问题上是过大的杀伤力

    霍夫线,来抢救!

    您只想在2D图像中找到线条?
    对行(也称为“hough线”)使用Hough变换。
    OpenCV拥有它。

    再次介绍一下:OpenCV's python tutorial on Hough Lines

    我使用了二进制图像的框架(因此,每行仅被更新一次),并手动选择了我为算法提供给OpenCV的参数。
    这就是行有时似乎与特定图像不完全匹配的原因,这是由于采样率和诸如=)

    新希望

    在您指出了计算速度的必要性之后,我想到了更多利用图像属性的技术。

    兰萨克

    我想到对数据使用RANSAC变体:毕竟,您希望将线拟合到点云中。
    如您所知,基本技术是
  • (随机)选择足够的数据以适合模型(您的情况下为线)
  • 评估离群数(模型无法使用的数据点)
  • 重申并保持得分最高的模型的统计(并保持一定时间,包括数学在内)

  • RANSAC的一个很棒的介绍是this song(奇怪的是)

    但我看到了并发症:
  • 哪种型号? :您是使用4个点来定义2条线,还是对一条线做2点并进行两次?
  • 没有异常值:您实际上没有适当的异常值,那么为什么要对这样一个小问题使用RANSAC?
  • 计算能力:您确实会无缘无故地进行数千次迭代,因为您正在随机浏览各个点。

  • 不用说,RANSAC不仅可以解决问题,而且我们可以将其用作灵感

    扫描线!

    让我们考虑一下Ls的边界框。

    如果我们在Y=0上水平 slice ,我们将拥有一维数组,并为True定义了一个连续区域

    那么,如果我们像这样间隔 slice 图像来定义L的 vector ,该怎么办?

    将5%设置为基线,我们只是找到“哪个X-index是Y = 0值的一维数组的中心”,然后对Y = 0.05 * img_width进行相同操作。

    现在,我们有2个2D点定义了图像的第一行。

    在另一侧重复,您将找到解决方案!

    通过计算,您只是在img_width长度数组中找到4个中值,
    每一个都是图像中连续的内存块(Heeeeelllo L2缓存命中!)。

    同样,如果现在很难想象,请参阅code walkthrough的结尾部分

    10-06 11:44