Spaces:
Running
Running
import gradio as gr | |
import cv2 | |
import numpy as np | |
def process_image(image, blur, threshold, stroke_width, use_sobel, use_laplacian, contrast): | |
# Convert to grayscale | |
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) | |
# Adjust contrast | |
gray = cv2.convertScaleAbs(gray, alpha=contrast, beta=0) # Alpha controls contrast | |
# Apply Gaussian blur | |
ksize = blur * 2 + 1 | |
blurred = cv2.GaussianBlur(gray, (ksize, ksize), 0) | |
# Apply Sobel or Laplacian | |
if use_sobel: | |
edges = cv2.Sobel(blurred, cv2.CV_64F, 1, 1, ksize=5) | |
edges = cv2.convertScaleAbs(edges) | |
elif use_laplacian: | |
edges = cv2.Laplacian(blurred, cv2.CV_64F) | |
edges = cv2.convertScaleAbs(edges) | |
else: | |
# Default to Canny if no additional edge enhancement is selected | |
edges = cv2.Canny(blurred, threshold, threshold * 2) | |
# Dilate edges for thicker strokes | |
kernel = np.ones((stroke_width, stroke_width), np.uint8) | |
edges_dilated = cv2.dilate(edges, kernel, iterations=1) | |
# Invert for sketch effect | |
sketch = cv2.bitwise_not(edges_dilated) | |
sketch_bgr = cv2.cvtColor(sketch, cv2.COLOR_GRAY2BGR) | |
# Apply bilateral filter for cartoon effect | |
bilateral = cv2.bilateralFilter(image, 9, 75, 75) | |
cartoon = cv2.bitwise_and(bilateral, bilateral, mask=sketch) | |
return sketch_bgr, cartoon | |
with gr.Blocks() as demo: | |
with gr.Row(): | |
image_input = gr.Image(type='numpy', label="Upload Image") | |
with gr.Row(): | |
blur_slider = gr.Slider(1, 10, step=1, label="Blur", value=1) | |
threshold_slider = gr.Slider(50, 255, step=1, label="Threshold", value=100) | |
stroke_width_slider = gr.Slider(1, 10, step=1, label="Stroke Width", value=1) | |
contrast_slider = gr.Slider(0.5, 3.0, step=0.1, label="Contrast", value=1.0) | |
sobel_checkbox = gr.Checkbox(label="Use Sobel Filter", value=False) | |
laplacian_checkbox = gr.Checkbox(label="Use Laplacian Filter", value=False) | |
with gr.Row(): | |
sketch_output = gr.Image(type='numpy', label="Pencil Sketch") | |
cartoon_output = gr.Image(type='numpy', label="Cartoonized Image") | |
def update(image, blur, threshold, stroke_width, contrast, use_sobel, use_laplacian): | |
if image is None: | |
return None, None | |
sketch, cartoon = process_image(image, blur, threshold, stroke_width, use_sobel, use_laplacian, contrast) | |
return sketch, cartoon | |
inputs = [image_input, blur_slider, threshold_slider, stroke_width_slider, contrast_slider, sobel_checkbox, laplacian_checkbox] | |
outputs = [sketch_output, cartoon_output] | |
for component in inputs: | |
component.change(fn=update, inputs=inputs, outputs=outputs) | |
if __name__ == "__main__": | |
demo.launch() | |