Image-to-prompt / app.py
PrathamGhaywat
FInal app!
eecace9
Raw
History Blame Contribute Delete
6.74 kB
import gradio as gr
import torch
from transformers import BlipProcessor, BlipForConditionalGeneration
import re
import os
MODEL_NAME = "Salesforce/blip-image-captioning-base"
print(f"📦 Using model: {MODEL_NAME}")
print(f"💾 Models stored in: {os.path.expanduser('~/.cache/huggingface/transformers/')}")
device = "cuda" if torch.cuda.is_available() else "cpu"
# Initialize BLIP model
try:
processor = BlipProcessor.from_pretrained(MODEL_NAME)
model = BlipForConditionalGeneration.from_pretrained(MODEL_NAME).to(device)
MODEL_LOADED = True
print(f"✅ Loaded BLIP model on {device} (~400MB)")
except Exception as e:
print(f"❌ Error loading model: {e}")
MODEL_LOADED = False
model = None
processor = None
def generate_caption_blip(image, style="detailed", max_length=50):
"""Generate caption using BLIP model"""
try:
inputs = processor(image, return_tensors="pt").to(device)
# Different generation parameters for different styles
if style == "simple":
generated_ids = model.generate(**inputs, max_length=25, num_beams=3)
elif style == "detailed":
generated_ids = model.generate(**inputs, max_length=max_length, num_beams=4, do_sample=True, temperature=0.7)
else: # artistic
generated_ids = model.generate(**inputs, max_length=max_length, num_beams=5, do_sample=True, temperature=0.9)
caption = processor.decode(generated_ids[0], skip_special_tokens=True)
return enhance_caption(caption, style)
except Exception as e:
return f"BLIP Error: {str(e)}"
def enhance_caption(caption, style):
"""Clean up and enhance captions"""
# Remove common prefixes
caption = re.sub(r'^(a|an|the|this is|there is)\s+', '', caption, flags=re.IGNORECASE)
caption = re.sub(r'(image|picture|photo)\s+(of|showing)\s+', '', caption, flags=re.IGNORECASE)
# Style enhancements
if style == "simple":
return caption.strip()
elif style == "detailed":
enhancers = ["detailed", "high-quality", "clear", "professional"]
import random
return f"{random.choice(enhancers)} {caption.strip()}"
else: # artistic
enhancers = ["stunning", "beautiful", "artistic", "masterpiece", "breathtaking"]
import random
return f"{random.choice(enhancers)} {caption.strip()}"
def generate_lightweight_prompt(image, style="detailed", max_length=50):
"""Main function - always uses BLIP model if loaded, else fallback"""
if not MODEL_LOADED:
return generate_basic_fallback(image, style)
try:
return generate_caption_blip(image, style, max_length)
except Exception as e:
return generate_basic_fallback(image, style)
def generate_basic_fallback(image, style):
"""Ultra-basic fallback (no models needed)"""
import numpy as np
try:
img_array = np.array(image)
height, width = img_array.shape[:2]
# Basic analysis
aspect_ratio = width / height
if aspect_ratio > 1.5:
comp = "wide landscape"
elif aspect_ratio < 0.7:
comp = "portrait orientation"
else:
comp = "balanced composition"
# Color analysis
if len(img_array.shape) == 3:
avg_brightness = np.mean(img_array)
if avg_brightness > 180:
lighting = "bright, well-lit"
elif avg_brightness > 100:
lighting = "evenly lit"
else:
lighting = "moody, darker"
else:
lighting = "black and white"
base_descriptions = {
"simple": f"{comp} image",
"detailed": f"A {lighting} {comp} photograph with good clarity",
"artistic": f"Artistic {comp} with {lighting} atmospheric mood"
}
return base_descriptions.get(style, "processed image")
except Exception as e:
return f"Basic analysis: {style} style image"
def create_lightweight_interface():
"""Lightweight Gradio interface (no model info or delete instructions)"""
with gr.Blocks(title="Lightweight Image-to-Prompt", theme=gr.themes.Monochrome()) as demo:
gr.Markdown("# ⚡ Lightweight Image-to-Prompt")
gr.Markdown("*Optimized for speed and storage efficiency*")
with gr.Row():
with gr.Column():
image_input = gr.Image(
type="pil",
label="📷 Upload Image",
height=300
)
with gr.Row():
style_radio = gr.Radio(
choices=["simple", "detailed", "artistic"],
value="detailed",
label="Style",
scale=2
)
length_slider = gr.Slider(
minimum=20,
maximum=80,
value=50,
step=10,
label="Length",
scale=1
)
generate_btn = gr.Button("Generate", variant="primary")
with gr.Column():
prompt_output = gr.Textbox(
label="Generated Prompt",
lines=5,
placeholder="Upload an image..."
)
with gr.Row():
copy_btn = gr.Button("Copy", size="sm")
clear_btn = gr.Button("Clear", size="sm")
# Event handlers
def process_image(image, style, length):
if image is None:
return "Upload an image first!"
return generate_lightweight_prompt(image, style, length)
# Auto-generate on upload
image_input.change(
fn=process_image,
inputs=[image_input, style_radio, length_slider],
outputs=prompt_output
)
generate_btn.click(
fn=process_image,
inputs=[image_input, style_radio, length_slider],
outputs=prompt_output
)
copy_btn.click(None, inputs=prompt_output, js="(text) => navigator.clipboard.writeText(text)")
clear_btn.click(lambda: "", outputs=prompt_output)
return demo
if __name__ == "__main__":
print("🚀 Starting Lightweight Image-to-Prompt...")
print(f"💾 Model cache: ~/.cache/huggingface/transformers/")
demo = create_lightweight_interface()
demo.launch()