creek

The AI Image Editor of 2030

models/era_cult.py (4409B)


  1"""
  2Era / Cultural Reference
  3Original file: https://colab.research.google.com/drive/15k15A0X38sOgwqGR5j7QhDBS8_61R_ca
  4"""
  5
  6!pip install git+https://github.com/openai/CLIP.git --q
  7!pip install torch torchvision ftfy regex tqdm --q
  8
  9import torch
 10import clip
 11from PIL import Image
 12import numpy as np
 13from google.colab import files
 14import io
 15
 16device = "cuda" if torch.cuda.is_available() else "cpu"
 17print(f"Using device: {device}")
 18
 19model, preprocess = clip.load("ViT-B/32", device=device)
 20
 21ERA_CLASSES = [
 22    "vintage-60s",
 23    "modern",
 24    "90s-magazine",
 25    "art-deco",
 26    "punk",
 27    "avant-garde",
 28]
 29
 30ERA_DESCRIPTIONS = {
 31    "vintage-60s": "1960s aesthetic, psychedelic art, mod fashion, kodachrome film look, flower power era",
 32    "modern": "modern contemporary aesthetic, clean design, digital photography, high resolution, 21st century style",
 33    "90s-magazine": "1990s fashion magazine style, grunge aesthetic, harsh flash photography, teen vogue 90s, glossy editorial",
 34    "art-deco": "art deco style, 1920s geometric patterns, gold and black luxury, great gatsby aesthetic, streamline moderne",
 35    "punk": "punk rock aesthetic, diy zine style, xeroxed textures, safety pins, rebellious and chaotic visual style",
 36    "avant-garde": "avant-garde fashion, experimental art, high concept, unconventional silhouette, futuristic and edgy",
 37}
 38
 39PROMPT_TEMPLATES = [
 40    "a photo representing the {} aesthetic",
 41    "artistic rendering in {} style",
 42    "an image from the {} era",
 43    "visuals depicting {}",
 44    "a high quality example of {} culture",
 45    "a magazine scan showing {}",
 46    "fashion photography in the style of {}",
 47    "a poster with {} design elements",
 48]
 49
 50
 51class EraClassifier:
 52    def __init__(self):
 53        self.centroids = None
 54        self.class_names = ERA_CLASSES
 55        self.build_text_features()
 56
 57    def build_text_features(self):
 58        """
 59        Pre-computes the embedding centroids for all eras.
 60        """
 61        print("Building text embeddings for eras...")
 62        class_centroids = []
 63
 64        with torch.no_grad():
 65            for label in self.class_names:
 66                desc = ERA_DESCRIPTIONS[label]
 67
 68                prompts = [tpl.format(desc) for tpl in PROMPT_TEMPLATES]
 69
 70                tokens = clip.tokenize(prompts).to(device)
 71                text_features = model.encode_text(tokens)
 72
 73                text_features = text_features / text_features.norm(dim=-1, keepdim=True)
 74
 75                centroid = text_features.mean(dim=0)
 76                centroid = centroid / centroid.norm()
 77
 78                class_centroids.append(centroid)
 79
 80        self.centroids = torch.stack(class_centroids).to(device)
 81        print("Text embeddings built successfully.")
 82
 83    def predict(self, image_path, threshold=0.20):
 84        image = Image.open(image_path).convert("RGB")
 85        img_tensor = preprocess(image).unsqueeze(0).to(device)
 86
 87        with torch.no_grad():
 88            img_feat = model.encode_image(img_tensor)
 89            img_feat = img_feat / img_feat.norm(dim=-1, keepdim=True)
 90
 91        similarity = 100.0 * img_feat @ self.centroids.T
 92
 93        probs = similarity.softmax(dim=-1).cpu().numpy()[0]
 94        raw_scores = similarity.cpu().numpy()[0] / 100.0
 95
 96        results = []
 97        for i, label in enumerate(self.class_names):
 98            results.append(
 99                {
100                    "label": label,
101                    "score": float(raw_scores[i]),
102                    "confidence_pct": float(probs[i] * 100),
103                }
104            )
105
106        results.sort(key=lambda x: x["score"], reverse=True)
107        top_result = results[0]
108
109        if top_result["score"] < threshold:
110            prediction = "undefined/mixed"
111        else:
112            prediction = top_result["label"]
113
114        return prediction, results
115
116
117# Runner
118
119classifier = EraClassifier()
120
121print("\nPlease upload an image to analyze...")
122uploaded = files.upload()
123
124if len(uploaded) > 0:
125    img_path = list(uploaded.keys())[0]
126
127    prediction, details = classifier.predict(img_path)
128
129    print("\n" + "=" * 30)
130    print(f"PREDICTED ERA: {prediction.upper()}")
131    print("=" * 30)
132
133    print(f"\nDetailed Breakdown:")
134    print(f"{'Era/Style':<15} | {'Cosine Sim':<12} | {'Rel Confidence':<15}")
135    print("-" * 45)
136
137    for item in details:
138        print(
139            f"{item['label']:<15} | {item['score']:.4f}       | {item['confidence_pct']:.1f}%"
140        )