pasma / examples /classify.py
Prikol5ist's picture
Publish Pasma v1.0 candidates, model card and complete benchmark evidence
028c4b5 verified
Raw History Blame Contribute Delete
2.57 kB
"""Run a bundled Pasma ONNX graph on one local image (no image upload)."""
from __future__ import annotations
import argparse
import json
from pathlib import Path
import numpy as np
import onnxruntime as ort
from PIL import Image, ImageOps
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('image', type=Path)
parser.add_argument('--model', type=Path, default=Path(__file__).resolve().parents[1] / 'models/pasma_small_320_fp32.onnx')
args = parser.parse_args()
metadata = args.model.parent
labels = json.loads((metadata / 'labels_order.json').read_text())
session = ort.InferenceSession(str(args.model), providers=['CPUExecutionProvider'])
size = session.get_inputs()[0].shape[-1]
with Image.open(args.image) as source:
image = ImageOps.exif_transpose(source).convert('RGB')
scale = size / max(image.size)
image = image.resize(tuple(max(1, round(v * scale)) for v in image.size), Image.Resampling.BILINEAR)
canvas = Image.new('RGB', (size, size), (128, 128, 128))
canvas.paste(image, ((size - image.width) // 2, (size - image.height) // 2))
x = np.asarray(canvas, dtype=np.float32).transpose(2, 0, 1)[None] / 255.0
coarse, types, materials = session.run(['prob_coarse', 'prob_type', 'prob_material'], {'image': x})
top3 = np.argsort(-types[0])[:3]
chosen = labels['garment_types'][int(top3[0])]
# Marginal argmax may differ; use this mapping for the displayed pair.
category = labels['type_to_coarse'][chosen]
prefix_to_run = {'pasma_small_320': 'r4_edgenext_320', 'pasma_nano_256': 'r3_edgenext_s',
'pasma_pico_256': 'r3_convnext_pico'}
run = next(run for prefix, run in prefix_to_run.items() if args.model.stem.startswith(prefix))
thresholds = json.loads((metadata / 'material_thresholds.json').read_text())['thresholds'][run]
suggestions = [{'label': name, 'score': float(materials[0, i])}
for i, name in enumerate(labels['materials'])
if thresholds[name]['fitted'] and materials[0, i] >= thresholds[name]['threshold']]
print(json.dumps({'top3': [{'type': labels['garment_types'][int(i)], 'score': float(types[0, i])}
for i in top3], 'category_for_selected_type': category,
'coarse_marginal_argmax': labels['coarse_categories'][int(coarse[0].argmax())],
'visual_material_suggestions': sorted(suggestions, key=lambda v: -v['score'])}, indent=2))
if __name__ == '__main__':
main()