python - 使用修正的Hausdorff距离查找形状

标签 python opencv image-processing computer-vision pattern-recognition

我有2张图像,它们具有相同的形状,但排列在不同的位置。我想正确匹配那些图像。

执行的步骤...

  • 从源图像获取轮廓。
  • 从目标图像获取轮廓。
  • 使用修改的Hausdorff距离比较从源到目标的轮廓。
  • 获取最小值作为匹配项。
    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的旋转轮廓。

    让图像的平移,旋转轮廓和力矩分别存储在transControtContmoment中。
    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/

    相关文章:

    python - 计算行日期之前 x 天的出现次数

    python - 使用列表理解创建 numPy 数组

    移植opencv所需的文件

    python - 使用 OpenCV 和 Python 查找数独网格

    python - 将解析后的 pdf 中的句子连接在一起

    通过逻辑索引对 Python OpenCV 进行阈值处理

    java - Android - Opencv 增加 FPS

    python - 在python opencv中查找图像的所有X和Y坐标

    c# - 从一大组照片中找出一张照片是否是单色/棕褐色

    python - 在 cython : memoryview vs vector of dictionaries 中快速访问稀疏矩阵