DEV Community

A0mineTV
A0mineTV

Posted on

Transform Your Images into Pencil Sketches with Python 🚀

Have you ever wondered how to create a pencil sketch effect from an image programmatically? With Python and some powerful libraries, you can achieve this in just a few lines of code! In this article, I'll walk you through a simple script that transforms any image into a pencil sketch using grayscale conversion, Gaussian blur, and a dodge blending effect.


📜 The Concept Behind Pencil Sketching

The pencil sketch effect relies on simulating how light and shadow interact in hand-drawn sketches. Here's the breakdown:

  1. Convert the image to grayscale: Remove all colors to simplify the image to shades of gray.
  2. Invert the grayscale image: Create a negative effect where light becomes dark and vice versa.
  3. Apply a Gaussian blur: Blur the inverted image to soften details.
  4. Dodge blending: Blend the blurred image with the original grayscale to simulate pencil strokes.

🚀 Python Implementation

Here's the Python code that does it all:

import numpy as np
import imageio.v2 as imageio  # Explicit use of imageio.v2
import cv2
import scipy.ndimage


def convert_to_grayscale(rgb_image):
    """
    Converts an RGB image to grayscale.
    """
    return np.dot(rgb_image[..., :3], [0.299, 0.587, 0.114])


def apply_dodge(front_layer, back_layer):
    """
    Applies the 'dodge' effect to create a pencil sketch effect.
    """
    result = front_layer * 255 / (255 - back_layer)
    result[result > 255] = 255
    result[back_layer == 255] = 255
    return result.astype('uint8')


def pencil_sketch(image_path, output_path, blur_sigma=10):
    """
    Generates a pencil sketch effect from an image.

    Args:
        image_path (str): Path to the input image.
        output_path (str): Path to the output image.
        blur_sigma (float): Sigma for the Gaussian blur (defines the blur level).
    """
    # Load the image
    original_image = imageio.imread(image_path)

    # Convert to grayscale
    grayscale_image = convert_to_grayscale(original_image)

    # Invert the colors
    inverted_image = 255 - grayscale_image

    # Apply Gaussian blur
    blurred_image = scipy.ndimage.gaussian_filter(inverted_image, sigma=blur_sigma)

    # Apply the dodge effect
    final_image = apply_dodge(blurred_image, grayscale_image)

    # Save the resulting image
    cv2.imwrite(output_path, final_image)
    print(f"The image has been saved to '{output_path}'.")


# Example usage
if __name__ == "__main__":
    input_image = "test.jpeg"
    output_image = "test_coloring.png"
    pencil_sketch(input_image, output_image)
Enter fullscreen mode Exit fullscreen mode

🔍 Understanding the Functions

1. Grayscale Conversion

The function convert_to_grayscale uses a weighted sum to convert an RGB image into grayscale. This replicates human perception, where green contributes the most, followed by red, and then blue.

np.dot(rgb_image[..., :3], [0.299, 0.587, 0.114])
Enter fullscreen mode Exit fullscreen mode

2. Dodge Effect

The apply_dodge function lightens the grayscale image, mimicking pencil strokes. It ensures pixel values stay within valid bounds (0-255).

def apply_dodge(front_layer, back_layer):
    result = front_layer * 255 / (255 - back_layer)
    result[result > 255] = 255
    result[back_layer == 255] = 255
    return result.astype('uint8')
Enter fullscreen mode Exit fullscreen mode

3. Gaussian Blur

The blur effect softens the details of the inverted image, helping create smoother pencil strokes. It is achieved using the scipy.ndimage.gaussian_filter function, where the sigma parameter controls the intensity of the blur.

blurred_image = scipy.ndimage.gaussian_filter(inverted_image, sigma=blur_sigma)
Enter fullscreen mode Exit fullscreen mode

🖼️ Example Usage

Save the script as pencil_sketch.py, then run it with the following setup:

python main.py
Enter fullscreen mode Exit fullscreen mode

Input:

Place an image (e.g., test.jpeg) in the same directory.

Output:

The output will be saved as test_coloring.png, a beautiful pencil sketch version of the input image.


🛠️ Tips for Customization

  • Adjust Blur Intensity: The blur_sigma parameter controls the level of detail in the sketch. A lower value retains more details, while a higher value creates a smoother sketch.
pencil_sketch("input.jpg", "output.png", blur_sigma=15)
Enter fullscreen mode Exit fullscreen mode
  • Error Handling: Add checks to handle invalid paths or unsupported formats.
if not os.path.exists(image_path):
    raise FileNotFoundError("The input image file does not exist.")
Enter fullscreen mode Exit fullscreen mode
  • Performance Boost: Use OpenCV's cv2.cvtColor for faster grayscale conversion if performance is critical.

🌟 Resources


🔮 Conclusion

This script showcases how Python's versatile libraries can simplify complex image processing tasks. Whether you're a beginner or a seasoned developer, transforming images into pencil sketches is a fun and rewarding project. So, why not try it out with your favorite pictures ?

Top comments (0)