OpenCV Tutorial
Image Processing
Feature Detection and Description
Drawing Functions
Video Processing
Applications and Projects
Turning an image into a cartoon-like visualization can be a fun project to understand multiple techniques within computer vision. In this tutorial, we'll transform an image into its cartoon version using OpenCV in Python.
Setup: If you haven't installed OpenCV, do so using pip:
pip install opencv-python
Read the Image: Start by reading the image.
import cv2 img = cv2.imread("path_to_image.jpg")
Apply a Bilateral Filter: Bilateral filters are great at preserving edges while reducing color noise. We'll use it to give our image a smooth appearance.
# Apply bilateral filter with d=9, sigmaColor=sigmaSpace=75 filtered_img = cv2.bilateralFilter(img, d=9, sigmaColor=75, sigmaSpace=75)
Convert Image to Grayscale & Apply Median Blur: The idea here is to detect and enhance the edges. So, we first convert the image to grayscale and then apply a median blur to reduce image noise.
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) blurred_gray = cv2.medianBlur(gray, 7)
Use Adaptive Thresholding: To detect and enhance the edges in the image, we'll use adaptive thresholding.
edges = cv2.adaptiveThreshold(blurred_gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, blockSize=9, C=2)
Convert Edges to Color Image: We need the edges in the same format (3-channel) as the filtered image to merge them.
color_edges = cv2.cvtColor(edges, cv2.COLOR_GRAY2BGR)
Cartoon Effect: Subtract the color edges from the filtered image to give a cartoon effect.
cartoon = cv2.bitwise_and(filtered_img, color_edges)
Display the Results:
cv2.imshow("Original Image", img) cv2.imshow("Cartoon Image", cartoon) cv2.waitKey(0) cv2.destroyAllWindows()
When you run the entire sequence, you should see two windows: one with the original image and another with the cartoon version of the image.
This process gives a simple cartoon effect. You can experiment with the parameters in the bilateral filter, median blur, and adaptive thresholding to fine-tune the effect according to your needs.
Edge detection helps identify prominent edges in the image, creating a sketch-like effect.
import cv2 import numpy as np def edge_detection(image): # Convert the image to grayscale gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Apply GaussianBlur to reduce noise and improve edge detection blurred = cv2.GaussianBlur(gray, (5, 5), 0) # Use Canny edge detector edges = cv2.Canny(blurred, 50, 150) return edges
Color quantization reduces the number of colors in the image to give it a more cartoonish appearance.
def color_quantization(image, k=9): # Reshape the image to a 2D array of pixels pixels = image.reshape((-1, 3)) # Convert to float32 for k-means pixels = np.float32(pixels) # Define criteria and apply k-means criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.2) _, labels, centers = cv2.kmeans(pixels, k, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS) # Convert back to 8-bit values centers = np.uint8(centers) # Map the labels to the centers segmented_image = centers[labels.flatten()] # Reshape back to the original image shape segmented_image = segmented_image.reshape(image.shape) return segmented_image
Combine the edge-detected image and the color-quantized image to create the final cartoon effect.
def cartoonize_image(image): # Step 1: Edge Detection edges = edge_detection(image) # Step 2: Color Quantization quantized = color_quantization(image) # Combine the edges and color-quantized image cartoon = cv2.bitwise_and(quantized, quantized, mask=edges) return cartoon
Load an image and apply the cartoonize function.
# Load an image image = cv2.imread('input_image.jpg') # Cartoonize the image cartoon_image = cartoonize_image(image) # Display the original and cartoonized images cv2.imshow('Original Image', image) cv2.imshow('Cartoonized Image', cartoon_image) cv2.waitKey(0) cv2.destroyAllWindows()
Experiment with parameters like kernel size, Canny thresholds, and the number of colors (k) in k-means for fine-tuning.
The bilateral filter can be used for smoothing while preserving edges in the cartoonized image.
def cartoonize_with_bilateral(image): # Step 1: Edge Detection edges = edge_detection(image) # Step 2: Apply Bilateral Filter for smoothing smooth = cv2.bilateralFilter(image, d=9, sigmaColor=300, sigmaSpace=300) # Combine the edges and smoothed image cartoon = cv2.bitwise_and(smooth, smooth, mask=edges) return cartoon