Skip to content

SuperPoint and LightGlue #7

Merged
ismukhin merged 8 commits intoitlab-vision:mainfrom
SimonovDmitry:superpoint-lightglue
Apr 14, 2026
Merged

SuperPoint and LightGlue #7
ismukhin merged 8 commits intoitlab-vision:mainfrom
SimonovDmitry:superpoint-lightglue

Conversation

@SimonovDmitry
Copy link
Copy Markdown
Contributor

No description provided.

Comment on lines +68 to +70
raw_kp = processed['keypoints'].cpu().numpy()
raw_scores = processed['scores'].cpu().numpy()
raw_des = processed['descriptors'].cpu().numpy().astype(np.float32)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вот здесь тонкий момент: возможно в какой-то момент захочется запускать инференс этих моделей на GPU, поэтому нужно будет сделать внешний параметр cpu или gpu, чтобы корректно управлять тензорами

Comment on lines +96 to +100
def detect(self, img):
return self._forward(img)[0]

def compute(self, img, kp):
model_kp, model_des = self._forward(img)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вроде обговаривали, что мы не инферим модель 2 раза. Мы проход по сетке делаем один раз и сохраняем результат в переменную, потом просто этот результат возвращаем (detect инферит, а compute возвращает ранее посчитанные дескрипторы). Только нужно будет подумать как создавать один и тот же экземпляр класса в 2 разных переменных

@pytest.fixture
def load_img():
def _load(name, color=True):
path = Path(__file__).parent.parent / "test_data" / name
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Здесь надо использовать os.path.join(...) для склеивания путей.

src/matchers.py Outdated

@abstractmethod
def _simple_match(self, des1, des2):
def match(self, **kwargs):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вместо **kwargs передаем словарь.

src/matchers.py Outdated
super().__init__(logger, matcher_name, descriptor_name)
self.mode = mode

def match(self, **kwargs):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Здесь тоже словарь типа {'des1': ..., 'des2': ...}

src/matchers.py Outdated
bf = self._init_matcher()
return bf.match(des1, des2)
class BFMatcher(OpenCVMatcher):
def __init__(self, logger, matcher_name, descriptor_name, **kwargs):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вместо **kwargs используем словарь

src/matchers.py Outdated
def __init__(self, logger, descriptor_method, mode='simple', **kwargs):
super().__init__(logger, descriptor_method, mode, **kwargs)
class FLANNMatcher(OpenCVMatcher):
def __init__(self, logger, matcher_name, descriptor_name, **kwargs):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

И здесь

Comment on lines +93 to +94
LightGlueMatcher._shared_matchers[matcher_key] = (LightGlue(features=self.extractor_type)
.eval().to(self._device))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Создать только один объект LightGlue

self._device = torch.device(device)
self.extractor_type = extractor_type.lower()

matcher_key = (self.extractor_type, self._device.type)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Удалить

matches01 = self._matcher(input_dict)
matches01 = rbd(matches01)

return matches01["matches"] No newline at end of file
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Нужно вернуть достоверности для соответствий

Comment on lines +77 to +79
kp = [cv.KeyPoint(x=float(p[0]), y=float(p[1]), size=8, response=float(s))
for p, s in zip(raw_kp[mask], raw_scores[mask])]
des = raw_des[mask]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вынести в отдельную функцию/класс PostProcessor в скрипт auxiliary.py перевод точек в формат cv.KeyPoint


def compute(self, img, features):
kp, des = self._forward(img)
return {'kp': kp, 'des': des}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Аналогично ввести флаг состояния

@SimonovDmitry
Copy link
Copy Markdown
Contributor Author

@ismukhin Исправили код, все тесты проходят, позапускали все алгоритмы, все работает.



def build_detector_config(args):
config = {}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dict()



def build_descriptor_config(args):
config = {}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dict()



def build_matcher_config(args):
config = {}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dict()



def build_preprocessor_config(args):
config = {}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dict()

def build_preprocessor_config(args):
config = {}
if args.pre_device is not None:
config['device'] = args.pre_device
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Непонятно зачем здесь device, нужно гарантировать, что все операции выполняются на одном устройстве

@@ -0,0 +1,85 @@
import cv2 as cv
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lightglue_pipeline.py

if algo in self._VALID_FORMATS:
return algo

if algo in NEURAL_ALGORITHMS:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DNN_{всё остальное}

from src.converter import Converter


class PreProcessor:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Preprocessor

else:
self._device = torch.device(device)

if SuperPoint._shared_model is None:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SuperPoint._model

self._device = torch.device(device)

if SuperPoint._shared_model is None:
SuperPoint._shared_processor = AutoImageProcessor.from_pretrained(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SuperPoint._image_processor

@ismukhin ismukhin merged commit b2f3e36 into itlab-vision:main Apr 14, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants