105

Painting and Sketching with OpenCV in Python

 4 years ago
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.
neoserver,ios ssh client

Painting and Sketching with OpenCV in Python

Make art like oil and watercolor painting, draw sketches, and create Pointillist art using OpenCV in Python.

juUbE3i.jpg!web

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)

Bn6FviR.jpg!web

Original Image

fUFFJb2.jpg!web

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

jEneQbA.jpg!web

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

RjeEjqq.jpg!web

Black and white sketch

7rIFFfI.jpg!web

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)

bymEFbn.jpg!web

Original Image

7F7rye.jpg!web

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:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK