Instructions to use MingzhenL/vessa-2d-ssl-bundle with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- sam2
How to use MingzhenL/vessa-2d-ssl-bundle with sam2:
# Use SAM2 with images import torch from sam2.sam2_image_predictor import SAM2ImagePredictor predictor = SAM2ImagePredictor.from_pretrained("MingzhenL/vessa-2d-ssl-bundle") with torch.inference_mode(), torch.autocast("cuda", dtype=torch.bfloat16): predictor.set_image(<your_image>) masks, _, _ = predictor.predict(<input_prompts>)# Use SAM2 with videos import torch from sam2.sam2_video_predictor import SAM2VideoPredictor predictor = SAM2VideoPredictor.from_pretrained("MingzhenL/vessa-2d-ssl-bundle") with torch.inference_mode(), torch.autocast("cuda", dtype=torch.bfloat16): state = predictor.init_state(<your_video>) # add new prompts and instantly get the output on the same frame frame_idx, object_ids, masks = predictor.add_new_points(state, <your_prompts>) # propagate the prompts to get masklets throughout the video for frame_idx, object_ids, masks in predictor.propagate_in_video(state): ... - Notebooks
- Google Colab
- Kaggle
Download code/VESSA/data_preprocessing/build_template_bank.py from MingzhenL/vessa-2d-ssl-bundle: direct link, hf CLI and curl.
- Browser
- Download file 7.41 kB
-
https://huggingface.co/MingzhenL/vessa-2d-ssl-bundle/resolve/main/code/VESSA/data_preprocessing/build_template_bank.py
- Command line
-
hf download hf://MingzhenL/vessa-2d-ssl-bundle/code/VESSA/data_preprocessing/build_template_bank.py
-
curl -L -o build_template_bank.py https://huggingface.co/MingzhenL/vessa-2d-ssl-bundle/resolve/main/code/VESSA/data_preprocessing/build_template_bank.py
7.41 kB
| #!/usr/bin/env python3 | |
| """ | |
| Build a template bank (template/*.npz + template_summary.json) for a raw dataset, | |
| matching the schema used by existing <name>_10percent_processed directories. | |
| Inputs: | |
| A raw dataset dir of the form: | |
| <source_dir>/ | |
| dataset_info.json (must contain "dataset_name" and ideally "modality" and "classes"/"class_mapping") | |
| train/images/ (*.jpg | *.png | *.jpeg) | |
| train/masks/ (matching *.png masks) | |
| Outputs: | |
| <output_dir>/ | |
| template/ | |
| {stem}.npz one per chosen sample, with keys: | |
| - template_image uint8 [H, W, 3] (NATIVE image size, no resize) | |
| - template_mask uint8 [H, W] (multi-class, 0 = background) | |
| - cls_feature float32 [384] (DINOv2-vits14 CLS, cosine-normalized) | |
| - classes int64 [K] (non-bg class ids present in this mask) | |
| - original_size int64 [W, H] | |
| - modality unicode str (from dataset_info.json, else "Unknown") | |
| template_summary.json index of all templates with metadata | |
| Selection: | |
| ratio × N_train samples are drawn uniformly at random from train/images, seeded by --seed. | |
| Each chosen sample is ALSO a valid SFT target sample (bank ⊂ train). No disjointness. | |
| """ | |
| import argparse | |
| import json | |
| import os | |
| import random | |
| import sys | |
| from pathlib import Path | |
| import cv2 | |
| import numpy as np | |
| from PIL import Image | |
| THIS_DIR = Path(__file__).resolve().parent | |
| VESSA_ROOT = THIS_DIR.parent | |
| TRAIN_VESSA = VESSA_ROOT / "train_vessa" | |
| if str(TRAIN_VESSA) not in sys.path: | |
| sys.path.insert(0, str(TRAIN_VESSA)) | |
| IMAGE_EXTS = (".jpg", ".jpeg", ".png") | |
| MASK_EXTS = (".png", ".jpg", ".jpeg") | |
| def _list_stems(root: str, exts): | |
| if not os.path.isdir(root): | |
| return [] | |
| stems = [] | |
| for name in sorted(os.listdir(root)): | |
| low = name.lower() | |
| if any(low.endswith(e) for e in exts): | |
| stems.append(os.path.splitext(name)[0]) | |
| return stems | |
| def _path_for_stem(root: str, stem: str, exts): | |
| for name in os.listdir(root): | |
| base, ext = os.path.splitext(name) | |
| if base == stem and any(name.lower().endswith(e) for e in exts): | |
| return os.path.join(root, name) | |
| return None | |
| def _load_dataset_info(source_dir: str): | |
| info_path = os.path.join(source_dir, "dataset_info.json") | |
| if not os.path.isfile(info_path): | |
| raise FileNotFoundError(f"dataset_info.json not found in {source_dir}") | |
| with open(info_path, "r", encoding="utf-8") as f: | |
| return json.load(f) | |
| def _unique_fg_classes(mask: np.ndarray): | |
| return sorted(int(v) for v in np.unique(mask).tolist() if int(v) != 0) | |
| def _choose_bank_stems(train_img_dir: str, train_mask_dir: str, ratio: float, seed: int): | |
| img_stems = set(_list_stems(train_img_dir, IMAGE_EXTS)) | |
| msk_stems = set(_list_stems(train_mask_dir, MASK_EXTS)) | |
| common = sorted(img_stems & msk_stems) | |
| n_total = len(common) | |
| if n_total == 0: | |
| raise RuntimeError(f"No (image, mask) pairs under {train_img_dir} / {train_mask_dir}") | |
| n_bank = max(1, int(round(n_total * ratio))) | |
| rng = random.Random(seed) | |
| chosen = rng.sample(common, n_bank) | |
| return common, chosen | |
| def build_bank(source_dir: str, output_dir: str, ratio: float, seed: int, | |
| device: str = "cuda:0", model_name: str = "dinov2_vits14"): | |
| # Lazy-import so the module can load without GPU libs when just reading | |
| from template_manager import TemplateManager | |
| info = _load_dataset_info(source_dir) | |
| dataset_name = info.get("dataset_name", os.path.basename(source_dir.rstrip("/"))) | |
| modality = info.get("modality", "Unknown") | |
| train_img_dir = os.path.join(source_dir, "train", "images") | |
| train_mask_dir = os.path.join(source_dir, "train", "masks") | |
| all_stems, chosen_stems = _choose_bank_stems(train_img_dir, train_mask_dir, ratio, seed) | |
| print(f"[build_bank] {dataset_name}: n_train={len(all_stems)} ratio={ratio:.0%} bank_size={len(chosen_stems)}") | |
| template_dir = os.path.join(output_dir, "template") | |
| os.makedirs(template_dir, exist_ok=True) | |
| # DINOv2 feature extractor (cosine-normalized, matches TemplateManager default) | |
| tm = TemplateManager(device=device, model_name=model_name, distance_metric="cosine") | |
| summary = {} | |
| built = 0 | |
| skipped = 0 | |
| for stem in chosen_stems: | |
| img_path = _path_for_stem(train_img_dir, stem, IMAGE_EXTS) | |
| msk_path = _path_for_stem(train_mask_dir, stem, MASK_EXTS) | |
| if img_path is None or msk_path is None: | |
| skipped += 1 | |
| continue | |
| img_bgr = cv2.imread(img_path, cv2.IMREAD_COLOR) | |
| mask = cv2.imread(msk_path, cv2.IMREAD_GRAYSCALE) | |
| if img_bgr is None or mask is None: | |
| skipped += 1 | |
| continue | |
| img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB) | |
| classes = _unique_fg_classes(mask) | |
| if not classes: | |
| # A mask with no foreground is useless as a template. | |
| skipped += 1 | |
| continue | |
| # DINOv2 cls_feature at native resolution (TemplateManager resizes to 224 internally) | |
| cls_feat = tm._extract_feature(Image.fromarray(img_rgb)) | |
| H, W = img_rgb.shape[:2] | |
| out_path = os.path.join(template_dir, stem + ".npz") | |
| np.savez_compressed( | |
| out_path, | |
| template_image=img_rgb.astype(np.uint8), | |
| template_mask=mask.astype(np.uint8), | |
| cls_feature=cls_feat.astype(np.float32), | |
| classes=np.array(classes, dtype=np.int64), | |
| original_size=np.array([W, H], dtype=np.int64), | |
| modality=np.array(modality, dtype="U10"), | |
| ) | |
| summary[stem] = { | |
| "path": out_path, | |
| "original_size": [W, H], | |
| "cls_feature_shape": [int(cls_feat.shape[0])], | |
| "classes": classes, | |
| "modality": modality, | |
| } | |
| built += 1 | |
| summary_path = os.path.join(template_dir, "template_summary.json") | |
| with open(summary_path, "w", encoding="utf-8") as f: | |
| json.dump(summary, f, indent=2) | |
| print(f"[build_bank] {dataset_name}: built={built} skipped={skipped} -> {template_dir}") | |
| return built, skipped | |
| def parse_args(): | |
| p = argparse.ArgumentParser(description="Build a DINOv2-feature template bank at a given ratio.") | |
| p.add_argument("--source_dir", required=True, type=str, | |
| help="Raw dataset root (contains dataset_info.json, train/, val/)") | |
| p.add_argument("--output_dir", required=True, type=str, | |
| help="Output dataset root (e.g. <name>_5percent_processed). template/ will be created under this.") | |
| p.add_argument("--ratio", required=True, type=float, | |
| help="Fraction of train samples to include in the bank (e.g. 0.05, 0.20)") | |
| p.add_argument("--seed", type=int, default=666, | |
| help="Random seed for bank selection. Keep identical across ratios to get nested banks.") | |
| p.add_argument("--device", type=str, default="cuda:0") | |
| p.add_argument("--model_name", type=str, default="dinov2_vits14") | |
| return p.parse_args() | |
| def main(): | |
| args = parse_args() | |
| build_bank( | |
| source_dir=args.source_dir, | |
| output_dir=args.output_dir, | |
| ratio=args.ratio, | |
| seed=args.seed, | |
| device=args.device, | |
| model_name=args.model_name, | |
| ) | |
| if __name__ == "__main__": | |
| main() | |