我有2张图像,它们具有相同的形状,但排列在不同的位置。我想正确匹配那些图像。
执行的步骤...
def modified_hausdorff(A,B):
D = cdist(A,B) #euclidean distance
fhd = np.mean(np.min(D,axis=0))
rhd = np.mean(np.min(D,axis=1))
return max(fhd,rhd)
源图像。
目标图像。
最佳答案
这是双向任务。
前进方向
1.翻译
对于每个轮廓,计算其moment。然后针对该轮廓中的每个点,将其平移一下,即contour.point[i] = contour.point[i] - contour.moment[i]
。这会将所有轮廓点移动到原点。
PS:您需要跟踪每个轮廓的产生力矩,因为它将在下一部分中使用
2.旋转
使用新翻译的点,计算其rotated rect。这将为您提供旋转 Angular 。根据该 Angular ,您需要计算要旋转此轮廓的新 Angular 。 this answer会有所帮助。
达到新 Angular 后,计算rotation matrix。请记住,这里的中心将是起点,即(0, 0)
。在计算旋转矩阵时,我没有考虑缩放(金字塔起作用的地方),因此我通过了1。
PS:您需要跟踪每个轮廓的生成矩阵,因为它将在下一部分中使用
使用该矩阵,可以继续旋转轮廓线中的每个点,如here *所示。
完成所有这些操作后,您可以继续计算Hausdorff距离并找到通过您设置的阈值的轮廓。
后退方向
在第一部分中完成的所有操作都必须撤消,以便我们将有效的轮廓绘制到摄像机的提要上。
1.旋转
回想一下,每个检测到的轮廓都会产生一个旋转矩阵。您要撤消有效轮廓的旋转。只需执行相同的旋转,但使用inverse matrix即可。
For each valid contour and corresponding matrix
inverse_matrix = matrix[i].inv(cv2.DECOMP_SVD)
Use * to rotate the points but with inverse_matrix as parameter
PS:计算逆时,如果生成的矩阵不是平方矩阵,则将失败。即使原始矩阵是非正方形的,
cv2.DECOMP_SVD
也会产生一个逆矩阵。2.翻译
将有效轮廓的点向后旋转,您只需撤消之前执行的平移。无需减去,只需将力矩添加到每个点。
现在,您可以继续将这些轮廓绘制到相机源中。
缩放
这是图像金字塔发挥作用的地方。
您要做的就是按照固定的大小/比例将模板图像调整为所需的次数(称为图层)。教程发现here很好地解释了如何在OpenCV中执行此操作。
不用说,您选择的用于调整图像大小和层数的值将确实在程序的鲁棒性方面发挥巨大作用。
放在一起
模板图像操作
Create a pyramid consisting of n layers
For each layer in n
Find contours
Translate the contour points
Rotate the contour points
该操作只能执行一次,并且只能存储旋转点的结果。
相机Feed操作
假设条件
让模板图像在每个级别的旋转轮廓都存储在
templ_contours
中。因此,如果我说templ_contours[0]
,这将为我提供金字塔等级0的旋转轮廓。让图像的平移,旋转轮廓和力矩分别存储在
transCont
,rotCont
和moment
中。image_contours = Find Contours
for each contour detected in image
moment = calculate moment
for each point in image_contours
transCont.thisPoint = forward_translate(image_contours.thisPoint)
rotCont.thisPoint = forward_rotate(transCont.thisPoint)
for each contour_layer in templ_contours
for each contour in rotCont
calculate Hausdorff Distance
valid_contours = contours_passing_distance_threshold
for each point in valid_contours
valid_point = backward_rotate(valid_point)
for each point in valid_contours
valid_point = backward_translate(valid_point)
drawContours(valid_contours, image)
刚开始时可能会有些混乱,尤其是在跟踪每个轮廓的各自力矩和旋转矩阵时,但是一旦您了解发生了什么,它实际上是一种非常容易实现的算法。
关于python - 使用修正的Hausdorff距离查找形状,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46776280/