From cf455cd0f38bb03e5ed47e9d899eca99566d1180 Mon Sep 17 00:00:00 2001 From: pikaliov Date: Sat, 18 Apr 2026 02:41:29 +0300 Subject: [PATCH] Update docs: target-size 512, dataset generated - Drone images now 512x512 (not 256x256) - Satellite crops saved at native 512x512 (no downscale) - Dataset generated: 25 GB on disk - Added known issue: 6 drones in route 06 outside satellite coverage Co-Authored-By: Claude Opus 4.6 (1M context) --- CLAUDE.md | 11 +++++++++-- README.md | 18 ++++++++++++++---- .../prepare_dataset.cpython-312.pyc | Bin 0 -> 23549 bytes 3 files changed, 23 insertions(+), 6 deletions(-) create mode 100644 scripts/__pycache__/prepare_dataset.cpython-312.pyc diff --git a/CLAUDE.md b/CLAUDE.md index f0207cc..9ab2543 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -7,8 +7,9 @@ - **Статус:** выполнен, данные готовы (2026-04-17) ## Результаты обработки -- Drone: 6,744 изображений resized 256x256 -- Satellite кропов: 74,807 (512x512 -> 256x256) +- Drone: 6,744 изображений resized 512x512 +- Satellite кропов: 74,807 (512x512, без downscale) +- Размер на диске: 25 GB - Train queries: 5,060 / Test queries: 1,684 - Gallery: 74,807 кропов (одинаковая для train и test) - Median distance drone->crop: 25.9m, P99: 45.7m @@ -36,5 +37,11 @@ - 6 drone в маршруте 06 (06_0093-06_0098) за пределами спутниковой карты (distance >1000m) - Нет val split (только train/test как в оригинальном UAV-VisLoc) +## Разрешение +- Drone: 512x512 (resize из 3976x2652 / 3000x2000) +- Satellite crops: 512x512 (нарезка без downscale, сохраняют полное разрешение) +- Resize до 224/256 для модели — в dataloader, не на диске +- Разрешение 512 выбрано для downstream задач: сегментация, depth, normals, canopy height + ## GSD спутника ~0.30 м/px (единый zoom level). Вариации GSD по долготе (0.23-0.27 м/px) — косинусный эффект широты, не разная высота съёмки. diff --git a/README.md b/README.md index 1d3db57..f4fa4c7 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,8 @@ compatible with UAV-GeoLoc format. ``` UAV_VisLoc_dataset/ UAV_VisLoc_processed/ ├── 01/ ├── 01/ -│ ├── drone/*.JPG (3976x2652) ---> │ ├── drone/*.JPG (256x256) -│ ├── satellite01.tif ---> │ ├── DB/img/crop_X_Y.png (256x256) +│ ├── drone/*.JPG (3976x2652) ---> │ ├── drone/*.JPG (512x512) +│ ├── satellite01.tif ---> │ ├── DB/img/crop_X_Y.png (512x512) │ └── 01.csv │ ├── DB/db_postion.txt │ │ ├── positive.json ├── ... │ └── semi_positive.json @@ -43,9 +43,9 @@ python scripts/prepare_dataset.py --src ... --dst ... --routes 01 02 03 ## Steps -1. **Resize drone images** -> 256x256 JPEG (quality=95) +1. **Resize drone images** -> 512x512 JPEG (quality=95) 2. **Stitch satellite tiles** for route 09 (4 tiles -> 44800x33280) -3. **Crop satellite maps** -> 512x512 patches, stride 256 (50% overlap), resize -> 256x256 PNG +3. **Crop satellite maps** -> 512x512 patches, stride 256 (50% overlap), saved as 512x512 PNG 4. **Compute GPS** for each crop center from satellite bbox + grid position 5. **Match drone -> crops** via vectorized haversine (positive = closest, semi-positive = +-1 in grid) 6. **Write metadata**: positive.json, semi_positive.json, db_postion.txt (per route) @@ -107,6 +107,16 @@ Columns: name, longitude, latitude, scale_lon (deg/px), scale_lat (deg/px). | **Total** | **6,744** | **74,807** | | | Split: 5,060 train / 1,684 test queries. Gallery: 74,807 crops (shared). +Disk size: **25 GB**. + +## Image Resolution + +All images stored at **512x512** on disk: +- Drone: resized from 3976x2652 / 3000x2000 -> 512x512 +- Satellite crops: cut at 512x512 from satellite map, no downscale + +Resolution 512 chosen to support downstream tasks (segmentation, depth, normals, canopy height). +Resize to 224/256 for model input should be done in the dataloader, not on disk. ## GPS Matching Quality diff --git a/scripts/__pycache__/prepare_dataset.cpython-312.pyc b/scripts/__pycache__/prepare_dataset.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..23d07bb1cdcae1b34cd8b89dafef40ef39d12266 GIT binary patch literal 23549 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 literal 0 HcmV?d00001