【问题标题】:Distance between set of lines一组线之间的距离
【发布时间】:2012-12-21 11:07:57
【问题描述】:

假设我的图像是简单的形状 - 一组线条、点、曲线和简单的对象, 如何计算图像之间的距离 - 所以长度很重要,但总比例不重要,线\曲线的位置很重要,角度很重要等

附图例如:

我的比较对象是左上角的一个立方体,分数只是这个例子的虚构。

  1. 到圆柱体的距离为 80(有 2 条线,但顶部几何形状不同)
  2. 左下角的立方体得分为 100,因为它完全匹配不同比例的线条。
  3. 右下角的矩形得分为 90,因为它的顶部有完全匹配线,但侧面有不同的比例线。

我正在寻找可以帮助我开始思考解决方案的算法名称或一般方法......

感谢您的帮助。

【问题讨论】:

  • 您忘记评论您的问题的一个非常重要和关键的方面:这些形状是如何获得的?有人手动绘制它们吗?或者,也许,您是否有一组定义形状的点?如果是前者,那么你有一个非常困难的问题,只能通过猜测来近似。
  • 我将通过边缘和线检测或霍夫变换得到图像,原始图像是简单形状立方体圆形三角形等的灰度,因此变换输出应该(理论上)与原始图像匹配输入
  • 很好,但我很想知道您将如何使用 Hough 处理任意行 :) 如果稍后我有时间,我会根​​据您的更新信息提供一些答案。
  • 我在想任意的线和点都会参与评分机制,我不知道这到底是怎么回事,我需要寻找算法名称或方法。
  • 我仍然很好奇您认为您将如何使用 Hough 处理任意曲线。

标签: algorithm image-processing


【解决方案1】:

这里有一些东西可以帮助您入门。当遇到新问题时,我认为尝试很多复杂的步骤并没有多大价值,因为它们可以在某个地方使用。所以我的重点是使用相对简单的东西,在更多不同的情况下会失败,但希望你能看到它的价值并了解问题所在。

该方法完全基于角点检测;这种检测的两种典型方法是 Harris 检测器,或者是 Shi 和 Tomasi 在 1994 年的“Good Features to Track”一文中描述的一种。我将使用第二种方法,因为在 OpenCV 和较新的 Matlab 中有现成的实现,可能还有很多其他地方。它在这些包上的实施还允许更轻松地调整关于拐角质量和拐角之间的最小距离的参数。那么,假设您可以正确检测所有角点,您如何根据这些点测量一个形状与另一个形状的接近程度?图像具有任意大小,所以我的想法是将点坐标标准化为范围 [0, 1]。这解决了缩放问题,根据原始描述,这是所需的。现在我们必须比较 [0, 1] 范围内的点集。这里我们采用最简单的方法:考虑形状a 中的一点p,形状b 中最近的点是什么?我们假设它是这个点pb 中的任何点之间绝对差异最小的一个。如果我们将所有值相加,我们会得到形状之间的评分。分数越低,形状越相似(根据这种方法)。

这是我画的一些形状:

以下是检测到的角点:

正如您在最后一组图像中清楚地看到的那样,该方法很容易将矩形/正方形与圆柱体混淆。要处理这个问题,您需要将该方法与其他描述符结合起来。最初,您可能会考虑一个简单的问题,即形状的面积与其边界框面积之间的比率(矩形为 1,圆柱体为更低)。

使用上述方法,以下是第一和第二形状、第一和第三形状之间的测量值……分别为:0.02358485、0.41350339、0.30128458 0.4980852、0.18031262。第二个多维数据集是第一个多维数据集的调整大小版本,如您所见,它们在这个指标上非常相似。最后一个形状是第一个立方体的大小调整版本,但没有保持纵横比,并且度量给出了更大的差异。

如果您想使用执行此操作的代码,这里是(在 Python 中,取决于 OpenCV,numpy):

import sys
import cv2 as cv
import numpy

inp = []
for fname in sys.argv[1:]:
    img_color = cv.imread(fname)
    img = cv.cvtColor(img_color, cv.COLOR_RGB2GRAY)
    inp.append((img_color, img))

ptsets = []

# Corner detection parameters.
params = (
        200,  # max number of corners
        0.01, # minimum quality level of corners
        10,   # minimum distance between corners
)
# Params for visual circle markers.
circle_radii = 3
circle_color = (255, 0, 0)
for i, (img_color, img) in enumerate(inp):
    height, width = img.shape
    cornerMap = cv.goodFeaturesToTrack(img, *params)
    corner = numpy.array([c[0] for c in cornerMap])

    for c in corner:
        cv.circle(img_color, tuple(c), circle_radii, circle_color, -1)

    # Just to visually check for correct corners.
    cv.imwrite('temp_%d.png' % i, img_color)

    # Convert corner coordinates to [0, 1]
    cornerUnity = (corner - corner.min()) / (corner.max() - corner.min())
    # You might want to use other descriptors here. XXX
    ptsets.append(cornerUnity)


def compare_ptsets(p):
    res = numpy.zeros(len(p))

    base = p[0]
    for i in xrange(1, len(p)):
        sum_min_diff = sum(numpy.abs(p[i] - value).min() for value in base)
        res[i] = sum_min_diff

    return res

res = compare_ptsets(ptsets)
print res

【讨论】:

  • 谢谢你的详细解答,任意曲线确实是我的问题。你建议如何处理曲线?
  • 拐角检测也是一个很好的起点。检测到角落后,您可以轻松分割线条。现在这取决于这些曲线实际上有多随意。如果我自己解决这个问题,并在我的脑海中施加了一些限制,我可能会执行样条近似来关联两个图中线条的相似程度。
【解决方案2】:

要遵循的过程取决于您要考虑的功能深度和所需的准确性。

如果您想要更准确的信息,请搜索一些技术论文,例如 this,它们可以提供具体且经过充分验证的方法或算法。

编辑:

华尔兹算法(人工智能中的一种方法)的想法可以调整。这只是我的想法。解释原始图像,从中生成一些约束。对于每个候选人,找出它满足的约束数量。满足更多约束的那一张将与原始图像最相似。

【讨论】:

    【解决方案3】:

    尝试为每个数字计算mass center。把图中的每个点看成质量等于1的粒子。

    然后将每个距离计算为sqrt((x1-x2)^2 + (y1-y2)^2),其中 (xi, yi) 是图 i 的质心坐标。

    【讨论】:

    • 你如何处理这些距离?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-17
    • 2017-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多