import gradio as gr import cv2 import numpy as np class ImageToSketchEffect: """Transform an image to mimic the effect of a sketch drawn with a pencil.""" def __init__( self, blur_strength: int = 5, blur_kernel_size: tuple = (0, 0), edge_enhance_level: int = None, custom_sharpen_kernel: np.ndarray = None, ): self.blur_strength = blur_strength self.blur_kernel_size = blur_kernel_size self.edge_enhance_level = edge_enhance_level self.sharpen_kernel = np.array([[0, -1, 0], [-1, edge_enhance_level, -1], [0, -1, 0]]) if custom_sharpen_kernel is None else custom_sharpen_kernel def blend_mode_dodge(self, top_layer: np.ndarray, bottom_layer: np.ndarray) -> np.ndarray: output = bottom_layer * 255.0 / (255.0 - top_layer) output[output > 255] = 255 output[bottom_layer == 255] = 255 return output.astype('uint8') def enhance_edges(self, img: np.ndarray) -> np.ndarray: if self.edge_enhance_level is not None and isinstance(self.edge_enhance_level, int): inverse_image = 255 - img return 255 - cv2.filter2D(src=inverse_image, ddepth=-1, kernel=self.sharpen_kernel) return img def apply_sketch_effect(self, image: np.ndarray) -> (np.ndarray, np.ndarray): grayscale_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) inverted_image = 255 - grayscale_image blurred_image = cv2.GaussianBlur(inverted_image, ksize=self.blur_kernel_size, sigmaX=self.blur_strength) sketch_image = self.blend_mode_dodge(blurred_image, grayscale_image) sketch_image = self.enhance_edges(sketch_image) blurred_for_alpha = cv2.GaussianBlur(sketch_image, (5, 5), 0) if len(blurred_for_alpha.shape) == 3 and blurred_for_alpha.shape[2] == 3: blurred_for_alpha = cv2.cvtColor(blurred_for_alpha, cv2.COLOR_BGR2GRAY) _, alpha_mask = cv2.threshold(blurred_for_alpha, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) final_sketch_transparent = cv2.merge((blurred_for_alpha, blurred_for_alpha, blurred_for_alpha, alpha_mask)) return sketch_image, final_sketch_transparent def process_image(image, blur_strength, blur_kernel_size, edge_enhance_level): sketch_effect = ImageToSketchEffect(blur_strength, (blur_kernel_size, blur_kernel_size), edge_enhance_level) return sketch_effect.apply_sketch_effect(image) iface = gr.Interface(fn=process_image, inputs=[gr.Image(), gr.Slider(1, 10, value=7), gr.Slider(3, 25, step=2, value=15), gr.Slider(1, 10, value=7)], outputs=[gr.Image(type="numpy", label="Pencil Sketch"),gr.Image(type="numpy", label="Transparent Pencil Sketch")], title="Image to Sketch Converter", description="Upload an image to convert it into a pencil sketch.") if __name__ == "__main__": iface.launch()