# 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("

📸 Photo Filter ⭐

") gr.Markdown("

Apply professional photo filters with adjustable brightness, contrast, and sharpness. Perfect your images instantly!

") # 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()