近似相等物体的交集

Intersection for approximately equal objects

提问人:Kalev Maricq 提问时间:1/12/2020 更新时间:1/12/2020 访问量:89

问:

我正在检测图像中的物体并尝试不同的检测算法。我想在我的数据集上比较算法的结果。我已将每个算法的结果存储为 [filepath,detection_box_coordinates,otherstuff] 的列表。我想将两个检测视为相同,如果文件路径相同,并且检测框中的重叠高于某个阈值。我想为任意两个算法结果 A 和 B 生成列表 only_in_A、only_in_B 和 in_both。我希望找到“一种,最好只有一种明显的方法”来做到这一点,但到目前为止,我的搜索已经产生了几种不一定明显的方法。

专注于计算in_both,我考虑过做以下事情:

  1. 遍历每个列表的每个元素并进行比较
  2. 按文件路径对列表进行排序和分区,然后针对每个文件路径,遍历每个列表中的元素
  3. [x for x in itertools.product(A,B) and match(x)] 使用自定义匹配函数
  4. 将类 Detection 和定义 __eq__ 作为我的匹配函数
  5. 实现我自己的 Intersector 类,如下所示:Python intersection with custom equality
  6. 使用 lambda 函数

现在我可以看到这些想法的以下缺点:

  1. 很慢
  2. 仍然比集合操作和一堆可能重新发明轮子的代码慢
  3. 可能速度慢且占用大量内存
  4. __eq__将是反身的和对称的,但不是传递的。此外,两个项目可能__eq__返回 true,但具有不同的哈希值。
  5. 同上。不确定性能。
  6. 还不清楚如何实施。

我的哪些想法是好的,哪些是坏的?我错过了什么明显的方式吗?

python 集合 运算符 交集 相等

评论


答:

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 中删除。

我无法尝试这个,我希望这能帮助你或给你新的想法。

类变量似乎不需要是字典,但字典速度非常快。