Spaces:
Running
Running
File size: 3,492 Bytes
8071e3e d379ce4 0f173ed d379ce4 0f173ed d379ce4 0f173ed 8071e3e 0f173ed 8071e3e 0f173ed 8071e3e 0f173ed 8071e3e 0f173ed 7dc26b7 0f173ed 8071e3e 5fe3046 0f173ed 5fe3046 0f173ed 5fe3046 0f173ed 5fe3046 0f173ed de7814e 0f173ed de7814e 0f173ed |
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 |
import gradio as gr
import torch
from torch import nn
from transformers import CLIPVisionModel, CLIPImageProcessor
from PIL import Image, ImageEnhance, ImageOps
device = "cuda" if torch.cuda.is_available() else "cpu"
# -----------------------------
# Aesthetic Scoring Model
# -----------------------------
class AestheticScorer(nn.Module):
def __init__(self):
super().__init__()
self.vision_model = CLIPVisionModel.from_pretrained("openai/clip-vit-base-patch16")
self.mlp = nn.Sequential(
nn.Linear(self.vision_model.config.hidden_size, 512),
nn.ReLU(),
nn.Linear(512, 1)
)
def forward(self, pixel_values):
outputs = self.vision_model(pixel_values=pixel_values)
pooled = outputs.pooler_output
return self.mlp(pooled)
processor = CLIPImageProcessor.from_pretrained("openai/clip-vit-base-patch16")
ae_model = AestheticScorer().to(device)
ae_model.eval()
# -----------------------------
# Cinematic Enhancement
# -----------------------------
def apply_cinematic(image: Image.Image) -> Image.Image:
img = image.convert("RGB")
# slight letterboxing for cinematic aspect ratio feel
w, h = img.size
bar_height = int(h * 0.07) # 7% black bars
new_img = Image.new("RGB", (w, h), (0, 0, 0))
new_img.paste(img, (0, 0))
# adjust colors for cinematic mood
enhancer = ImageEnhance.Color(img)
img = enhancer.enhance(1.2) # richer colors
enhancer = ImageEnhance.Contrast(img)
img = enhancer.enhance(1.15) # more contrast
enhancer = ImageEnhance.Brightness(img)
img = enhancer.enhance(0.95) # slightly darker
# add subtle warm tint (teal & orange style)
r, g, b = img.split()
r = r.point(lambda i: i * 1.05)
b = b.point(lambda i: i * 0.95)
img = Image.merge("RGB", (r, g, b))
# add black bars
new_img.paste(img, (0, 0))
draw = ImageOps.expand(img, border=(0, bar_height, 0, bar_height), fill="black")
return draw
# -----------------------------
# Scoring
# -----------------------------
def aesthetic_score(image: Image.Image) -> float:
inputs = processor(images=image, return_tensors="pt").to(device)
with torch.no_grad():
score = ae_model(inputs['pixel_values']).cpu().item()
return round(float(score), 2)
# -----------------------------
# Pipeline
# -----------------------------
def process(image):
# score original
original_score = aesthetic_score(image)
# cinematic version
cinematic_img = apply_cinematic(image)
# score cinematic
cinematic_score = aesthetic_score(cinematic_img)
# ranking suggestion
suggestions = sorted(
[("Original", original_score), ("Cinematic", cinematic_score)],
key=lambda x: x[1],
reverse=True,
)
result_text = "π Aesthetic Ranking:\n"
for rank, (name, score) in enumerate(suggestions, 1):
result_text += f"{rank}. {name} β Score: {score}\n"
return cinematic_img, result_text
# -----------------------------
# Gradio UI
# -----------------------------
with gr.Blocks() as demo:
gr.Markdown("## π¬ Cinematic Photo Enhancer")
with gr.Row():
inp = gr.Image(type="pil", label="Upload your photo")
out_img = gr.Image(type="pil", label="Cinematic Output")
out_txt = gr.Textbox(label="Suggestions & Scores")
run_btn = gr.Button("Enhance Photo")
run_btn.click(process, inputs=inp, outputs=[out_img, out_txt])
demo.launch()
|