Image_filtered / app.py
shiue2000's picture
Update app.py
540fae5 verified
import os
import cv2
import numpy as np
import gradio as gr
from PIL import Image
import pyheif
import uuid
from diffusers import StableDiffusionPipeline
import torch
# --- OUTPUT DIRECTORY ---
OUTPUT_DIR = "outputs"
os.makedirs(OUTPUT_DIR, exist_ok=True)
# --- DEVICE SETUP ---
device = "cpu" # Force CPU
# --- LOAD STABLE DIFFUSION PIPELINE ---
MODEL_NAME = "Lykon/anything-cartoon" # original model
PUBLIC_MODEL = "runwayml/stable-diffusion-v1-5" # fallback
HF_TOKEN = os.getenv("HF_TOKEN", None) # optional token for private repo
try:
pipe = StableDiffusionPipeline.from_pretrained(
MODEL_NAME,
torch_dtype=torch.float32,
use_auth_token=HF_TOKEN
)
except Exception as e:
print(f"Failed to load '{MODEL_NAME}': {e}")
print(f"Falling back to public model '{PUBLIC_MODEL}'")
pipe = StableDiffusionPipeline.from_pretrained(
PUBLIC_MODEL,
torch_dtype=torch.float32
)
pipe.to(device)
# --- HELPER FUNCTIONS ---
def load_image(file):
ext = os.path.splitext(file.name)[1].lower() if hasattr(file, "name") else os.path.splitext(file)[1].lower()
if ext in [".heic", ".heif"]:
if hasattr(file, "read"):
heif_file = pyheif.read_heif(file.read())
else:
with open(file, "rb") as f:
heif_file = pyheif.read_heif(f.read())
image = Image.frombytes(
heif_file.mode,
heif_file.size,
heif_file.data,
"raw",
heif_file.mode,
heif_file.stride,
)
return image
else:
if hasattr(file, "seek"):
file.seek(0)
return Image.open(file)
else:
return Image.open(file)
def apply_filters(file, mode):
image = load_image(file)
img = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
if mode == "Gray":
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
processed = cv2.cvtColor(gray, cv2.COLOR_GRAY2RGB)
elif mode == "Scratch":
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
denoised = cv2.fastNlMeansDenoising(gray, h=10)
processed = cv2.cvtColor(denoised, cv2.COLOR_GRAY2RGB)
elif mode == "Pencil Sketch":
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
inv = 255 - gray
blur = cv2.GaussianBlur(inv, (21, 21), 0)
sketch = cv2.divide(gray, 255 - blur, scale=256.0)
processed = cv2.cvtColor(sketch, cv2.COLOR_GRAY2RGB)
elif mode == "Cartoon":
num_down = 2
num_bilateral = 7
img_color = img.copy()
for _ in range(num_down):
img_color = cv2.pyrDown(img_color)
for _ in range(num_bilateral):
img_color = cv2.bilateralFilter(img_color, d=9, sigmaColor=75, sigmaSpace=75)
for _ in range(num_down):
img_color = cv2.pyrUp(img_color)
if img_color.shape != img.shape:
img_color = cv2.resize(img_color, (img.shape[1], img.shape[0]))
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_blur = cv2.medianBlur(img_gray, 7)
edges = cv2.adaptiveThreshold(img_blur, 255,
cv2.ADAPTIVE_THRESH_MEAN_C,
cv2.THRESH_BINARY, 9, 2)
edges = cv2.cvtColor(edges, cv2.COLOR_GRAY2BGR)
cartoon = cv2.bitwise_and(img_color, edges)
processed = cv2.cvtColor(cartoon, cv2.COLOR_BGR2RGB)
elif mode == "AI Cartoon":
pil_img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
prompt = "cartoon, anime style, vibrant colors, detailed, smooth"
# CPU only
cartoon_img = pipe(prompt=prompt, image=pil_img, num_inference_steps=30).images[0]
processed = np.array(cartoon_img)
elif mode == "Sepia":
sepia_filter = np.array([[0.272, 0.534, 0.131],
[0.349, 0.686, 0.168],
[0.393, 0.769, 0.189]])
sepia = cv2.transform(img, sepia_filter)
sepia = np.clip(sepia, 0, 255).astype(np.uint8)
processed = cv2.cvtColor(sepia, cv2.COLOR_BGR2RGB)
elif mode == "Edge Detection":
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 100, 200)
processed = cv2.cvtColor(edges, cv2.COLOR_GRAY2RGB)
elif mode == "HSV":
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
processed = cv2.cvtColor(hsv, cv2.COLOR_HSV2RGB)
else:
processed = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
output_filename = f"{uuid.uuid4().hex}_{mode.replace(' ', '_')}.png"
output_path = os.path.join(OUTPUT_DIR, output_filename)
Image.fromarray(processed).save(output_path)
return processed, output_path
# --- GRADIO INTERFACE ---
demo = gr.Interface(
fn=apply_filters,
inputs=[
gr.File(label="Upload Image (PNG, JPG, HEIC)", type="filepath"), # FIXED
gr.Radio(
choices=["Gray", "Scratch", "Pencil Sketch", "Cartoon", "AI Cartoon",
"Sepia", "Edge Detection", "RGB", "HSV"],
value="Gray",
label="Filter Mode"
),
],
outputs=[
gr.Image(type="numpy", label="Filtered Image"),
gr.File(label="⬇️ Download Image")
],
title="🎨 Image Filter Lab",
description="Apply filters including AI Cartoon. Supports iPhone HEIC images.",
allow_flagging="never",
theme="soft"
)
if __name__ == "__main__":
demo.launch()