Python+Opencv2(一)Hausdorff距离

一、Hausdorff介绍

豪斯多夫距离以德国数学家(Hausdorff,Felix, 1868~1942)来命名,豪斯多夫距离是在度量空间中任意两个集合之间定义的一种距离

这个说法大家可能不太熟悉,反而大家熟知的欧几里得距离或者欧式距离

欧几里得几何称为等距同构下的豪斯多夫距离。

在数学中,欧几里得距离或欧几里得度量欧几里得空间中两点间“普通”(即直线)距离。使用这个距离,欧氏空间成为度量空间。
在这里插入图片描述
(图片摘自百度百科)

欧式距离是两个图形最近点的距离(图中红点的距离,不会考虑整个形状):
在这里插入图片描述
最短距离的概念带有非常低的信息内容(最短的距离不考虑对象的位置):
在这里插入图片描述
(摘自:Mr. Godfried Toussaint《Hausdorff distant between convex ploygons》)

豪斯多夫距离:
在这里插入图片描述
(图片摘自图像配准之Hausdorff距离

简单来说是一个集合到另一个集合中最近点的最大距离
很明显的是H(A,B)不等于H(B,A):
在这里插入图片描述
Hausdorff距离是由这两个距离的最大值决定。容易受极端值的影响。

二、Python小实例

准备3张图片:
在这里插入图片描述
运用opencv的cv2.createHausdorffDistanceExtractor()创建Hausdorff距离:

import cv2
import matplotlib.pyplot as plt

def get_contours(img):
    """获取连通域

    :param img: 输入图片
    :return: 最大连通域
    """
    # 灰度化, 二值化, 连通域分析
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    ret, img_bin = cv2.threshold(img_gray, 200, 255, cv2.THRESH_BINARY)
    contours, hierarchy = cv2.findContours(img_bin, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    
    return contours[0]


def main():

    # 1.导入图片
    img_cs1 = cv2.imread("images/hand/one.png")
    img_cs2 = cv2.imread("images/hand/two.png")
    img_hand = cv2.imread("images/hand/hand.png")

    # 2.获取图片连通域
    cnt_cs1 = get_contours(img_cs1)
    cnt_cs2 = get_contours(img_cs2)
    cnt_hand = get_contours(img_hand)

    # 3.创建计算距离对象
    hausdorff_sd = cv2.createHausdorffDistanceExtractor()

    # 4.计算轮廓之间的距离
    d1 = hausdorff_sd.computeDistance(cnt_hand, cnt_hand)
    print("与自身的距离hausdorff\t d1=", d1)

    d2 = hausdorff_sd.computeDistance(cnt_hand, cnt_cs2)
    print("与相似图片的距离hausdorff\t d2=", d2)

    d3 = hausdorff_sd.computeDistance(cnt_hand, cnt_cs1)
    print("与不同图片的距离hausdorff\t d3=", d3)

    # 5.显示图片
    plt.figure(figsize=(10,10))
    plt.subplot(2,2,1)
    plt.imshow(cv2.cvtColor(img_hand, cv2.COLOR_BGR2RGB))
    plt.title(u'hand.png')
    plt.subplot(2,2,2)
    plt.imshow(cv2.cvtColor(img_hand, cv2.COLOR_BGR2RGB))
    plt.ylabel(u'self_hand.png')
    plt.xlabel(u'd = '+'%.4f'%d1)
    plt.subplot(2,2,3)
    plt.imshow(cv2.cvtColor(img_cs2, cv2.COLOR_BGR2RGB))
    plt.ylabel(u'near_two.png')
    plt.xlabel(u'd = '+'%.4f'%d2)
    plt.subplot(2,2,4)
    plt.imshow(cv2.cvtColor(img_cs1, cv2.COLOR_BGR2RGB))
    plt.ylabel(u'other_one.png')
    plt.xlabel(u'd = '+'%.4f'%d3)
    plt.show()
    
if __name__ == '__main__':
    main()

运行效果:
在这里插入图片描述
可以发现:

  • 图片和本身的Hausdorff距离为0
  • 和相似图片的Hausdorff距离较小
  • 和不相似图片的Hausdorff距离较大

因此,Hausdorff距离可以用来进行简单的模型匹配:
在这里插入图片描述

©️2020 CSDN 皮肤主题: 终极编程指南 设计师:CSDN官方博客 返回首页