一、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距离可以用来进行简单的模型匹配: