4

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

附图例如:

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

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

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

谢谢您的帮助。

在此处输入图像描述

4

3 回答 3

2

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

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

下面是我画的一些形状:

在此处输入图像描述在此处输入图像描述在此处输入图像描述在此处输入图像描述在此处输入图像描述在此处输入图像描述

以下是检测到的角点:

在此处输入图像描述在此处输入图像描述在此处输入图像描述在此处输入图像描述在此处输入图像描述在此处输入图像描述

正如您在最后一组图像中清楚地看到的那样,该方法很容易将矩形/正方形与圆柱体混淆。要处理这个问题,您需要将该方法与其他描述符结合起来。最初,您可能会考虑一个简单的问题,即形状面积与其边界框面积之间的比率(矩形为 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
于 2012-12-20T19:18:50.807 回答
1

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

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

编辑:

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

于 2012-12-19T06:05:17.767 回答
0

尝试计算每个图形的质心。将图中的每个点都视为质量等于 1 的粒子。

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

于 2012-12-19T05:53:11.197 回答