这里有一些东西可以帮助您入门。当遇到新问题时,我认为尝试很多复杂的步骤并没有多大价值,因为它们可以在某个地方使用。所以我的重点是使用相对简单的东西,在更多不同的情况下会失败,但希望你能看到它的价值并了解问题所在。
该方法完全基于角点检测;这种检测的两种典型方法是 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