提问人:Kalev Maricq 提问时间:1/12/2020 更新时间:1/12/2020 访问量:89
近似相等物体的交集
Intersection for approximately equal objects
问:
我正在检测图像中的物体并尝试不同的检测算法。我想在我的数据集上比较算法的结果。我已将每个算法的结果存储为 [filepath,detection_box_coordinates,otherstuff] 的列表。我想将两个检测视为相同,如果文件路径相同,并且检测框中的重叠高于某个阈值。我想为任意两个算法结果 A 和 B 生成列表 only_in_A、only_in_B 和 in_both。我希望找到“一种,最好只有一种明显的方法”来做到这一点,但到目前为止,我的搜索已经产生了几种不一定明显的方法。
专注于计算in_both,我考虑过做以下事情:
- 遍历每个列表的每个元素并进行比较
- 按文件路径对列表进行排序和分区,然后针对每个文件路径,遍历每个列表中的元素
- [x for x in itertools.product(A,B) and match(x)] 使用自定义匹配函数
- 将类 Detection 和定义 __eq__ 作为我的匹配函数
- 实现我自己的 Intersector 类,如下所示:Python intersection with custom equality
- 使用 lambda 函数
现在我可以看到这些想法的以下缺点:
- 很慢
- 仍然比集合操作和一堆可能重新发明轮子的代码慢
- 可能速度慢且占用大量内存
- __eq__将是反身的和对称的,但不是传递的。此外,两个项目可能__eq__返回 true,但具有不同的哈希值。
- 同上。不确定性能。
- 还不清楚如何实施。
我的哪些想法是好的,哪些是坏的?我错过了什么明显的方式吗?
答:
0赞
EzIsFoglalt
1/12/2020
#1
我认为经过一些修改的 Detection 类将是一个好主意:
class Detection():
Instances = dict()
In_A = dict()
In_B = dict()
def __new__(cls,*args,**kwargs):
if filepath in Detection.Instances.keys():
_instance = Detection.Instances[filepath]
else:
_instance = super(Detection, cls).__new__(cls, *args, **kwargs)
return _instance
def __init__(self,filepath,coords,other,From_Algo):
if From_Algo = "A"
self.filepath = filepath
self.coords_A = coords
self.in_A = True
self.other_A = other
Detection.In_A[filepath] = self # Make sure that filepath is hashable
if From_Algo = "B"
self.filepath = filepath
self.coords_B = coords
self.in_B = True
self.other_B = other
Detection.In_B[filepath] = self # Make sure that filepath is hashable
Detection.Instances[filepath]=self # Make sure that filepath is hashable
@classmethod
def Check_coord_relation(cls,A_coords,B_coords):
...
# compare A_coords and B_coords
...
return Result
@classmethod
def Get_In_Both(cls):
cls._Get_In_Both = [Det in Det for cls.Instances.values() if (hasattr(Det,"In_A") and hasattr(Det,"In_B") and cls.Check_coord_relation(Det.coords_A,coords_B))]
@classmethod
def Get_Only_In_A(cls):
cls._Only_In_A = [Det in Det for cls.In_A.values() if Det not in cls._Get_In_Both]
@classmethod
def Get_Only_In_B(cls):
cls._Only_In_B = [Det in Det for cls.In_B.values() if Det not in cls._Get_In_Both]
@classmethod
def Calc_Interseciton(cls):
cls.Get_In_Both()
cls.Get_Only_In_A()
cls.Get_Only_In_B()
您可以使用__new__来检查实例是否已经存在,因此可以更新算法中的不同属性,之后该类可以处理创建的所有实例。
首先检查两个算法中的检测,将它们从 A 和 B 中删除。
我无法尝试这个,我希望这能帮助你或给你新的想法。
类变量似乎不需要是字典,但字典速度非常快。
上一个:如何检查一个值与两个值的相等性?
下一个:正确打印值 1 到 10
评论