提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
轮廓相似度比较的两种算法
- 欧式距离
- 豪斯多夫距离
欧式距离示意图
豪斯多夫距离示意图
形状上下文
import numpy as np
# 轮廓1
contour1 = [(0, 0), (1, 2), (2, 1), (1, -1), (0, 0)]
# 轮廓2
contour2 = [(0, 0), (1, 3), (2, 1), (1, -1), (0, 0)]
def shape_context(points, num_bins=12):
# 计算形状上下文
context = []
for point in points:
hist = np.zeros(num_bins)
for other in points:
if point != other:
dx, dy = np.array(other) - np.array(point)
r = np.sqrt(dx ** 2 + dy ** 2)
theta = np.arctan2(dy, dx) % (2 * np.pi)
bin_idx = int(num_bins * theta / (2 * np.pi))
hist[bin_idx] += 1 / r # 使用距离的倒数作为权重
context.append(hist)
return np.array(context)
欧式距离
import numpy as np
from scipy.spatial.distance import cdist
# 轮廓1
contour1 = [(10, 10), (11, 12), (12, 11), (11, 9), (10, 10)]
# 轮廓2
contour2 = [(0, 0), (1, 3), (2, 1), (1, -1), (0, 0)]
def shape_context(points, num_bins=12):
# 计算形状上下文
context = []
for point in points:
hist = np.zeros(num_bins)
for other in points:
if point != other:
dx, dy = np.array(other) - np.array(point)
r = np.sqrt(dx ** 2 + dy ** 2)
theta = np.arctan2(dy, dx) % (2 * np.pi)
bin_idx = int(num_bins * theta / (2 * np.pi))
hist[bin_idx] += 1 / r # 使用距离的倒数作为权重
context.append(hist)
return np.array(context)
# 计算两个轮廓的形状上下文
sc1 = shape_context(contour1)
sc2 = shape_context(contour2)
def compare_shape_context(sc1, sc2):
# 计算两个形状上下文之间的距离
distances = cdist(sc1, sc2, metric='euclidean')
# 返回最小距离和平均距离
min_distance = np.min(distances)
avg_distance = np.mean(distances)
return min_distance, avg_distance
# 比较两个轮廓的相似度
min_distance, avg_distance = compare_shape_context(sc1, sc2)
print(f"最小距离: {min_distance}")
print(f"平均距离: {avg_distance}")
豪斯多夫距离
import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial.distance import directed_hausdorff
def hausdorff_distance(setA, setB):
"""计算两组点的Hausdorff距离"""
return max(directed_hausdorff(setA, setB)[0], directed_hausdorff(setB, setA)[0])
# 轮廓1
# 轮廓1
contour1 = [(10, 10), (11, 13), (12, 11), (13, 10), (10, 10)]
# 轮廓2
contour2 = [(0, 0), (1, 3), (2, 1), (1, -1), (0, 0)]
def shape_context(points, num_bins=12):
# 计算形状上下文
context = []
for point in points:
hist = np.zeros(num_bins)
for other in points:
if point != other:
dx, dy = np.array(other) - np.array(point)
r = np.sqrt(dx ** 2 + dy ** 2)
theta = np.arctan2(dy, dx) % (2 * np.pi)
bin_idx = int(num_bins * theta / (2 * np.pi))
hist[bin_idx] += 1 / r # 使用距离的倒数作为权重
context.append(hist)
return np.array(context)
# 计算两个轮廓的形状上下文
sc1 = shape_context(contour1)
sc2 = shape_context(contour2)
distance = hausdorff_distance(sc1, sc2)
print('distance', distance)
相似度计算
similarity = 1 / (1 + distance)
print("相似度:", similarity)
可视化轮廓
import matplotlib.pyplot as plt
# 可视化轮廓(可选)
def plot_contour(contour, label):
x, y = zip(*contour)
plt.plot(x, y, label=label)
plt.figure()
plot_contour(contour1, 'Contour 1')
plot_contour(contour2, 'Contour 2')
plt.legend()
plt.show()
总结
本文仅仅简单介绍了欧式距离与豪斯多夫距离计算轮廓相似度的实现方法。