Turn Photos into Cartoons with OpenCV and Python

Want to transform your images into a fun, cartoon-like style with just a few lines of Python code? In this post, you‘ll learn how to build your own "cartoonify" tool using OpenCV, an open-source computer vision library. By the end, you‘ll have a simple app that can take any image and convert it to a cartoon automatically!

We‘ll cover the key computer vision techniques powering the cartoon effect under the hood, and walk through the Python code step-by-step. Let‘s jump in!

What is OpenCV?

OpenCV (Open Source Computer Vision Library) is a popular open-source library for computer vision and machine learning. It provides a wide range of features and functions for image and video processing tasks.

Some key things OpenCV is great for:

  • Face, object, and text detection
  • Image filtering, transformations, and other manipulations
  • Feature detection and matching
  • Deep learning integration (e.g. using pre-trained models)

OpenCV has interfaces for many programming languages including Python, Java, and C++. In this post, we‘ll use Python and OpenCV together to process and transform images into cartoons.

Cartoonify Process Overview

At a high level, here are the main steps our Python script will perform to cartoonify an input image:

  1. Convert the image from color to grayscale
  2. Apply Gaussian blur to smooth the grayscale image
  3. Detect edges in the blurred grayscale image
  4. Apply a bilateral filter to the original color image to reduce noise while preserving edges
  5. Create a mask by combining the edge image and the color image
  6. Combine the color image and edge mask to get the final cartoon effect

We‘ll see the code for each step in the next section. The key OpenCV functions we‘ll use are:

  • cv2.cvtColor() to convert between color spaces
  • cv2.GaussianBlur() to apply Gaussian smoothing
  • cv2.adaptiveThreshold() to detect edges
  • cv2.bilateralFilter() to reduce noise while preserving edges
  • cv2.bitwise_and() to mask the color image with detected edges

Python Code Walkthrough

Let‘s break down the Python script piece by piece. We‘ll use OpenCV 4.7.0 which is the latest version as of 2024.

First, import the required libraries:

import cv2
import numpy as np
import tkinter as tk
from tkinter import filedialog
from PIL import ImageTk, Image

In addition to OpenCV (cv2) and NumPy, we import Tkinter to create the GUI for loading images.

Next, define a function to load the image file selected by the user:

def load_image():
    file_path = filedialog.askopenfilename()
    img = cv2.imread(file_path)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    return img

This uses Tkinter‘s filedialog to open a file browser window. We read the selected image using cv2.imread and convert it from BGR to RGB color space.

Now the main cartoonify function:

def cartoonify(img):
    # Convert to grayscale
    gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)

    # Apply Gaussian blur
    gray = cv2.GaussianBlur(gray, (5, 5), 0)

    # Detect edges
    edges = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, 
                                  cv2.THRESH_BINARY, 9, 9)

    # Apply bilateral filter
    color = cv2.bilateralFilter(img, 9, 300, 300)

    # Combine color image and edges for cartoon effect 
    cartoon = cv2.bitwise_and(color, color, mask=edges)

    return cartoon

This function takes a color image as input and returns the cartoonified version. Let‘s go through it step-by-step:

  1. Convert the image to grayscale using cv2.cvtColor. Grayscale reduces the image to a single channel, which is useful for edge detection.

  2. Apply a Gaussian blur to the grayscale image using cv2.GaussianBlur. This reduces noise and smooths the image. We use a 5×5 kernel size.

  3. Detect edges in the blurred grayscale image using cv2.adaptiveThreshold. This finds areas where intensity changes sharply. We use the mean adaptive thresholding algorithm with an 9×9 neighborhood size.

  4. Apply a bilateral filter to the original color image using cv2.bilateralFilter. This reduces noise while preserving edges. We use a filter size of 9 and large sigmaColor and sigmaSpace values of 300 to get a strong cartoon effect.

  5. Create the cartoon image by combining the color image and edge mask using cv2.bitwise_and. This masks the color image with the edges to get the final effect.

Finally, let‘s create a basic GUI to load images and display the cartoon version:

# Create the main window 
window = tk.Tk()
window.title("Cartoonify")

# Create a button to load image
btn_load = tk.Button(window, text="Load Image", command=load_and_cartoonify)
btn_load.pack(pady=10)

# Create a label to display the image
lbl_img = tk.Label(window)
lbl_img.pack()

window.mainloop()

This creates a simple window with a "Load Image" button. When clicked, it calls a load_and_cartoonify function (not shown) that loads the selected image, applies the cartoonify transformation, and displays the result in the lbl_img label.

And that‘s it! With just a few dozen lines of code, we‘ve created a fun tool to turn any photo into a cartoon.

Customizing the Cartoon Effect

By adjusting the parameters to the OpenCV functions, you can customize the appearance of the cartoon effect. Some things to try:

  • Increasing the kernel size of the Gaussian blur (e.g. (7, 7)) will make the cartoon look smoother and less detailed
  • Decreasing the threshold block size in adaptiveThreshold (e.g. 5) will detect finer edges
  • Lowering the sigmaColor and sigmaSpace in bilateralFilter (e.g. 150) will preserve more of the original colors

Play around with the values to get a range of different styles!

Ideas for Extending the Project

This cartoon effect is just the beginning. Here are some ideas for taking it further:

  • Cartoonify videos by applying the effect to each frame. You can use OpenCV‘s VideoCapture to read video frames.
  • Apply the cartoon filter in real-time to a webcam feed. This would make a fun "cartoon mirror."
  • Train a neural style transfer model to cartoonify images in the style of your favorite cartoon. You‘d need a dataset of cartoon images to train on.
  • Make an animated cartoon by extracting the edges and filling them in with solid colors based on the average color of each region.

The possibilities are endless! Feel free to get creative and experiment.

Conclusion

In this post, you learned how to use OpenCV and Python to transform regular photos into cartoon-style images automatically. We covered:

  • What OpenCV is and how it‘s useful for computer vision and image processing
  • The step-by-step process to get a cartoon effect: grayscale conversion, blurring, edge detection, bilateral filtering, and masking
  • The Python code to implement each step clearly and concisely
  • How to make a user-friendly GUI for loading images with Tkinter
  • Ideas for customizing the effect and extending it to new applications

Equipped with these key techniques and concepts, you‘re ready to start building your own computer vision and image manipulation tools! Continue your learning journey with these recommended resources:

Happy coding!

How useful was this post?

Click on a star to rate it!

Average rating 5 / 5. Vote count: 1

No votes so far! Be the first to rate this post.

Similar Posts