Cartoonize / app.py
outshine84@gmail.com
initial retry
8eb9eb9
import cv2
import os
import numpy as np
import gradio as gr
from sklearn.cluster import KMeans
import uvicorn
import tempfile
# -----------------------------
# FUNZIONI
# -----------------------------
def posterize (image, colors: int):
data = image.reshape(-1, 3).astype(np.float32)
kmeans = KMeans(n_clusters=colors, random_state=42, n_init='auto')
kmeans.fit(data)
labels = kmeans.predict(data)
centers = np.uint8(kmeans.cluster_centers_)
posterized_image = centers[labels]
posterized_image = posterized_image.reshape(image.shape)
return posterized_image
def adjust_image (image, saturation: int, brightness: int):
hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv_image)
s = cv2.add(s, saturation) # Increase saturation by adding a constant
s = np.clip(s, 0, 255) # Clip values to 0-255
v = cv2.add(v, brightness) # Increase brightness by adding a constant
v = np.clip(v, 0, 255) # Clip values to 0-255
adjusted_hsv = cv2.merge([h, s, v])
adjusted_color_image = cv2.cvtColor(adjusted_hsv, cv2.COLOR_HSV2BGR)
return adjusted_color_image
def cartoonize (image, saturation: int, brightness: int, edge_cut: int, paint_effect: int, blur: int , colors: int):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.medianBlur(gray, blur)
adjusted_color_image = adjust_image(image, saturation, brightness)
posterized_image = posterize(adjusted_color_image, colors)
edges = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 9, edge_cut)
color = cv2.bilateralFilter(posterized_image, paint_effect*2+1, 250, 250)
cartoon = cv2.bitwise_and(color, color, mask=edges)
return cartoon
# -----------------------------
# FILTRI
# -----------------------------
def apply_filters(image, blur, edge_cut, saturation, brightness, paint_effect, colors):
if image is None:
return None
# Convertiamo da RGB (Gradio) a BGR (OpenCV)
img = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
cartoonized = cartoonize(img,saturation,brightness,edge_cut,paint_effect,blur,colors)
cartoonized = cv2.cvtColor(cartoonized, cv2.COLOR_BGR2RGB)
return cartoonized
with gr.Blocks() as demo:
gr.Markdown("# Cartoonizer")
with gr.Row():
input_img = gr.Image(label="Carica immagine",type='numpy')
output_img = gr.Image(label="Risultato")
with gr.Accordion("Filtri", open=True):
blur = gr.Slider(0, 10, value=5, step=1, label="Sfocatura")
edge_cut = gr.Slider(0, 9, value=4, step=1, label="Edge Cut")
saturation = gr.Slider(0, 50, value=30, step=5, label="Saturazione")
brightness = gr.Slider(0, 50, value=15, step=5, label="Luminosità")
paint_effect = gr.Slider(0, 9, value=9, step=1, label="Modalità Paint")
colors = gr.Slider(0, 20, value=12, step=1, label="Numero di colori")
btn = gr.Button("Applica Filtri")
save = gr.Button("Salva Immagine")
# Aggiornamento in tempo reale
btn.click(
apply_filters,
inputs=[input_img, blur, edge_cut, saturation,brightness,paint_effect, colors],
outputs=output_img
)
# Salvataggio file
def save_image(image):
if image is None:
return None
tmp_path = os.path.join(
tempfile.gettempdir(),
"cartoonized_image.png" # fixed name or generate unique
)
bgr = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
cv2.imwrite(tmp_path, bgr)
return tmp_path
save.click(save_image, inputs=output_img, outputs=gr.File(label="File Salvato"))
# Avvio app
demo.launch(debug=True)