Painting and Sketching with OpenCV in Python
source link: https://towardsdatascience.com/painting-and-sketching-with-opencv-in-python-4293026d78b?gi=535b8191a05c
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Painting and Sketching with OpenCV in Python
Make art like oil and watercolor painting, draw sketches, and create Pointillist art using OpenCV in Python.
Jul 20 ·4min read
Photo by Geordanna Cordero on Unsplash
OpenCV is a powerful computer vision library with a strong image processing toolkit. In this article, we will utilize it to create drawings and paintings and most of them will be using in-built functions! Let’s keep the introduction short and move straight into the exciting part.
Table of Contents
- Requirements
- Oil Painting effect
- Watercolor Effect
- Black and white and colored pencil sketches
- Pointillist art
Requirements
The oil painting effect requires OpenCV Contrib modules while others can be performed using the standard distribution of OpenCV. Other than that, the pointillist art requires Sklearn and Scipy.
pip install opencv-contrib-python==4.3.0.36 pip install scikit-learn pip install scipy
Oil Painting Effect
It is included in cv2.xphoto()
which also has several other cool functions like image inpainting, white balance, image denoising, etc.
import cv2img = cv2.imread('img.jpg') res = cv2.xphoto.oilPainting(img, 7, 1)
Original Image
Oil Painting Effect
Watercolor Effect
Like the oil painting effect, the watercolor effect can also be done with a single line of code excluding the imports and image reading. It is done by cv2.stylization()
.
import cv2img = cv2.imread('img.jpg') res = cv2.stylization(img, sigma_s=60, sigma_r=0.6)# sigma_s controls the size of the neighborhood. Range 1 - 200# sigma_r controls the how dissimilar colors within the neighborhood will be averaged. A larger sigma_r results in large regions of constant color. Range 0 - 1
Watercolor effect
Black and White and Colored Pencil Sketches
Again with just a line of code, we get great sketches both in grayscale and color.
import cv2 img = cv2.imread('img.jpg') dst_gray, dst_color = cv2.pencilSketch(img, sigma_s=60, sigma_r=0.07, shade_factor=0.05) # sigma_s and sigma_r are the same as in stylization.# shade_factor is a simple scaling of the output image intensity. The higher the value, the brighter is the result. Range 0 - 0.1
Black and white sketch
Colored sketch
Pointillist art
According to Wikipedia , pointillist art can be defined as:
Pointillism is a technique of painting in which small, distinct dots of color are applied in patterns to form an image
To do this in Python, our first step is to compute the most used colors for which Kmeans is used. I used a color palette of 20 which means that the dots will be made by 20 most used colors will be present in the image. A suitable radius size is calculated for the dots according to the image size. Then we loop over the image and find the color closest to the dot, using which the circle is drawn.
import scipy.spatial import numpy as np import random import cv2 import math from sklearn.cluster import KMeansdef compute_color_probabilities(pixels, palette): distances = scipy.spatial.distance.cdist(pixels, palette) maxima = np.amax(distances, axis=1)distances = maxima[:, None] - distances summ = np.sum(distances, 1) distances /= summ[:, None] return distancesdef get_color_from_prob(probabilities, palette): probs = np.argsort(probabilities) i = probs[-1] return palette[i]def randomized_grid(h, w, scale): assert (scale > 0) r = scale//2 grid = [] for i in range(0, h, scale): for j in range(0, w, scale): y = random.randint(-r, r) + i x = random.randint(-r, r) + j grid.append((y % h, x % w)) random.shuffle(grid) return griddef get_color_palette(img, n=20): clt = KMeans(n_clusters=n) clt.fit(img.reshape(-1, 3))return clt.cluster_centers_def complement(colors): return 255 - colorsdef create_pointillism_art(image_path, primary_colors): img = cv2.imread(image_path) radius_width = int(math.ceil(max(img.shape) / 1000)) palette = get_color_palette(img, primary_colors) complements = complement(palette) palette = np.vstack((palette, complements)) canvas = img.copy() grid = randomized_grid(img.shape[0], img.shape[1], scale=3) pixel_colors = np.array([img[x[0], x[1]] for x in grid]) color_probabilities = compute_color_probabilities(pixel_colors, palette)for i, (y, x) in enumerate(grid): color = get_color_from_prob(color_probabilities[i], palette) cv2.ellipse(canvas, (x, y), (radius_width, radius_width), 0, 0, 360, color, -1, cv2.LINE_AA) return canvasres = create_pointillism_art('img.jpg', 20)
Original Image
Result
The code for pointillist art is inspired by this GitHub repository with some changes.
So we saw that making art with OpenCV is a piece of cake especially using the inbuilt functions. If you want to see image editing operations using OpenCV you can refer to this article:
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK