creek
The AI Image Editor of 2030git clone https://github.com/maydayv7/creek
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 )