Download code/prep.py from fnruha0921/knps-change-detection-tmp: direct link, hf CLI and curl.
- Browser
- Download file 3.08 kB
-
https://huggingface.co/fnruha0921/knps-change-detection-tmp/resolve/main/code/prep.py
- Command line
-
hf download hf://fnruha0921/knps-change-detection-tmp/code/prep.py
-
curl -L -o prep.py https://huggingface.co/fnruha0921/knps-change-detection-tmp/resolve/main/code/prep.py
3.08 kB
| """Resample HF single-date datasets to ~0.55-0.65 m/px and pack into npy arrays. | |
| FLAIR (0.2 m, 512^2) -> 192^2 (~0.53 m/px). classes: 1 building, 18 greenhouse -> building; | |
| 6 conifer, 7 deciduous, 16 mixed, 17 ligneous -> tree; 2,4,10,11,12,15 -> ground donors. | |
| OAM-TCD (0.1 m, 2048^2) -> 320^2 (0.64 m/px). annotation > 0 -> tree. | |
| """ | |
| import glob | |
| import io | |
| import os | |
| from concurrent.futures import ProcessPoolExecutor | |
| import cv2 | |
| import numpy as np | |
| import pyarrow.parquet as pq | |
| import tifffile | |
| from PIL import Image | |
| OUT = "/workspace/prep" | |
| os.makedirs(OUT, exist_ok=True) | |
| BUILD = [1, 18] | |
| TREE = [6, 7, 16, 17] | |
| GROUND = [2, 4, 10, 11, 12, 15] | |
| def flair_one(img_path): | |
| msk_path = img_path.replace("/aerial/", "/labels/").replace("IMG_", "MSK_") | |
| if not os.path.exists(msk_path): | |
| cand = glob.glob(os.path.join(os.path.dirname(img_path).replace("img", "msk"), "MSK_" + img_path.split("IMG_")[-1])) | |
| if not cand: | |
| return None | |
| msk_path = cand[0] | |
| im = tifffile.imread(img_path) | |
| if im.shape[0] in (4, 5): | |
| im = np.transpose(im, (1, 2, 0)) | |
| rgb = np.ascontiguousarray(im[..., :3]).astype(np.uint8) | |
| m = tifffile.imread(msk_path) | |
| if m.ndim == 3: | |
| m = m[0] if m.shape[0] < m.shape[-1] else m[..., 0] | |
| rgb = cv2.resize(rgb, (192, 192), interpolation=cv2.INTER_AREA) | |
| lab = np.zeros(m.shape, np.uint8) | |
| lab[np.isin(m, TREE)] = 2 | |
| lab[np.isin(m, GROUND)] = 3 | |
| lab[np.isin(m, BUILD)] = 1 | |
| lab = cv2.resize(lab, (192, 192), interpolation=cv2.INTER_NEAREST) | |
| return rgb, lab | |
| def main(): | |
| imgs = sorted(glob.glob("/workspace/data/flair/unz/**/IMG_*.tif", recursive=True)) | |
| print("flair imgs", len(imgs), flush=True) | |
| with ProcessPoolExecutor(48) as ex: | |
| res = [r for r in ex.map(flair_one, imgs, chunksize=32) if r is not None] | |
| fx = np.stack([r[0] for r in res]); fy = np.stack([r[1] for r in res]) | |
| np.save(f"{OUT}/flair_x.npy", fx); np.save(f"{OUT}/flair_y.npy", fy) | |
| print("flair", fx.shape, "building frac", (fy == 1).mean(), "tree frac", (fy == 2).mean(), flush=True) | |
| xs, ys = [], [] | |
| for f in sorted(glob.glob("/workspace/data/tcd/data/train-*.parquet")): | |
| t = pq.read_table(f, columns=["image", "annotation"]).to_pylist() | |
| for row in t: | |
| im = np.asarray(Image.open(io.BytesIO(row["image"]["bytes"])).convert("RGB")) | |
| an = np.asarray(Image.open(io.BytesIO(row["annotation"]["bytes"]))) | |
| if an.ndim == 3: | |
| an = an[..., 0] | |
| s = 320 * max(im.shape[:2]) // 2048 | |
| xs.append(cv2.resize(im, (s, s), interpolation=cv2.INTER_AREA) if s == 320 else cv2.resize(im, (320, 320), interpolation=cv2.INTER_AREA)) | |
| ys.append(cv2.resize(((an > 0) * 2).astype(np.uint8), (320, 320), interpolation=cv2.INTER_NEAREST)) | |
| print(f, len(xs), flush=True) | |
| tx = np.stack(xs); ty = np.stack(ys) | |
| np.save(f"{OUT}/tcd_x.npy", tx); np.save(f"{OUT}/tcd_y.npy", ty) | |
| print("tcd", tx.shape, "tree frac", (ty == 2).mean(), flush=True) | |
| if __name__ == "__main__": | |
| main() | |