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>
This commit is contained in:
117
analyze/analyze_crop_scheme.py
Normal file
117
analyze/analyze_crop_scheme.py
Normal file
@@ -0,0 +1,117 @@
|
||||
"""
|
||||
Анализ схемы нарезки спутниковых снимков в датасете UAV-GeoLoc.
|
||||
|
||||
Скрипт определяет crop_size, stride и overlap для каждой сцены,
|
||||
сопоставляя кропы с исходным merge.tif через попиксельное сравнение.
|
||||
|
||||
Результат: stride = crop_size // 2 (50% overlap) для всех сцен.
|
||||
Naming: crop_X_Y.png — X по ширине (col), Y по высоте (row).
|
||||
Позиция в merge.tif: merge[Y*stride : Y*stride+crop_size, X*stride : X*stride+crop_size]
|
||||
"""
|
||||
|
||||
import glob
|
||||
import os
|
||||
|
||||
import numpy as np
|
||||
from PIL import Image
|
||||
|
||||
Image.MAX_IMAGE_PIXELS = None # некоторые merge.tif очень большие
|
||||
|
||||
|
||||
def analyze_scene(scene_db_dir: str) -> dict:
|
||||
"""Определяет параметры нарезки для одной сцены.
|
||||
|
||||
Args:
|
||||
scene_db_dir: путь к папке DB сцены (содержит merge.tif и img/).
|
||||
|
||||
Returns:
|
||||
dict с ключами: merge_size, crop_size, grid, stride, overlap.
|
||||
"""
|
||||
merge_path = os.path.join(scene_db_dir, "merge.tif")
|
||||
img_dir = os.path.join(scene_db_dir, "img")
|
||||
|
||||
merge = np.array(Image.open(merge_path))
|
||||
mh, mw = merge.shape[:2]
|
||||
|
||||
# Размер кропа
|
||||
c00 = np.array(Image.open(os.path.join(img_dir, "crop_0_0.png")))
|
||||
ch, cw = c00.shape[:2]
|
||||
|
||||
# Размер сетки
|
||||
crops = os.listdir(img_dir)
|
||||
xs, ys = [], []
|
||||
for name in crops:
|
||||
parts = name.replace("crop_", "").replace(".png", "").split("_")
|
||||
xs.append(int(parts[0]))
|
||||
ys.append(int(parts[1]))
|
||||
grid_x, grid_y = max(xs) + 1, max(ys) + 1
|
||||
|
||||
# Проверяем что crop_0_0 начинается с (0, 0)
|
||||
assert np.array_equal(c00, merge[0:ch, 0:cw, :3]), "crop_0_0 не совпадает с merge[0:ch, 0:cw]"
|
||||
|
||||
# Ищем stride по X: сдвигаем crop_1_0 вдоль ширины merge
|
||||
c10 = np.array(Image.open(os.path.join(img_dir, "crop_1_0.png")))
|
||||
stride_x = None
|
||||
for s in range(1, cw + 1):
|
||||
if s + cw <= mw and np.array_equal(c10, merge[0:ch, s:s + cw, :3]):
|
||||
stride_x = s
|
||||
break
|
||||
assert stride_x is not None, "Не удалось найти stride по X"
|
||||
|
||||
# Ищем stride по Y: сдвигаем crop_0_1 вдоль высоты merge
|
||||
c01 = np.array(Image.open(os.path.join(img_dir, "crop_0_1.png")))
|
||||
stride_y = None
|
||||
for s in range(1, ch + 1):
|
||||
if s + ch <= mh and np.array_equal(c01, merge[s:s + ch, 0:cw, :3]):
|
||||
stride_y = s
|
||||
break
|
||||
assert stride_y is not None, "Не удалось найти stride по Y"
|
||||
|
||||
return {
|
||||
"merge_size": (mw, mh),
|
||||
"crop_size": (cw, ch),
|
||||
"grid": (grid_x, grid_y),
|
||||
"stride": (stride_x, stride_y),
|
||||
"overlap": (cw - stride_x, ch - stride_y),
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
base = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
patterns = [
|
||||
os.path.join(base, "Country", "*", "*", "*", "DB"),
|
||||
os.path.join(base, "Terrain", "*", "*", "DB"),
|
||||
]
|
||||
|
||||
scene_dirs = []
|
||||
for pat in patterns:
|
||||
scene_dirs.extend(sorted(glob.glob(pat)))
|
||||
|
||||
print(f"{'Scene':<50} {'merge WxH':>14} {'crop':>8} {'grid':>8} {'stride':>8} {'overlap':>8}")
|
||||
print("-" * 100)
|
||||
|
||||
for scene_db in scene_dirs:
|
||||
if not os.path.isfile(os.path.join(scene_db, "merge.tif")):
|
||||
continue
|
||||
|
||||
# Короткое имя сцены
|
||||
rel = os.path.relpath(scene_db, base)
|
||||
name = rel.replace("/DB", "")
|
||||
|
||||
try:
|
||||
info = analyze_scene(scene_db)
|
||||
mw, mh = info["merge_size"]
|
||||
cw, ch = info["crop_size"]
|
||||
gx, gy = info["grid"]
|
||||
sx, sy = info["stride"]
|
||||
ox, oy = info["overlap"]
|
||||
print(
|
||||
f"{name:<50} {mw:>6}x{mh:<6} {cw:>3}x{ch:<4} {gx:>3}x{gy:<4} {sx:>3}x{sy:<4} {ox:>3}x{oy:<4}"
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"{name:<50} ERROR: {e}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user