Files
World-UAV-ds/README.md
Pikaliov 4ff36ce188 Initial import: World-UAV prepro
Add dataloaders (v1/v2), analysis scripts, and documentation for working with UAV-GeoLoc (World-UAV).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-09 12:44:49 +03:00

7.9 KiB
Raw Blame History

World-UAV-prepro

Эта папка — мой слой препроцесса/аналитики поверх датасета UAV-GeoLoc (World-UAV).

Здесь нет обучения моделей. Основные артефакты:

  • dataloader.py: компактный PyTorch Dataset/DataLoader для train/eval по индекс-файлам Index/*.txt.
  • dataloader_v2.py: расширенная версия лоадера с парсингом метаданных (height/rotation), утилитами GPS/локализационной ошибки и scene-based лоадером для кастомных сплитов.
  • analyze/: оффлайн-скрипты, которые проверяют структуру датасета, схему нарезки спутника, и генерируют графики/примерные картинки.

Формат данных (ожидаемая структура датасета)

Оба лоадера предполагают, что корень датасета (root) выглядит примерно так:

<root>/
  Country/...
  Terrain/...
  Rot/...
  Index/
    train_query.txt
    train_db.txt
    val_query.txt
    val_db.txt
    test_query.txt
    test_db.txt
    ... и варианты *_country.txt, *_all.txt

На уровне сцены (примерно):

<root>/Terrain/<TerrainType>/<SceneName>/
  positive.json
  semi_positive.json
  DB/
    merge.tif
    db_postion.txt
    img/crop_X_Y.png
  query/
    height100_rot0/footage/*.jpeg
    ...

Index-файлы (ключевой интерфейс)

DB index (*_db*.txt)

По 1 пути на строку, путь относительно root:

Terrain/Mountain/Andes/DB/img/crop_0_0.png
Terrain/Mountain/Andes/DB/img/crop_0_1.png
...

Query index (*_query*.txt)

Формат строки:

<query_path> <scene_label_int> <positive_db_1> [positive_db_2 ...]

Пример:

Terrain/Mountain/Andes/query/height100_rot0/footage/height100_rot0_00.jpeg 12 Terrain/Mountain/Andes/DB/img/crop_10_7.png Terrain/Mountain/Andes/DB/img/crop_10_8.png

Важно: в путях могут встречаться пробелы (в вариантах/папках). Парсер в обоих лоадерах извлекает DB-пути по паттерну */DB/img/crop_*.png, а label берёт как последний числовой токен перед DB-путями.

dataloader.py (базовый)

Что даёт

  • Train:
    • UAVGeoLocTrain: (query, positive, negative) triplets (негатив берётся случайно из train_db.txt, исключая positives этого scene label).
    • UAVGeoLocPair: (query, positive) пары (под contrastive без explicit negative).
  • Eval:
    • UAVGeoLocEval(mode="query"): одиночные query-изображения + label + список positives.
    • UAVGeoLocEval(mode="db"): одиночные DB-изображения.
    • eval_collate_fn: collate, который оставляет positives списком (variable-length).
  • build_dataloaders(...): собирает набор лоадеров на train/val/test.

Мини-пример использования

from dataloader import build_dataloaders

root = "/path/to/UAV-GeoLoc"
loaders = build_dataloaders(root, split="terrain", batch_size=32, img_size=512, num_workers=4, mode="triplet")

batch = next(iter(loaders["train"]))
print(batch["query"].shape, batch["positive"].shape, batch["negative"].shape, batch["label"])

dataloader_v2.py (расширенный)

Отличия от базовой версии

  • Метаданные query:
    • парсит height и rotation из пути вида height125_rot270/....
    • возвращает их в батчах train/eval.
  • GPS / локализационная ошибка:
    • load_db_positions(...), haversine_m(...)
    • compute_localization_error(...): метрики ошибки в метрах по retrieval predictions (top-1 индексы DB).
  • Утилита нарезки спутника:
    • tile_satellite_image(...): генерирует кропы в стиле UAV-GeoLoc (stride по умолчанию crop_size // 2).
  • Scene-based loader:
    • UAVGeoLocScene(scene_dir=...): читает сцену напрямую из папки (без Index/*.txt), удобно для кастомных выборок/проверок (в т.ч. Rot subset).
    • build_rot_loader(...): convenience лоадер для Rot/SouthernSuburbs.

Мини-пример: посчитать error (м) по top-1 предсказаниям

import numpy as np
from dataloader_v2 import build_dataloaders, compute_localization_error

root = "/path/to/UAV-GeoLoc"
loaders = build_dataloaders(root, split="terrain", batch_size=64, img_size=224, num_workers=4, mode="triplet")
q_ds = loaders["test_query"].dataset
d_ds = loaders["test_db"].dataset

# допустим, у вас есть top1 predictions как индексы DB:
pred = np.zeros(len(q_ds), dtype=np.int64)
stats = compute_localization_error(q_ds, d_ds, pred)
print(stats["mean_error_m"], stats["median_error_m"], stats["num_evaluated"])

Какой лоадер использовать

  • Бери dataloader.py, если тебе нужен минимальный, предсказуемый интерфейс:
    • train triplets/pairs
    • eval query/db
    • без метаданных и без геометрии/географии
  • Бери dataloader_v2.py, если:
    • в модели/логах важно height и rotation (например, для condition/аблаций)
    • хочешь считать ошибку локализации в метрах (по db_postion.txt)
    • нужно грузить сцены напрямую из папки (без Index/*.txt) или работать с Rot subset
    • нужен helper для tiling спутника tile_satellite_image(...)

На практике: для базовых retrieval-экспериментов достаточно dataloader.py, а v2 — когда переходишь к “исследовательским” метрикам/контролю условий.

Какие Index/*.txt ожидаются для terrain/country/all

Оба лоадера используют один и тот же принцип: в Index/ лежат файлы вида:

  • train_query*.txt, train_db*.txt
  • val_query*.txt, val_db*.txt
  • test_query*.txt, test_db*.txt

Суффиксы:

  • terrain: суффикс пустой (train_query.txt, train_db.txt, …)
  • country: суффикс _country (train_query_country.txt, …)
  • all: суффикс _all (train_query_all.txt, …)

Fallback-логика в build_dataloaders

В dataloader.py и dataloader_v2.py build_dataloaders(...) делает сборку так:

  • train: берёт строго Index/train_query{suffix}.txt и Index/train_db{suffix}.txt для выбранного split
  • val/test:
    • сначала пытается открыть Index/{phase}_query{suffix}.txt / Index/{phase}_db{suffix}.txt
    • если этих файлов нет, откатывается на несуффиксные Index/{phase}_query.txt / Index/{phase}_db.txt

Это удобно, если у тебя, например, train_*_country.txt есть, а val_*_country.txt ещё не сгенерен.

analyze/ (оффлайн анализ датасета)

Скрипты ориентированы на запуск “как есть”, но почти везде нужно поменять BASE/ROOT (путь к датасету).

Подробности см. analyze/README.md.