photo-filter / app.py
eienmojiki's picture
Update app.py
f2d70d3 verified
# author : OzlemAkgunoglu
# github : https://github.com/OzlemAkgunoglu
# Dynamic Photo Filter App
# This is a Dynamic Photo Filter App that allows you to apply various filters to your images.
# Adjust brightness, contrast, sharpening, and select a filter for real-time changes.
# And this app is created using OpenCV and Gradio. Thank you for using it.
# Let's load the necessary libraries
import cv2 as cv # OpenCV for image processing
import numpy as np # Numpy for arrays
import gradio as gr # Gradio for UI
import re
def rgba_to_rgb(rgba_string):
match = re.match(r'rgba\(([\d.]+),\s*([\d.]+),\s*([\d.]+),\s*([\d.]+)\)', rgba_string)
if not match:
raise ValueError("Invalid RGBA")
r, g, b, a = map(float, match.groups())
return (int(r), int(g), int(b))
# Let's define the filter functions
def apply_grayscale(image):
return cv.cvtColor(image, cv.COLOR_BGR2GRAY) # Convert the image to grayscale
# Sepia filter function
def apply_sepia(image):
sepia_filter = np.array([[0.272, 0.534, 0.131],
[0.349, 0.686, 0.168],
[0.393, 0.769, 0.189]])
sepia_image = cv.transform(image, sepia_filter) # Apply the filter
return np.clip(sepia_image, 0, 255).astype(np.uint8) # clip to hold values between 0 and 255 prevent excessive brightness or darkening.
def apply_negative(image):
return cv.bitwise_not(image) # Invert the image
# Sketch filter
def apply_sketch(image):
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY) # Convert the image to grayscale
inv = cv.bitwise_not(gray) # Invert the grayscale image
blurred = cv.GaussianBlur(inv, (21, 21), sigmaX=0, sigmaY=0)
sketch_image = cv.divide(gray, 255 - blurred, scale=256)
return sketch_image
def apply_sharpen(image, sharpening):
sharpening_filter = np.array([[0, -1, 0],
[-1, 5 + sharpening, -1],
[0, -1, 0]])
return cv.filter2D(image, -1, sharpening_filter) # Apply the filter each pixel is multiplied by the value in the kernel
def apply_edge_detection(image):
return cv.Canny(image, 100, 200)
def apply_fall_filter(frame):
fall_filter = np.array([[0.393, 0.769, 0.189],
[0.349, 0.686, 0.168],
[0.272, 0.534, 0.131]])
return cv.transform(frame, fall_filter)
# Emboss filter
def apply_emboss(image):
emboss_filter = np.array([[0, -1, 0],
[-1, 5, -1],
[0, -1, 0]])
return cv.filter2D(image, -1, emboss_filter)
# Blur filter
def apply_blur(image, kernel_size):
return cv.blur(image, (kernel_size, kernel_size))
# Vintage filter
def apply_vintage(image):
vintage_filter = np.array([[0.627, 0.554, 0.369],
[0.766, 0.714, 0.406],
[0.882, 0.869, 0.524]])
vintage_image = cv.transform(image, vintage_filter) # Apply the filter
return np.clip(vintage_image, 0, 255).astype(np.uint8) # clip to hold values between 0 and 255 prevent excessive brightness or darkening.
# Combined filter
def apply_combined(image, sharpening):
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
sepia = apply_sepia(image)
sharpened = apply_sharpen(sepia, sharpening)
edges = apply_edge_detection(gray)
edges = cv.cvtColor(edges, cv.COLOR_GRAY2BGR)
combined = cv.addWeighted(sharpened, 0.7, edges, 0.3, 0)
return combined
# Cartoon filter
def apply_cartoon(image):
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
gray = cv.medianBlur(gray, 7)
edges = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY_INV, 9, 9)
color = cv.bilateralFilter(image, 9, 300, 300)
cartoon = cv.bitwise_and(color, color, mask=edges)
return cartoon
# Watercolor filter
def apply_watercolor(image, size, sigma):
blurred = cv.GaussianBlur(image, (size, size), sigma)
watercolor = cv.addWeighted(image, 0.5, blurred, 0.5, 0)
return watercolor
# Hue Shift filter
def apply_hue_shift(image, hue_shift):
hsv = cv.cvtColor(image, cv.COLOR_BGR2HSV)
h, s, v = cv.split(hsv)
h = cv.add(h, hue_shift)
shifted_hsv = cv.merge([h, s, v])
shifted_image = cv.cvtColor(shifted_hsv, cv.COLOR_HSV2BGR)
return shifted_image
def apply_60s_tv(image):
# Convert to sepia
sepia = apply_sepia(image)
# Reduce sharpness
blurred = cv.GaussianBlur(sepia, (5, 5), sigmaX=0, sigmaY=0)
# Add noise
noise = np.zeros(sepia.shape, dtype=np.int16)
cv.randn(noise, 0, 20)
noisy_image = cv.add(blurred, noise, dtype=cv.CV_8UC3)
noisy_image = np.clip(noisy_image, 0, 255).astype(np.uint8)
# Reduce color depth
noisy_image = (noisy_image // 32) * 32
return noisy_image
# Vignette filter
def apply_vignette(image, strength, aspect_ratio, center_x, center_y, radius, smoothness):
rows, cols = image.shape[:2]
center = (int(cols * center_x), int(rows * center_y))
mask = np.zeros((rows, cols), dtype=np.float32)
for i in range(rows):
for j in range(cols):
distance_x = (j - center[0]) / (cols * aspect_ratio)
distance_y = (i - center[1]) / rows
distance = np.sqrt(distance_x**2 + distance_y**2)
mask[i, j] = 1 - (distance / radius) ** strength
mask = np.clip(mask, 0, 1)
mask = np.stack((mask, mask, mask), axis=2)
vignette_image = cv.multiply(image.astype(np.float32), mask)
return vignette_image.astype(np.uint8)
# Tint filter
def apply_tint(image, tint_color, intensity):
tint_color = np.array(tint_color, dtype=np.float32) / 255.0
tint_color = cv.cvtColor(np.uint8([[tint_color]]), cv.COLOR_BGR2HSV).flatten()
hsv_image = cv.cvtColor(image, cv.COLOR_BGR2HSV).astype(np.float32)
hsv_image[:, :, 0] = (hsv_image[:, :, 0] + tint_color[0] * intensity) % 180
hsv_image[:, :, 1] = np.clip(hsv_image[:, :, 1] + tint_color[1] * intensity, 0, 255)
hsv_image[:, :, 2] = np.clip(hsv_image[:, :, 2] + tint_color[2] * intensity, 0, 255)
tinted_image = cv.cvtColor(hsv_image.astype(np.uint8), cv.COLOR_HSV2BGR)
return tinted_image
# Dictionary to map filter names to functions
filter_functions = {
"Grayscale": apply_grayscale,
"Sepia": apply_sepia,
"Negative": apply_negative,
"Sketch": apply_sketch,
"Sharpen": apply_sharpen,
"Edge Detection": apply_edge_detection,
"Fall": apply_fall_filter,
"Emboss": apply_emboss,
"Blur": apply_blur,
"Vintage": apply_vintage,
"Combined": apply_combined,
"Cartoon": apply_cartoon,
"Watercolor": apply_watercolor,
"Hue Shift": apply_hue_shift,
"60s TV": apply_60s_tv,
"Vignette": apply_vignette,
"Tint": apply_tint
}
# Main function to apply selected filters
def apply_filters(image, filter_type, brightness, contrast, sharpening, kernel_size, hue_shift, size, sigma, vignette_strength, vignette_aspect_ratio, vignette_center_x, vignette_center_y, vignette_radius, vignette_smoothness, tint_color, tint_intensity):
if image is None:
gr.Error("Input image is empty!") # for debugging
return None # Return None if the input image is empty
# Adjust brightness and contrast
image = cv.convertScaleAbs(image, alpha=contrast, beta=brightness)
if isinstance(tint_color, str):
if tint_color.startswith('#') and len(tint_color) == 7:
try:
tint_color = tint_color.lstrip('#')
tint_color_rgb = tuple(int(tint_color[i:i+2], 16) for i in (0, 2, 4))
except ValueError:
print("Invalid hex color format. Using default color #FF0000.")
tint_color_rgb = (255, 0, 0) # Default color red
elif tint_color.startswith('rgba('):
try:
tint_color_rgb = rgba_to_rgb(tint_color)
except ValueError:
print("Invalid rgba format. Using default color #FF0000.", )
tint_color_rgb = (255, 0, 0) # Default color red
else:
print("Invalid color format. Using default color #FF0000.")
tint_color_rgb = (255, 0, 0) # Default color red
else:
print("Invalid color format. Using default color #FF0000.")
tint_color_rgb = (255, 0, 0) # Default color red
# Apply the selected filter from dictionary called filter_functions
if filter_type in filter_functions:
if filter_type == "Sharpen" or filter_type == "Combined":
image = filter_functions[filter_type](image, sharpening) # Calls the Sharpen or Combined filter with the sharpening parameter
elif filter_type == "Blur":
image = filter_functions[filter_type](image, kernel_size) # Calls the Blur filter with the kernel_size parameter
elif filter_type == "Hue Shift":
image = filter_functions[filter_type](image, hue_shift) # Calls the Hue Shift filter with hue_shift parameter
elif filter_type == "Watercolor":
image = filter_functions[filter_type](image, size, sigma) # Calls the Watercolor filter with size and sigma parameters
elif filter_type == "Vignette":
image = filter_functions[filter_type](image, vignette_strength, vignette_aspect_ratio, vignette_center_x, vignette_center_y, vignette_radius, vignette_smoothness) # Calls the Vignette filter with vignette_strength parameter
elif filter_type == "Tint":
image = filter_functions[filter_type](image, tint_color_rgb, tint_intensity)
else:
image = filter_functions[filter_type](image)
return image
# Define Interface
with gr.Blocks(theme="ParityError/Interstellar") as app:
# Title and Description
gr.Markdown("<h1 style='font-family: Arial, sans-serif; color: #333;'>📸 Photo Filter ⭐</h1>")
gr.Markdown("<p style='color: #666;'>Apply professional photo filters with adjustable brightness, contrast, and sharpness. Perfect your images instantly!</p>")
# Choices and Sliders at the Top
with gr.Row():
filter_choice = gr.Radio(list(filter_functions.keys()), label="Filter")
with gr.Column():
brightness_slider = gr.Slider(-100, 100, step=1, label="Brightness", value=0)
contrast_slider = gr.Slider(0.5, 3.0, step=0.1, label="Contrast", value=1.0)
sharpening_slider = gr.Slider(0, 5, step=0.1, label="Sharpening", value=0)
blur_slider = gr.Slider(3, 21, step=2, label="Blur Kernel Size", value=15, visible=False)
hue_shift_slider = gr.Slider(-180, 180, step=1, label="Hue Shift", value=0, visible=False)
watercolor_size_slider = gr.Slider(3, 21, step=2, label="Watercolor Size", value=15, visible=False)
watercolor_sigma_slider = gr.Slider(0.1, 10.0, step=0.1, label="Watercolor Sigma", value=2.0, visible=False)
vignette_strength_slider = gr.Slider(1, 10, step=0.1, label="Vignette Strength", value=3.0, visible=False)
vignette_aspect_ratio_slider = gr.Slider(0.5, 2.0, step=0.1, label="Vignette Aspect Ratio", value=1.0, visible=False)
vignette_center_x_slider = gr.Slider(0.0, 1.0, step=0.01, label="Vignette Center X", value=0.5, visible=False)
vignette_center_y_slider = gr.Slider(0.0, 1.0, step=0.01, label="Vignette Center Y", value=0.5, visible=False)
vignette_radius_slider = gr.Slider(0.1, 1.0, step=0.01, label="Vignette Radius", value=0.75, visible=False)
vignette_smoothness_slider = gr.Slider(1, 10, step=0.1, label="Vignette Smoothness", value=3.0, visible=False)
tint_color_picker = gr.ColorPicker(label="Tint Color", value="#FF0000", visible=False)
tint_intensity_slider = gr.Slider(0, 1, step=0.01, label="Tint Intensity", value=0.5, visible=False)
# Horizontal display of the images
with gr.Row():
image_input = gr.Image(label="Upload Image", type="numpy")
image_output = gr.Image(label="Filtered Image")
# Function to update visibility of sliders
def update_slider_visibility(filter_type):
blur_visible = filter_type == "Blur"
hue_visible = filter_type == "Hue Shift"
watercolor_visible = filter_type == "Watercolor"
vignette_visible = filter_type == "Vignette"
tint_visible = filter_type == "Tint"
return (
gr.update(visible=blur_visible),
gr.update(visible=hue_visible),
gr.update(visible=watercolor_visible),
gr.update(visible=watercolor_visible),
gr.update(visible=vignette_visible),
gr.update(visible=vignette_visible),
gr.update(visible=vignette_visible),
gr.update(visible=vignette_visible),
gr.update(visible=vignette_visible),
gr.update(visible=vignette_visible),
gr.update(visible=tint_visible),
gr.update(visible=tint_visible)
)
# Link events for real-time updates
image_input.change(
apply_filters,
inputs=[
image_input, filter_choice, brightness_slider, contrast_slider, sharpening_slider,
blur_slider, hue_shift_slider, watercolor_size_slider, watercolor_sigma_slider,
vignette_strength_slider, vignette_aspect_ratio_slider, vignette_center_x_slider,
vignette_center_y_slider, vignette_radius_slider, vignette_smoothness_slider,
tint_color_picker, tint_intensity_slider
],
outputs=image_output
)
filter_choice.change(
apply_filters,
inputs=[
image_input, filter_choice, brightness_slider, contrast_slider, sharpening_slider,
blur_slider, hue_shift_slider, watercolor_size_slider, watercolor_sigma_slider,
vignette_strength_slider, vignette_aspect_ratio_slider, vignette_center_x_slider,
vignette_center_y_slider, vignette_radius_slider, vignette_smoothness_slider,
tint_color_picker, tint_intensity_slider
],
outputs=image_output
)
brightness_slider.change(
apply_filters,
inputs=[
image_input, filter_choice, brightness_slider, contrast_slider, sharpening_slider,
blur_slider, hue_shift_slider, watercolor_size_slider, watercolor_sigma_slider,
vignette_strength_slider, vignette_aspect_ratio_slider, vignette_center_x_slider,
vignette_center_y_slider, vignette_radius_slider, vignette_smoothness_slider,
tint_color_picker, tint_intensity_slider
],
outputs=image_output
)
contrast_slider.change(
apply_filters,
inputs=[
image_input, filter_choice, brightness_slider, contrast_slider, sharpening_slider,
blur_slider, hue_shift_slider, watercolor_size_slider, watercolor_sigma_slider,
vignette_strength_slider, vignette_aspect_ratio_slider, vignette_center_x_slider,
vignette_center_y_slider, vignette_radius_slider, vignette_smoothness_slider,
tint_color_picker, tint_intensity_slider
],
outputs=image_output
)
sharpening_slider.change(
apply_filters,
inputs=[
image_input, filter_choice, brightness_slider, contrast_slider, sharpening_slider,
blur_slider, hue_shift_slider, watercolor_size_slider, watercolor_sigma_slider,
vignette_strength_slider, vignette_aspect_ratio_slider, vignette_center_x_slider,
vignette_center_y_slider, vignette_radius_slider, vignette_smoothness_slider,
tint_color_picker, tint_intensity_slider
],
outputs=image_output
)
blur_slider.change(
apply_filters,
inputs=[
image_input, filter_choice, brightness_slider, contrast_slider, sharpening_slider,
blur_slider, hue_shift_slider, watercolor_size_slider, watercolor_sigma_slider,
vignette_strength_slider, vignette_aspect_ratio_slider, vignette_center_x_slider,
vignette_center_y_slider, vignette_radius_slider, vignette_smoothness_slider,
tint_color_picker, tint_intensity_slider
],
outputs=image_output
)
hue_shift_slider.change(
apply_filters,
inputs=[
image_input, filter_choice, brightness_slider, contrast_slider, sharpening_slider,
blur_slider, hue_shift_slider, watercolor_size_slider, watercolor_sigma_slider,
vignette_strength_slider, vignette_aspect_ratio_slider, vignette_center_x_slider,
vignette_center_y_slider, vignette_radius_slider, vignette_smoothness_slider,
tint_color_picker, tint_intensity_slider
],
outputs=image_output
)
watercolor_size_slider.change(
apply_filters,
inputs=[
image_input, filter_choice, brightness_slider, contrast_slider, sharpening_slider,
blur_slider, hue_shift_slider, watercolor_size_slider, watercolor_sigma_slider,
vignette_strength_slider, vignette_aspect_ratio_slider, vignette_center_x_slider,
vignette_center_y_slider, vignette_radius_slider, vignette_smoothness_slider,
tint_color_picker, tint_intensity_slider
],
outputs=image_output
)
watercolor_sigma_slider.change(
apply_filters,
inputs=[
image_input, filter_choice, brightness_slider, contrast_slider, sharpening_slider,
blur_slider, hue_shift_slider, watercolor_size_slider, watercolor_sigma_slider,
vignette_strength_slider, vignette_aspect_ratio_slider, vignette_center_x_slider,
vignette_center_y_slider, vignette_radius_slider, vignette_smoothness_slider,
tint_color_picker, tint_intensity_slider
],
outputs=image_output
)
vignette_strength_slider.change(
apply_filters,
inputs=[
image_input, filter_choice, brightness_slider, contrast_slider, sharpening_slider,
blur_slider, hue_shift_slider, watercolor_size_slider, watercolor_sigma_slider,
vignette_strength_slider, vignette_aspect_ratio_slider, vignette_center_x_slider,
vignette_center_y_slider, vignette_radius_slider, vignette_smoothness_slider,
tint_color_picker, tint_intensity_slider
],
outputs=image_output
)
vignette_aspect_ratio_slider.change(
apply_filters,
inputs=[
image_input, filter_choice, brightness_slider, contrast_slider, sharpening_slider,
blur_slider, hue_shift_slider, watercolor_size_slider, watercolor_sigma_slider,
vignette_strength_slider, vignette_aspect_ratio_slider, vignette_center_x_slider,
vignette_center_y_slider, vignette_radius_slider, vignette_smoothness_slider,
tint_color_picker, tint_intensity_slider
],
outputs=image_output
)
vignette_center_x_slider.change(
apply_filters,
inputs=[
image_input, filter_choice, brightness_slider, contrast_slider, sharpening_slider,
blur_slider, hue_shift_slider, watercolor_size_slider, watercolor_sigma_slider,
vignette_strength_slider, vignette_aspect_ratio_slider, vignette_center_x_slider,
vignette_center_y_slider, vignette_radius_slider, vignette_smoothness_slider,
tint_color_picker, tint_intensity_slider
],
outputs=image_output
)
vignette_center_y_slider.change(
apply_filters,
inputs=[
image_input, filter_choice, brightness_slider, contrast_slider, sharpening_slider,
blur_slider, hue_shift_slider, watercolor_size_slider, watercolor_sigma_slider,
vignette_strength_slider, vignette_aspect_ratio_slider, vignette_center_x_slider,
vignette_center_y_slider, vignette_radius_slider, vignette_smoothness_slider,
tint_color_picker, tint_intensity_slider
],
outputs=image_output
)
vignette_radius_slider.change(
apply_filters,
inputs=[
image_input, filter_choice, brightness_slider, contrast_slider, sharpening_slider,
blur_slider, hue_shift_slider, watercolor_size_slider, watercolor_sigma_slider,
vignette_strength_slider, vignette_aspect_ratio_slider, vignette_center_x_slider,
vignette_center_y_slider, vignette_radius_slider, vignette_smoothness_slider,
tint_color_picker, tint_intensity_slider
],
outputs=image_output
)
vignette_smoothness_slider.change(
apply_filters,
inputs=[
image_input, filter_choice, brightness_slider, contrast_slider, sharpening_slider,
blur_slider, hue_shift_slider, watercolor_size_slider, watercolor_sigma_slider,
vignette_strength_slider, vignette_aspect_ratio_slider, vignette_center_x_slider,
vignette_center_y_slider, vignette_radius_slider, vignette_smoothness_slider,
tint_color_picker, tint_intensity_slider
],
outputs=image_output
)
tint_color_picker.change(
apply_filters,
inputs=[
image_input, filter_choice, brightness_slider, contrast_slider, sharpening_slider,
blur_slider, hue_shift_slider, watercolor_size_slider, watercolor_sigma_slider,
vignette_strength_slider, vignette_aspect_ratio_slider, vignette_center_x_slider,
vignette_center_y_slider, vignette_radius_slider, vignette_smoothness_slider,
tint_color_picker, tint_intensity_slider
],
outputs=image_output
)
tint_intensity_slider.change(
apply_filters,
inputs=[
image_input, filter_choice, brightness_slider, contrast_slider, sharpening_slider,
blur_slider, hue_shift_slider, watercolor_size_slider, watercolor_sigma_slider,
vignette_strength_slider, vignette_aspect_ratio_slider, vignette_center_x_slider,
vignette_center_y_slider, vignette_radius_slider, vignette_smoothness_slider,
tint_color_picker, tint_intensity_slider
],
outputs=image_output
)
# Update visibility of sliders when filter_choice changes
filter_choice.change(
update_slider_visibility,
inputs=[filter_choice],
outputs=[
blur_slider, hue_shift_slider, watercolor_size_slider, watercolor_sigma_slider,
vignette_strength_slider, vignette_aspect_ratio_slider, vignette_center_x_slider,
vignette_center_y_slider, vignette_radius_slider, vignette_smoothness_slider,
tint_color_picker, tint_intensity_slider
]
)
app.launch()