【问题标题】:Position detection of a defined mark in a picture图片中定义标记的位置检测
【发布时间】:2016-05-09 04:22:15
【问题描述】:

我仍然是编码的初学者。我目前正在使用 C/C++ 编写一个程序,该程序正在确定照片中已定义标记(这是一个带有白色周围的黑色圆圈)的像素位置。
我从标记和一个向量中制作了一个 mask,其中包含掩码的每个像素值作为它的元素(使用 Magick++ 我对红色、绿色和蓝色的值求和)。向量包含 aprox。 10 000 个值,因为掩码是 100x100px。我还使用阈值函数来简化图像。

比我做了一个网格,对图片做同样的事情,我想在其中找到标记的坐标。它基本上是一个循环,它遍历图像,当程序知道网格中的像素值时,它会立即将它们与掩码进行比较。主要思想是找到掩码和其中一个网格位置之间的最小差异。

然而,问题在于评估所有网格位置的过程需要大量时间(例如,图像有 1920x1080 像素,因此超过 200 万个向量包含 10000 个值)。我决定循环网格不是每个像素,而是例如每 10 列和行,并且为了从这个过程中获得最佳关联,我选择了使用每个像素循环的区域。但是,这仍然需要很多时间。

我想问你,是否有一些方法可以改进这种方法以获得更好(更快)的结果,或者整个想法不是时间效率高,我应该使用不同的方法。

感谢您的每一个建议!

编辑:该程序将用于处理多个图像,并且所有图像的大小都相同。这是阈值后的图片,标记是大黑点。 Image

【问题讨论】:

  • 请说明标记是否有特定位置或可能在任何位置。此外,澄清它是否具有特定大小,可能具有任何大小。此外,如果标记完全覆盖照片上的内容。
  • 您是否尝试过使用圆霍夫变换等算法?它可能会限制您最感兴趣的区域,从而使您的方法更快。
  • 我想您应该阅读一些有关最先进的模板匹配的内容。它与您所做的类似,但速度非常快。
  • 还请澄清图像是否是完全数字的,并且标记肯定会有白色和黑色(如果表示为 8 位深度的 RGB,则表示 0,0,0 和 255,255,255)。
  • 使用 GPU。它们是为这种事情而生的。

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


【解决方案1】:

我觉得有趣的想法是金字塔方案 - 或渐进式细化:您在较小尺寸的图像中找到点,然后在较大的图像中仅搜索一个小矩形。

如果您将图像在每个维度上减少 2,那么您将减少 4 时间以及在较大图像中的一些搜索工作。

这有一些问题:减少会影响我期望的准确性。你可能会错过这个地方。

在这种情况下,您必须将样品(模板)切割成一个半尺寸的模板。当你一半一半……模板会模糊到周围的物体中,所以不可能有一个有效的模板;一旦我猜到该点周围有几个像素,则为一半大小。

【讨论】:

  • 我喜欢这个想法,在较小尺寸的图像中找到点,而不是在较大的图像中定义精确算法应该运行的矩形。一定要试试。我想知道我可以从中获得多少计算时间。谢谢!
【解决方案2】:

由于您没有指定工具或操作系统,我将选择安装在大多数 Linux 发行版上并且可用于 OSX 和 Windows 的 ImageMagick。我只是在命令行中使用它,但有可用的 C、C++、Python、Perl、PHP、Ruby、Java 和 .Net 绑定。​​

我会像这样使用 “连接组件分析”“Blob 分析”

convert image.png -negate                            \
   -define connected-components:area-threshold=1200  \
   -define connected-components:verbose=true         \
   -connected-components 8 -auto-level result.png

我用-negate 反转了你的图像,因为在形态学操作中,前景通常是白色而不是黑色。我已经排除了小于 1200 像素的斑点,因为您的圆圈似乎有 22 像素的半径,这使得面积为 1520 像素 (Pi * 22^2)。

这给出了这个输出,这意味着 7 个 blob - 每行一个 - 带有边界框和每个区域的区域:

Objects (id: bounding-box centroid area mean-color):
  0: 1358x1032+0+0 640.8,517.0 1296947 gray(0)
  3: 341x350+1017+287 1206.5,468.9 90143 gray(255)
  106: 64x424+848+608 892.2,829.3 6854 gray(255)
  95: 38x101+44+565 61.5,619.1 2619 gray(255)
  49: 17x145+1341+379 1350.3,446.7 2063 gray(0)
  64: 43x43+843+443 864.2,464.1 1451 gray(255)
  86: 225x11+358+546 484.7,551.9 1379 gray(255)

请注意,由于您的圆圈是 42x42 像素,您将寻找一个接近该大小的方形斑点 - 所以我正在查看倒数第二行。我可以像这样在您的原始图像上用红色绘制:

convert image.png -fill none -stroke red -draw "rectangle 843,443 886,486" result.png

另外,请注意,当您正在寻找一个圆圈时,您会希望该区域为 pi * r^2 或大约 1500 像素,您可以在输出的倒数第二列中查看。

在合理规格的 iMac 上运行时间为 0.4 秒。请注意,您可以将图像分成 4 个并并行运行每个季度以加快速度。所以,如果你这样做:

#!/bin/bash
# Split image into 4 (maybe should allow 23 pixels overlap)
convert image.png -crop 1x4@ tile-%02d.mpc

# Do Blob Analysis on 4 strips in parallel
for f in tile-*mpc; do
   convert $f -negate \
      -define connected-components:area-threshold=1200 \
      -define connected-components:verbose=true        \
      -connected-components 8 info: &
done
# Wait for all 4 to finish
wait

运行时间约为 0.14 秒。

【讨论】:

    猜你喜欢
    • 2015-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-13
    • 2016-04-05
    • 1970-01-01
    相关资源
    最近更新 更多