Spaces:
Sleeping
Sleeping
| import json | |
| from pathlib import Path | |
| from typing import Any, Dict, List, Tuple | |
| # Default candidate labels for CLIP zero-shot (PRD brand list) | |
| DEFAULT_BRAND_CLIP_LABELS: List[str] = [ | |
| "Chanel designer handbag", | |
| "Hermes designer handbag", | |
| "Louis Vuitton designer handbag", | |
| "Gucci designer handbag", | |
| "Fendi designer handbag", | |
| "Prada designer handbag", | |
| "Rolex luxury wristwatch", | |
| "Patek Philippe luxury wristwatch", | |
| "Cartier luxury wristwatch", | |
| "Audemars Piguet luxury wristwatch", | |
| "Monet impressionist oil painting", | |
| "Van Gogh impressionist oil painting", | |
| "Vermeer Dutch golden age painting", | |
| "Rembrandt Dutch golden age painting", | |
| "Faberge ornate jewelled egg or objet", | |
| "Tiffany fine jewellery", | |
| "Van Cleef and Arpels fine jewellery", | |
| ] | |
| DEFAULT_LABEL_TO_BRAND_CATEGORY: Dict[str, Tuple[str, str]] = { | |
| "Chanel designer handbag": ("Chanel", "Handbag"), | |
| "Hermes designer handbag": ("Hermes", "Handbag"), | |
| "Louis Vuitton designer handbag": ("Louis Vuitton", "Handbag"), | |
| "Gucci designer handbag": ("Gucci", "Handbag"), | |
| "Fendi designer handbag": ("Fendi", "Handbag"), | |
| "Prada designer handbag": ("Prada", "Handbag"), | |
| "Rolex luxury wristwatch": ("Rolex", "Watch"), | |
| "Patek Philippe luxury wristwatch": ("Patek Philippe", "Watch"), | |
| "Cartier luxury wristwatch": ("Cartier", "Watch"), | |
| "Audemars Piguet luxury wristwatch": ("Audemars Piguet", "Watch"), | |
| "Monet impressionist oil painting": ("Monet", "Art"), | |
| "Van Gogh impressionist oil painting": ("Van Gogh", "Art"), | |
| "Vermeer Dutch golden age painting": ("Vermeer", "Art"), | |
| "Rembrandt Dutch golden age painting": ("Rembrandt", "Art"), | |
| "Faberge ornate jewelled egg or objet": ("Faberge", "Jewellery"), | |
| "Tiffany fine jewellery": ("Tiffany", "Jewellery"), | |
| "Van Cleef and Arpels fine jewellery": ("Van Cleef", "Jewellery"), | |
| } | |
| BRAND_CONFIDENCE_THRESHOLD = 0.35 | |
| DATA_DIR = Path(__file__).resolve().parent.parent / "data" | |
| BRAND_LABELS_JSON = DATA_DIR / "brand_labels.json" | |
| def _load_brand_assets() -> Tuple[List[str], Dict[str, Tuple[str, str]]]: | |
| if not BRAND_LABELS_JSON.exists(): | |
| return DEFAULT_BRAND_CLIP_LABELS, DEFAULT_LABEL_TO_BRAND_CATEGORY | |
| try: | |
| payload = json.loads(BRAND_LABELS_JSON.read_text(encoding="utf-8")) | |
| clip_labels = payload.get("clip_labels") | |
| mapping = payload.get("label_to_brand_category") | |
| if not isinstance(clip_labels, list) or not isinstance(mapping, dict): | |
| return DEFAULT_BRAND_CLIP_LABELS, DEFAULT_LABEL_TO_BRAND_CATEGORY | |
| # mapping values can come as lists; normalize to tuples. | |
| normalized: Dict[str, Tuple[str, str]] = {} | |
| for k, v in mapping.items(): | |
| if isinstance(v, (list, tuple)) and len(v) == 2: | |
| normalized[str(k)] = (str(v[0]), str(v[1])) | |
| clip_labels2 = [str(x) for x in clip_labels if isinstance(x, (str, int, float))] | |
| if not clip_labels2 or not normalized: | |
| return DEFAULT_BRAND_CLIP_LABELS, DEFAULT_LABEL_TO_BRAND_CATEGORY | |
| return clip_labels2, normalized | |
| except Exception: | |
| return DEFAULT_BRAND_CLIP_LABELS, DEFAULT_LABEL_TO_BRAND_CATEGORY | |
| def identify_object(image, clip_pipe, blip_pipe) -> Dict[str, Any]: | |
| """Layer 2: caption (BLIP) + brand/category (CLIP).""" | |
| caption_result = blip_pipe(image) | |
| caption = caption_result[0]["generated_text"].strip() | |
| brand_clip_labels, label_to_brand_category = _load_brand_assets() | |
| brand_result = clip_pipe(image, candidate_labels=brand_clip_labels) | |
| top3 = brand_result[:3] | |
| top = top3[0] | |
| top_label = top["label"] | |
| top_score = float(top["score"]) | |
| if top_score < BRAND_CONFIDENCE_THRESHOLD: | |
| return { | |
| "caption": caption, | |
| "brand": "Unknown luxury item", | |
| "category": "Unknown", | |
| "confidence": round(top_score, 4), | |
| "alt_guesses": [r["label"] for r in top3], | |
| "clip_label": top_label, | |
| } | |
| brand, category = label_to_brand_category.get( | |
| top_label, (top_label.split()[0], "Unknown") | |
| ) | |
| alt_guesses = [r["label"] for r in top3[1:3]] | |
| return { | |
| "caption": caption, | |
| "brand": brand, | |
| "category": category, | |
| "confidence": round(top_score, 4), | |
| "alt_guesses": alt_guesses, | |
| "clip_label": top_label, | |
| } |