如何匹配 Python 中两个列表中最接近的数组?
How to match closest arrays in two lists in Python?
我正在 2400x3000
图像上检测到一些对象。每个图像的大小都相同。但是每个图像都略有不同(可能有点旋转、倾斜等)。因此,我想使用第一张图像检测到的边界框坐标作为其他图像的参考。
所以我想找到检测到的边界框坐标数组之间的最佳匹配。这是一个例子:
[187.0, 489.0, 1501.0, 575.0]
[1810.0, 1967.0, 1917.0, 2052.0]
[1360.0, 2187.0, 1467.0, 2275.0]
[1256.0, 2188.0, 1361.0, 2276.0]
[506.0, 2197.0, 615.0, 2284.0]
[199.0, 2288.0, 306.0, 2372.0]
这是第一次报告坐标。另一个是:
[200.0, 490.0, 1491.0, 588.0]
[1813.0, 1966.0, 1919.0, 2053.0]
[1370.0, 2188.0, 1473.0, 2276.0]
[1265.0, 2189.0, 1365.0, 2275.0]
[520.0, 2200.0, 629.0, 2288.0]
[222.0, 2291.0, 327.0, 2376.0]
如你所知,这已经匹配了。第一份报告中的每一行都与第二份报告相对应。
但我想自动完成。我希望 Python 找到最接近的数组并匹配它们。
我看过数组比较、列表比较等算法,但我觉得我的情况有所不同,因为它们不是随机数而是坐标。
有人知道如何做到这一点吗?
例如:
[200.0, 490.0, 1491.0, 588.0]
应匹配:
[187.0, 489.0, 1501.0, 575.0]
或
这个数组:
[1813.0, 1966.0, 1919.0, 2053.0]
应匹配:
[1810.0, 1967.0, 1917.0, 2052.0]
提前致谢。
编辑:更具体地说,我需要根据匹配对两个列表进行排序。
TL;DR 解决方案:请看 James 的回答,它很有魅力!
您可以使用 k-nearest neighbors 并将邻居数设置为 1。第一组边界框中的每个示例都将对应于它自己的 class。拟合模型后,您可以预测哪些边界框最接近第一组。
from sklearn.neighbors import KNeighborsClassifier
import numpy as np
d1 = np.array(
[[187.0, 489.0, 1501.0, 575.0],
[1810.0, 1967.0, 1917.0, 2052.0],
[1360.0, 2187.0, 1467.0, 2275.0],
[1256.0, 2188.0, 1361.0, 2276.0],
[506.0, 2197.0, 615.0, 2284.0],
[199.0, 2288.0, 306.0, 2372.0]]
)
d2 = np.array(
[[200.0, 490.0, 1491.0, 588.0],
[1813.0, 1966.0, 1919.0, 2053.0],
[1370.0, 2188.0, 1473.0, 2276.0],
[1265.0, 2189.0, 1365.0, 2275.0],
[520.0, 2200.0, 629.0, 2288.0],
[222.0, 2291.0, 327.0, 2376.0]]
)
classes = np.arange(len(d1))
knn = KNeighborsClassifier(n_neighbors=1)
knn.fit(d1, y=classes)
knn.predict(d1)
# returns:
array([0, 1, 2, 3, 4, 5])
如您所述,这已经与第一组边界框的顺序相匹配。然而,如果我们看一组更随机的数据:
d3 = np.array([[ 524.0, 2182.0, 632.0, 2294.0],
[1368.0, 2173.0, 1471.0, 2287.0],
[ 182.0, 474.0, 1473.0, 605.0],
[1797.0, 1975.0, 1930.0, 2055.0],
[1281.0, 2202.0, 1356.0, 2263.0],
[ 227.0, 2295.0, 339.0, 2394.0]]
)
matches = knn.predict(d3)
matches
# returns:
array([4, 2, 0, 1, 3, 5])
要实际使用最接近的匹配项,我们可以使用 argsort 重新排序 d3
数组,使其与 d1
的 class 对齐。我们对预测的 classes matches
使用 argsort 来获得一个索引数组,该索引数组将对 classes 进行排序。然后使用索引数组正确排序 d3
以匹配 d1
d3_sorted = d3[np.argsort(matches)]
d3_sorted
# returns:
array([[ 182., 474., 1473., 605.],
[1797., 1975., 1930., 2055.],
[1368., 2173., 1471., 2287.],
[1281., 2202., 1356., 2263.],
[ 524., 2182., 632., 2294.],
[ 227., 2295., 339., 2394.]])
请更改以下函数中的变量 closest_percentage 以定义接近度
默认情况下,我发送的最接近百分比是 10,这意味着元素应该接近 10% 的边距
def closest_arrays(lst1,lst2,closest_percentage=5.0):
if(len(lst1)!=len(lst2)):
return False;
else:
counter=1
for i in range(len(lst1)):
if (((abs(lst1[i])-abs(lst2[i]))/(abs(lst1[i]))*100) > closest_percentage):
return False;
return True;
如果所有元素都小于或等于 closest_percentage(默认为 5%)则 return True
我正在 2400x3000
图像上检测到一些对象。每个图像的大小都相同。但是每个图像都略有不同(可能有点旋转、倾斜等)。因此,我想使用第一张图像检测到的边界框坐标作为其他图像的参考。
所以我想找到检测到的边界框坐标数组之间的最佳匹配。这是一个例子:
[187.0, 489.0, 1501.0, 575.0]
[1810.0, 1967.0, 1917.0, 2052.0]
[1360.0, 2187.0, 1467.0, 2275.0]
[1256.0, 2188.0, 1361.0, 2276.0]
[506.0, 2197.0, 615.0, 2284.0]
[199.0, 2288.0, 306.0, 2372.0]
这是第一次报告坐标。另一个是:
[200.0, 490.0, 1491.0, 588.0]
[1813.0, 1966.0, 1919.0, 2053.0]
[1370.0, 2188.0, 1473.0, 2276.0]
[1265.0, 2189.0, 1365.0, 2275.0]
[520.0, 2200.0, 629.0, 2288.0]
[222.0, 2291.0, 327.0, 2376.0]
如你所知,这已经匹配了。第一份报告中的每一行都与第二份报告相对应。
但我想自动完成。我希望 Python 找到最接近的数组并匹配它们。
我看过数组比较、列表比较等算法,但我觉得我的情况有所不同,因为它们不是随机数而是坐标。
有人知道如何做到这一点吗?
例如:
[200.0, 490.0, 1491.0, 588.0]
应匹配:
[187.0, 489.0, 1501.0, 575.0]
或 这个数组:
[1813.0, 1966.0, 1919.0, 2053.0]
应匹配:
[1810.0, 1967.0, 1917.0, 2052.0]
提前致谢。
编辑:更具体地说,我需要根据匹配对两个列表进行排序。
TL;DR 解决方案:请看 James 的回答,它很有魅力!
您可以使用 k-nearest neighbors 并将邻居数设置为 1。第一组边界框中的每个示例都将对应于它自己的 class。拟合模型后,您可以预测哪些边界框最接近第一组。
from sklearn.neighbors import KNeighborsClassifier
import numpy as np
d1 = np.array(
[[187.0, 489.0, 1501.0, 575.0],
[1810.0, 1967.0, 1917.0, 2052.0],
[1360.0, 2187.0, 1467.0, 2275.0],
[1256.0, 2188.0, 1361.0, 2276.0],
[506.0, 2197.0, 615.0, 2284.0],
[199.0, 2288.0, 306.0, 2372.0]]
)
d2 = np.array(
[[200.0, 490.0, 1491.0, 588.0],
[1813.0, 1966.0, 1919.0, 2053.0],
[1370.0, 2188.0, 1473.0, 2276.0],
[1265.0, 2189.0, 1365.0, 2275.0],
[520.0, 2200.0, 629.0, 2288.0],
[222.0, 2291.0, 327.0, 2376.0]]
)
classes = np.arange(len(d1))
knn = KNeighborsClassifier(n_neighbors=1)
knn.fit(d1, y=classes)
knn.predict(d1)
# returns:
array([0, 1, 2, 3, 4, 5])
如您所述,这已经与第一组边界框的顺序相匹配。然而,如果我们看一组更随机的数据:
d3 = np.array([[ 524.0, 2182.0, 632.0, 2294.0],
[1368.0, 2173.0, 1471.0, 2287.0],
[ 182.0, 474.0, 1473.0, 605.0],
[1797.0, 1975.0, 1930.0, 2055.0],
[1281.0, 2202.0, 1356.0, 2263.0],
[ 227.0, 2295.0, 339.0, 2394.0]]
)
matches = knn.predict(d3)
matches
# returns:
array([4, 2, 0, 1, 3, 5])
要实际使用最接近的匹配项,我们可以使用 argsort 重新排序 d3
数组,使其与 d1
的 class 对齐。我们对预测的 classes matches
使用 argsort 来获得一个索引数组,该索引数组将对 classes 进行排序。然后使用索引数组正确排序 d3
以匹配 d1
d3_sorted = d3[np.argsort(matches)]
d3_sorted
# returns:
array([[ 182., 474., 1473., 605.],
[1797., 1975., 1930., 2055.],
[1368., 2173., 1471., 2287.],
[1281., 2202., 1356., 2263.],
[ 524., 2182., 632., 2294.],
[ 227., 2295., 339., 2394.]])
请更改以下函数中的变量 closest_percentage 以定义接近度
默认情况下,我发送的最接近百分比是 10,这意味着元素应该接近 10% 的边距
def closest_arrays(lst1,lst2,closest_percentage=5.0):
if(len(lst1)!=len(lst2)):
return False;
else:
counter=1
for i in range(len(lst1)):
if (((abs(lst1[i])-abs(lst2[i]))/(abs(lst1[i]))*100) > closest_percentage):
return False;
return True;
如果所有元素都小于或等于 closest_percentage(默认为 5%)则 return True