Spaces:
Sleeping
Sleeping
File size: 7,616 Bytes
e9790f2 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 | import random
import torch
from transformers import BlipProcessor, BlipForConditionalGeneration
import gradio as gr
from PIL import Image
device = "cuda" if torch.cuda.is_available() else "cpu"
# Load the fine tuned model and processor
processor_trained = BlipProcessor.from_pretrained("saarah005/blip-finetuned-holmes")
model_trained = BlipForConditionalGeneration.from_pretrained("saarah005/blip-finetuned-holmes").to(device)
def holmesify(caption):
# Small dictionary of style replacements
replacements = {
# ---- People ----
"dog": "hound",
"dogs": "hounds",
"cat": "feline companion",
"cats": "feline companions",
"bird": "avian companion",
"birds": "avian companions",
"man": "gentleman",
"men": "gentlemen",
"woman": "lady",
"women": "ladies",
"boys": "young lads",
"boy": "young lad",
"girl": "young maiden",
"girls": "young maids",
"child": "youth",
"children": "young ones",
"person": "individual of interest",
"people": "various passersby",
"crowd": "assembly of onlookers",
# ---- Actions / Verbs ----
"running": "in swift pursuit",
"walking": "taking measured strides",
"standing": "stationed with deliberate poise",
"sitting": "resting in quiet contemplation",
"talking": "engaged in hushed discourse",
"laughing": "expressing a moment of levity",
"smiling": "bearing a subtle expression of warmth",
"looking": "fixing one's gaze with intent",
"pointing": "gesturing with purposeful direction",
"holding": "grasping with notable care",
"playing": "engaged in curious amusement",
"jumping": "springing forth with unexpected vigor",
"working": "occupied with some industrious task",
# ---- Objects ----
"car": "motorised carriage",
"bike": "mechanical velocipede",
"bicycle": "two-wheeled contraption",
"ball": "spherical object of diversion",
"bag": "carried satchel",
"phone": "telephonic device",
"camera": "photographic apparatus",
"book": "well-worn volume",
"hat": "notable headwear",
# ---- Locations / Environments ----
"beach": "windswept shore",
"street": "fog-laden lane",
"road": "lonely thoroughfare",
"park": "quiet public green",
"forest": "shadowed woodland",
"city": "bustling metropolis",
"house": "residence of uncertain history",
"room": "chamber of modest proportion",
"yard": "narrow courtyard",
"river": "meandering waterway",
# ---- Atmosphere / Adjectives ----
"beautiful": "most striking in its appearance",
"dark": "shrouded in somber gloom",
"bright": "lit with uncommon clarity",
"large": "of considerable magnitude",
"small": "modest in scale",
"happy": "in unusually pleasant spirits",
"old": "weathered by time",
"new": "freshly appointed",
# ---- Extra stylistic swaps ----
"near": "in the immediate vicinity of",
"beside": "adjacent to",
"behind": "situated just beyond",
"before": "presented directly before",
"with": "accompanied by",
}
words = caption.split()
new_words = [
replacements.get(w.lower().strip(",."), w.strip(",."))
for w in words
]
stylized = " ".join(new_words)
# Add a Holmesian flourish
intros = [
"Upon my keen observation,",
"It was immediately apparent to my trained eye that",
"After a brief yet thorough inspection, I deduced that",
"From even the faintest clues, one might surmise",
"To the ordinary passerby it may seem trivial, yet I perceived that",
]
outros = [
" — a detail insignificant to most, yet crucial to the discerning mind.",
" — a sight which, though mundane, whispered of deeper implications.",
" — revealing a subtle narrative hidden beneath the everyday scene.",
" — an occurrence that beckons further inquiry to the vigilant observer.",
]
holmes_caption = f"{random.choice(intros)} {stylized}{random.choice(outros)}"
return holmes_caption
def infer(image):
# Preprocess
inputs = processor_trained(images=image, return_tensors="pt").to(device)
pixel_values = inputs["pixel_values"]
# Generate BLIP caption
model_trained.eval()
with torch.no_grad():
generated_ids = model_trained.generate(pixel_values=pixel_values, max_length=50)
caption = processor_trained.batch_decode(generated_ids, skip_special_tokens=True)[0]
# To Holmesify
return holmesify(caption)
output_box = gr.Textbox(lines=8, label="Sherlock Caption", show_copy_button=True)
custom_css = """
/* Victorian accent font */
@import url('https://fonts.googleapis.com/css2?family=Great+Vibes&display=swap');
/* Theme variables */
:root {
--bg: #0d0d0d;
--text: #e4e4e4;
--border-color: #444;
}
/* Light theme class (not used unless you toggle it) */
.lightmode {
--bg: #ffffff;
--text: #1a1a1a;
--border-color: #ccc;
}
/* Global page background + text */
body, .gradio-container {
background-color: var(--bg) !important;
color: var(--text) !important;
}
/* Generic Gradio elements */
.gr-box, textarea {
background-color: var(--bg) !important;
color: var(--text) !important;
border-color: var(--border-color) !important;
}
/* Header container */
.header-container > div {
display: flex;
align-items: center;
text-align: center;
gap: 20px;
margin-bottom: 10px;
}
/* Header image */
.header-img {
height: 80px;
aspect-ratio: 1 / 1;
border-radius: 50%;
object-fit: cover;
border: 2px solid white;
}
/* Main heading */
.main-heading {
font-family: "Great Vibes", cursive; /* decorative font */
font-size: 40px;
font-weight: bold;
margin: 0 auto;
padding: 0;
color: var(--text);
text-align: center;
}
/* Sherlock button */
.sherlock-btn {
background-color: #692625 !important;
color: white !important;
border: 2px solid #4d1b1b !important;
font-weight: bold;
transition: 0.2s ease-in-out;
width: 250px !important;
margin: 20px auto !important;
display: block !important;
text-align: center !important;
}
/* Hover effect */
.sherlock-btn:hover {
background-color: #8a2f2e !important;
transform: scale(1.03);
}
/* Make both columns stretch to same height */
.gr-row {
align-items: stretch !important;
}
.equal-box {
height: 100% !important;
}
.equal-box textarea {
height: 100% !important;
}
"""
with gr.Blocks(css=custom_css) as demo:
# Background
theme_state = gr.State("dark")
# Header
gr.HTML("""
<div class="header-container">
<img src="https://www.mysterycenter.com/wp-content/uploads/2024/06/dreamstime_s_50012210-640x381.jpg" class="header-img">
<div>
<div class="main-heading">Sherlock Holmes Caption Generator</div>
</div>
</div>
""")
# Main Layout
with gr.Row():
# Image uploader
image_in = gr.Image(
type="pil",
label="Upload Image",
sources=["upload"],
elem_classes="equal-box"
)
# Output text box
output_box = gr.Textbox(
lines=10,
label="Sherlock Holmes Caption",
show_copy_button=True,
elem_classes="equal-box textarea"
)
# Button
run_btn = gr.Button("Generate Sherlock Caption", elem_classes="sherlock-btn")
run_btn.click(infer, inputs=image_in, outputs=output_box)
demo.launch(share=True, debug=True)
|