med_image / app.py
neotran's picture
Upload folder using huggingface_hub
b92346f verified
import gradio as gr
import numpy as np
from PIL import Image
def apply_photoshop_color_balance_with_controls(
image_pil, cyan_shift, magenta_shift, yellow_shift, brightness, contrast
):
# Check if image is None and return early
if image_pil is None:
return None
# Convert to RGB float [0–1]
image_rgb = np.array(image_pil.convert("RGB")).astype(np.float32) / 255.0
R0, G0, B0 = image_rgb[..., 0], image_rgb[..., 1], image_rgb[..., 2]
# Valid area (exclude black background)
valid_mask = np.any(image_rgb > 0.05, axis=-1)
# Original luminance
orig_lum = 0.299 * R0 + 0.587 * G0 + 0.114 * B0
# Convert to CMY
C = 1 - R0
M = 1 - G0
Y = 1 - B0
# CMY Shifts scaled to [-1, 1]
delta_C = cyan_shift / 100.0
delta_M = magenta_shift / 100.0
delta_Y = yellow_shift / 100.0
# Apply CMY shifts to valid pixels
C[valid_mask] = np.clip(C[valid_mask] + delta_C, 0, 1)
M[valid_mask] = np.clip(M[valid_mask] + delta_M, 0, 1)
Y[valid_mask] = np.clip(Y[valid_mask] + delta_Y, 0, 1)
# Convert back to RGB
R = 1 - C
G = 1 - M
B = 1 - Y
# Preserve brightness
new_lum = 0.299 * R + 0.587 * G + 0.114 * B
gain = np.ones_like(new_lum)
gain[valid_mask] = (orig_lum[valid_mask] + 1e-5) / (new_lum[valid_mask] + 1e-5)
R = np.clip(R * gain, 0, 1)
G = np.clip(G * gain, 0, 1)
B = np.clip(B * gain, 0, 1)
# Stack image and apply brightness/contrast
result = np.stack([R, G, B], axis=-1)
# Brightness [-100, 100] → shift [-0.4, +0.4]
brightness_shift = brightness / 250.0
result = np.clip(result + brightness_shift, 0, 1)
# Contrast [-100, 100] → scale [0.6, 1.4]
contrast_factor = 1.0 + (contrast / 250.0)
result = np.clip((result - 0.5) * contrast_factor + 0.5, 0, 1)
return Image.fromarray((result * 255).astype(np.uint8))
show_sliders = False
share = False
iface = gr.Interface(
fn=apply_photoshop_color_balance_with_controls,
inputs=[
gr.Image(type="pil", label="Upload Image"),
gr.Slider(-100, 100, value=37, label="Red–Cyan", visible=show_sliders),
gr.Slider(-100, 100, value=-20, label="Green-Magenta", visible=show_sliders),
gr.Slider(-100, 100, value=-10, label="Blue-Yellow", visible=show_sliders),
gr.Slider(-100, 100, value=-25, label="Brightness", visible=show_sliders),
gr.Slider(-100, 100, value=34, label="Contrast", visible=show_sliders),
],
live=True,
outputs=gr.Image(type="pil", label="Processed Image"),
title="Image Color Balancer with CMY + Brightness/Contrast",
description="Apply Photoshop-like CMY color shifts in shadows. Optionally adjust brightness and contrast.",
)
if __name__ == "__main__":
iface.launch(share=share)