pencildrawer / app.py
GandalfTheBlack's picture
Update app.py
685757b verified
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()