Skip to content

Commit 07f161c

Browse files
committed
2 parents d188cae + d5e9342 commit 07f161c

23 files changed

Lines changed: 4518 additions & 58 deletions

.DS_Store

8 KB
Binary file not shown.

.gitignore

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,4 +153,9 @@ dmypy.json
153153
cython_debug/
154154
data/
155155

156-
.DS_Store
156+
.DS_Store
157+
158+
# Exclude not needed notebooks files
159+
notebooks/exploration.ipynb
160+
notebooks/class_template.ipynb
161+
notebooks/few_shot_approaches_setup.ipynb

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ repos:
5959
#Automatic linting fixes
6060
types_or: [ python, pyi, jupyter ]
6161
args: [ --fix ]
62-
stages: [manual]
62+
#stages: [manual]
6363
- id: ruff-format
6464
types_or: [ python, pyi, jupyter ]
65-
stages: [manual]
65+
#stages: [manual]

data/.DS_Store

6 KB
Binary file not shown.

data/generate_pv_masks.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import numpy as np
2+
from PIL import Image
3+
from pathlib import Path
4+
5+
def extract_pv_masks(
6+
src_dir: Path,
7+
dst_dir: Path,
8+
pv_class: int = 0,
9+
background_value: int = 255
10+
):
11+
"""
12+
Extract masks that contain PV modules (class 0) and save a cleaned PV-only mask.
13+
14+
Parameters
15+
----------
16+
src_dir : Path
17+
Directory containing original RID superstructure masks.
18+
dst_dir : Path
19+
Output directory for pv-only masks.
20+
pv_class : int, optional
21+
Class index representing PV modules (default: 0).
22+
background_value : int, optional
23+
Value used for non-PV pixels in the output mask (default: 255 for easy visualization).
24+
"""
25+
dst_dir.mkdir(parents=True, exist_ok=True)
26+
27+
mask_files = list(src_dir.glob("*.png"))
28+
29+
print(f"Found {len(mask_files)} masks to inspect...")
30+
count_saved = 0
31+
32+
for mask_path in mask_files:
33+
mask = np.array(Image.open(mask_path))
34+
35+
# Check whether PV class exists
36+
if pv_class not in np.unique(mask):
37+
continue # skip masks without PV
38+
39+
# Create PV-only mask
40+
pv_mask = np.where(mask == pv_class, pv_class, background_value).astype(np.uint8)
41+
42+
# Save to new directory
43+
out_path = dst_dir / mask_path.name
44+
Image.fromarray(pv_mask).save(out_path)
45+
count_saved += 1
46+
47+
print(f"Saved {count_saved} PV-only masks to: {dst_dir}")
48+
49+
if __name__ == "__main__":
50+
BASE_DIR = Path(__file__).resolve().parent
51+
SRC_MASK_DIR = BASE_DIR / "masks_superstructures_reviewed"
52+
DST_PV_MASK_DIR = BASE_DIR / "masks_pv_modules_only"
53+
54+
extract_pv_masks(
55+
src_dir=SRC_MASK_DIR,
56+
dst_dir=DST_PV_MASK_DIR,
57+
pv_class=0,
58+
background_value=255, # white background for visualization
59+
)

data/load_rid_data.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Minimal setup script for the RID dataset.
4+
5+
Place this script in your `data/` directory and run:
6+
7+
python setup_rid_data_minimal.py
8+
9+
It will:
10+
- rsync ONLY:
11+
- images_roof_centered_geotiff
12+
- masks_superstructures_reviewed
13+
from the TUM server
14+
- download them directly into THIS folder (data/)
15+
- skip downloading if the folder already exists and is non-empty
16+
"""
17+
18+
import subprocess
19+
from pathlib import Path
20+
21+
SERVER = "rsync://m1655470@dataserv.ub.tum.de/m1655470"
22+
BASE_DIR = Path(__file__).resolve().parent # data/
23+
DATA_DIR = BASE_DIR
24+
25+
FOLDERS = [
26+
"images_roof_centered_geotiff",
27+
"masks_superstructures_reviewed",
28+
]
29+
30+
31+
def folder_has_data(path: Path) -> bool:
32+
"""Return True if folder exists and contains at least one file."""
33+
return path.exists() and any(path.iterdir())
34+
35+
36+
def rsync_folder(remote_name: str):
37+
"""Rsync a single folder from the server into DATA_DIR."""
38+
dst = DATA_DIR / remote_name
39+
40+
# Skip if already present and non-empty
41+
if folder_has_data(dst):
42+
print(f"✔ Skipping '{remote_name}' — folder already exists and is not empty.")
43+
return
44+
45+
# Ensure directory exists
46+
dst.mkdir(parents=True, exist_ok=True)
47+
48+
src = f"{SERVER}/{remote_name}/"
49+
cmd = [
50+
"rsync",
51+
"-av",
52+
"--progress",
53+
src,
54+
str(dst) + "/", # ensure trailing slash
55+
]
56+
57+
print(f">>> Downloading '{remote_name}' from server...")
58+
print(" ", " ".join(cmd))
59+
print(">>> You may be asked for the password (m1655470).")
60+
61+
try:
62+
subprocess.run(cmd, check=True)
63+
except FileNotFoundError:
64+
raise SystemExit("ERROR: rsync not found. Please install rsync and try again.")
65+
except subprocess.CalledProcessError as e:
66+
raise SystemExit(f"ERROR: rsync for {remote_name} failed with exit code {e.returncode}.")
67+
68+
69+
def main():
70+
print("=== Minimal RID dataset setup (only 2 folders, with existence check) ===")
71+
print(f"Data directory: {DATA_DIR}")
72+
print()
73+
74+
for folder in FOLDERS:
75+
rsync_folder(folder)
76+
print()
77+
78+
print("=== Done! ===")
79+
print("Folders now present:")
80+
for folder in FOLDERS:
81+
print(" •", DATA_DIR / folder)
82+
83+
84+
if __name__ == "__main__":
85+
main()

docs/tutorial_few_shot_learning.html

Lines changed: 526 additions & 23 deletions
Large diffs are not rendered by default.

notebooks/rid_roof_segments.ipynb

Lines changed: 130 additions & 0 deletions
Large diffs are not rendered by default.

notebooks/try_few_shot.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1440,7 +1440,7 @@
14401440
"name": "python",
14411441
"nbconvert_exporter": "python",
14421442
"pygments_lexer": "ipython3",
1443-
"version": "3.11.14"
1443+
"version": "3.10.19"
14441444
}
14451445
},
14461446
"nbformat": 4,

0 commit comments

Comments
 (0)