Skip to content

Quality evaluation module and benchmark application#11

Open
SimonovDmitry wants to merge 21 commits into
itlab-vision:mainfrom
SimonovDmitry:quality-evaluation-samples
Open

Quality evaluation module and benchmark application#11
SimonovDmitry wants to merge 21 commits into
itlab-vision:mainfrom
SimonovDmitry:quality-evaluation-samples

Conversation

@SimonovDmitry
Copy link
Copy Markdown
Contributor

No description provided.

@SimonovDmitry
Copy link
Copy Markdown
Contributor Author

@ismukhin Добавил оценку качества на датасете hpatches-release.

@ismukhin
Copy link
Copy Markdown
Contributor

@SimonovDmitry, боюсь, так мы не сможем оценить качество нейросетевых методов, плюсом оценка качества только по дескрипторам будто бы не имеет отношение к задачи сопоставления (хотя в HPatches она именно так и называется).
Тогда меняем тактику: так как есть датасет с фотографиями и истинными гомографиями по ним, то будем оценивать по гомографии. Идея в следующем: запускается процедура детектирования, вычисления дескрипторов, вычисления матчей. Далее по матчам формируем пары точек: (референсное изображение, преобразованное). Так как мы знаем истинную гомографию, то мы сможем посчитать координаты точек, где они должны находиться.
То есть, пусть $(x_i, y_i)^T$ - точки на первом изображении, $(\hat{x}, \hat{y})^T$ - истинные координаты точки на втором. Между ними есть взаимосвязь в однородных координатах: $(\hat{x} * z, \hat{y} * z, z)^T = H(x_i, y_i, 1)^T$.
LightGlue соединит точки так: $(x_i, y_i)^T \rightarrow (\overline{x_i}, \overline{y_i})^T$. Соответственно, мы считаем Евклидово расстояние между точками $(\hat{x}, \hat{y})^T$ и $(\overline{x_i}, \overline{y_i})^T$, если оно НЕ превышает установленный порог (1, 3, 5 px обычно берут), то это TP матч, иначе это FP матч. По ним считаем Precision и MatchingSrore. Последний считается как TP/N, где N -- количество точек, найденных детектором. В MatchingScore важно зафиксировать точки с наибольшим confidence (относительно первого изображения). Тем более, если будем сравниваться с классическими методами, то нужно это учитывать.
Последняя метрика, связанная с оценкой гомографии. Это расскажу на собрании

@SimonovDmitry
Copy link
Copy Markdown
Contributor Author

@ismukhin Поменял датасет на hpatches-sequences-release. Метрика mAP теперь вычисляется с помощью матрицы гомографии после вычисления матчей.

try:
if not args.path.exists():
logger.error(f"Dataset path does not exist: {args.path}")
return 1
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

raise ValueError('...')

Comment thread samples/hpatches_data_manager.py Outdated
Comment thread samples/hpatches_data_manager.py Outdated
scene_dir = self._raw_data_path / scene
self._logger.info(f"Loading {scene_dir}")

ref_path = scene_dir / "1.ppm"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Надо вынести значение константы 1.ppm

}

dataset[scene] = scene_data

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 thread samples/hpatches_task.py Outdated
if seq not in matching_data:
continue

for i in range(2, 7):
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

"Магический" range, который не понятно,откуда берется.

Comment thread samples/hpatches_task.py
import sys
import logging
from pathlib import Path

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.

sys.path.append(...)

Comment thread samples/hpatches_data_manager.py Outdated

h_path = scene_dir / f"H_1_{i}"
if img_target is not None and h_path.exists():
H = np.loadtxt(str(h_path))
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.

Надо посмотреть как парсится матрица из файла

@SimonovDmitry
Copy link
Copy Markdown
Contributor Author

SimonovDmitry commented Apr 30, 2026

@ismukhin Добавил вычисление метрик AUC@npx и MatchingScore, которые вы объяснили на собрании. Про вычисление MatchingScore: посмотрел различные статьи, пришел к выводу, что для нашей задачи подойдет формула MatchingScore = |inliers| / min(|K1|, |K2|), где inliers — это хорошие матчи, у которых евклидово расстояние между точкой, которую выдал наш матчер, и точкой, которую мы получили матрицей гомографии < threshold, а K1 и K2 — точки, которые нашел наш детектор на 1 и 2 изображении

Comment thread samples/hpatches_benchmark.py Outdated
Comment on lines +49 to +50
ds_group.add_argument('-bs', '--batch-size', type=int, default=4,
help='Batch size for processing images/scenes')
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.

Переименовать во что-то другое, так как batch_size связан с входом нейронных сетей

Comment thread samples/hpatches_data_manager.py Outdated

self._raw_data_path = Path(config.pop("raw_data_path", "hpatches-sequences-release"))
self._num_scenes = config.pop("num_scenes", 116)
self._batch_size = config.pop("batch_size", 4)
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.

Тоже переименовать

Comment thread samples/hpatches_data_manager.py Outdated

def _get_all_scenes(self):
scenes = [d for d in self._raw_data_path.iterdir() if d.is_dir()]
scenes.sort()
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.

Проверить целесобразность сортировки, возможно она не нужна

task = HPatchesTask.create(task_name=args.task, logger=logger, config=config['task'])

results = {}
while dm.has_more_data():
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.

Изучить случай, когда размер пачки данных больше размера самого датасета

Comment thread samples/hpatches_task.py Outdated
pts_tgt_gt = cv.perspectiveTransform(pts_ref, H)

distances = np.linalg.norm(pts_tgt_pred - pts_tgt_gt, axis=2).flatten()
labels = (distances <= self.pixel_threshold).astype(int)
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.

Не понятно, зачем преобразование к int

Comment thread samples/hpatches_task.py Outdated
'distances': distances,
'num_kp_ref': len(kp_ref),
'num_matches': len(matches),
'scores': np.array([-m.distance for m in matches])
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.

abs(m.distance)

Comment thread samples/hpatches_task.py Outdated
def report_metrics(self, results, task_name="Feature Matching (mAP)"):
rows = [{'Scene': s, 'mAP': np.mean([m['ap'] for m in r.values()])}
for s, r in results.items() if r]
df = pd.DataFrame(rows).sort_values('mAP', ascending=False)
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.

Скорее всего сортировка здесь тоже не нужна

Comment thread samples/hpatches_task.py Outdated
Comment on lines +217 to +220
accuracies = [np.mean(scene_errors < t) for t in thresholds]

area = np.trapezoid(accuracies, thresholds)
scene_auc = area / self._pixel_threshold
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.

Надо считать по всему датасету, а не по каждой папке в отдельности. Считаем Corner Errors для каждой папки, потом по ним AUC

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