Пересечение для примерно равных объектов - PullRequest
0 голосов
/ 11 января 2020

Я обнаруживаю объекты на изображениях и пробую разные алгоритмы обнаружения. Я хочу сравнить результаты алгоритмов по моему набору данных. Я сохранил результаты каждого алгоритма в виде списка [filepath, detection_box_coordinates, otherstuff]. Я хотел бы считать два обнаружения одинаковыми, если пути к файлам одинаковы, а перекрытие в полях обнаружения превышает некоторый порог. Я хочу получить для любых двух алгоритмов результаты A и B, списки only_in_A, only_in_B и in_both. Я надеялся найти «один и предпочтительно только один очевидный способ» сделать это, но мои поиски до сих пор дали несколько, не обязательно очевидных способов.

Сосредоточившись на вычислении in_both, я подумал о том, чтобы сделать следующее:

  1. Цикл по каждому элементу каждого списка и сравнение их
  2. Сортировка и разбиение списков по пути к файлу, а затем по каждому пути к файлу, цикл по элементам в каждом списке
  3. [x для x в itertools.product (A, B) и match (x)] с пользовательской функцией сопоставления
  4. Создание класса Detection и определение __eq__ как моей функции сопоставления
  5. Реализация моего собственного класса Intersector, как показано здесь: Python пересечение с пользовательским равенством
  6. Использование лямбда-функции

Прямо сейчас я вижу следующее минусы этих идей:

  1. Очень медленно
  2. Все еще медленнее, чем операции над множествами, и куча кода, который может заново изобретать колесо
  3. Возможно, sl Объем и объем памяти
  4. __eq__ будут рефлексивными и симметричными c, но не транзитивными. Кроме того, два элемента могут иметь __eq__, возвращающую true, но иметь разные хэши.
  5. То же, что и выше. Не уверен насчет производительности.
  6. Пока не имею четкого представления о том, как реализовать.

Какие из моих идей хороши или ужасны? Есть ли очевидный способ, которым я скучаю?

1 Ответ

0 голосов
/ 12 января 2020

Я думаю, что класс 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.

Я не смог попробовать это надеюсь, это поможет или даст вам новые идеи.

Переменные класса не обязательно должны быть словарями, но словари действительно быстрые.

...