How to cartoonize an image with Python

In this tutorial, I will show you how to give a cartoon-effect to an image in Python with OpenCV.

OpenCV is an open-source python library used for computer vision and machine learning. It is mainly aimed at real-time computer vision and image processing. It is used to perform different operations on images which transform them using different techniques.

Many apps can turn your photos into cartoons, but you can do this on your own with few lines of code Python code.

This is our test image:

Let’s jump to the code.

<span>import</span> <span>numpy</span> <span>as</span> <span>np</span>
<span>import</span> <span>cv2</span>
<span>import</span> <span>numpy</span> <span>as</span> <span>np</span>
<span>import</span> <span>cv2</span>
import numpy as np import cv2

Enter fullscreen mode Exit fullscreen mode

after that we we read our image:

<span>filename</span> <span>=</span> <span>'</span><span>elon.jpeg</span><span>'</span>
<span>filename</span> <span>=</span> <span>'</span><span>elon.jpeg</span><span>'</span>
filename = 'elon.jpeg'

Enter fullscreen mode Exit fullscreen mode

then we will define our resizeImage :

<span>def</span> <span>resizeImage</span><span>(</span><span>image</span><span>):</span>
<span>scale_ratio</span> <span>=</span> <span>0.3</span>
<span>width</span> <span>=</span> <span>int</span><span>(</span><span>image</span><span>.</span><span>shape</span><span>[</span><span>1</span><span>]</span> <span>*</span> <span>scale_ratio</span><span>)</span>
<span>height</span> <span>=</span> <span>int</span><span>(</span><span>image</span><span>.</span><span>shape</span><span>[</span><span>0</span><span>]</span> <span>*</span> <span>scale_ratio</span><span>)</span>
<span>new_dimensions</span> <span>=</span> <span>(</span><span>width</span><span>,</span> <span>height</span><span>)</span>
<span>resized</span> <span>=</span> <span>cv2</span><span>.</span><span>resize</span><span>(</span><span>image</span><span>,</span> <span>new_dimensions</span><span>,</span> <span>interpolation</span> <span>=</span> <span>cv2</span><span>.</span><span>INTER_AREA</span><span>)</span>
<span>return</span> <span>resized</span>
<span>def</span> <span>resizeImage</span><span>(</span><span>image</span><span>):</span>
    <span>scale_ratio</span> <span>=</span> <span>0.3</span>
    <span>width</span> <span>=</span> <span>int</span><span>(</span><span>image</span><span>.</span><span>shape</span><span>[</span><span>1</span><span>]</span> <span>*</span> <span>scale_ratio</span><span>)</span>
    <span>height</span> <span>=</span> <span>int</span><span>(</span><span>image</span><span>.</span><span>shape</span><span>[</span><span>0</span><span>]</span> <span>*</span> <span>scale_ratio</span><span>)</span>
    <span>new_dimensions</span> <span>=</span> <span>(</span><span>width</span><span>,</span> <span>height</span><span>)</span>
    <span>resized</span> <span>=</span> <span>cv2</span><span>.</span><span>resize</span><span>(</span><span>image</span><span>,</span> <span>new_dimensions</span><span>,</span> <span>interpolation</span> <span>=</span> <span>cv2</span><span>.</span><span>INTER_AREA</span><span>)</span>

    <span>return</span> <span>resized</span>
def resizeImage(image): scale_ratio = 0.3 width = int(image.shape[1] * scale_ratio) height = int(image.shape[0] * scale_ratio) new_dimensions = (width, height) resized = cv2.resize(image, new_dimensions, interpolation = cv2.INTER_AREA) return resized

Enter fullscreen mode Exit fullscreen mode

the we need to find contours:

<span>def</span> <span>findCountours</span><span>(</span><span>image</span><span>):</span>
<span>contoured_image</span> <span>=</span> <span>image</span>
<span>gray</span> <span>=</span> <span>cv2</span><span>.</span><span>cvtColor</span><span>(</span><span>contoured_image</span><span>,</span> <span>cv2</span><span>.</span><span>COLOR_BGR2GRAY</span><span>)</span>
<span>edged</span> <span>=</span> <span>cv2</span><span>.</span><span>Canny</span><span>(</span><span>gray</span><span>,</span> <span>30</span><span>,</span> <span>100</span><span>)</span>
<span>contours</span><span>,</span> <span>hierarchy</span> <span>=</span> <span>cv2</span><span>.</span><span>findContours</span><span>(</span><span>edged</span><span>,</span>
<span>cv2</span><span>.</span><span>RETR_EXTERNAL</span><span>,</span> <span>cv2</span><span>.</span><span>CHAIN_APPROX_NONE</span><span>)</span>
<span>cv2</span><span>.</span><span>drawContours</span><span>(</span><span>contoured_image</span><span>,</span> <span>contours</span><span>,</span> <span>contourIdx</span><span>=-</span><span>1</span><span>,</span> <span>color</span><span>=</span><span>1</span><span>,</span> <span>thickness</span><span>=</span><span>1</span><span>)</span>
<span>cv2</span><span>.</span><span>imshow</span><span>(</span><span>'</span><span>Image after countouring</span><span>'</span><span>,</span> <span>contoured_image</span><span>)</span>
<span>cv2</span><span>.</span><span>waitKey</span><span>(</span><span>0</span><span>)</span>
<span>cv2</span><span>.</span><span>destroyAllWindows</span><span>()</span>
<span>return</span> <span>contoured_image</span>
<span>def</span> <span>findCountours</span><span>(</span><span>image</span><span>):</span>

    <span>contoured_image</span> <span>=</span> <span>image</span>
    <span>gray</span> <span>=</span> <span>cv2</span><span>.</span><span>cvtColor</span><span>(</span><span>contoured_image</span><span>,</span> <span>cv2</span><span>.</span><span>COLOR_BGR2GRAY</span><span>)</span> 
    <span>edged</span> <span>=</span> <span>cv2</span><span>.</span><span>Canny</span><span>(</span><span>gray</span><span>,</span> <span>30</span><span>,</span> <span>100</span><span>)</span>
    <span>contours</span><span>,</span> <span>hierarchy</span> <span>=</span> <span>cv2</span><span>.</span><span>findContours</span><span>(</span><span>edged</span><span>,</span> 
    <span>cv2</span><span>.</span><span>RETR_EXTERNAL</span><span>,</span> <span>cv2</span><span>.</span><span>CHAIN_APPROX_NONE</span><span>)</span>
    <span>cv2</span><span>.</span><span>drawContours</span><span>(</span><span>contoured_image</span><span>,</span> <span>contours</span><span>,</span> <span>contourIdx</span><span>=-</span><span>1</span><span>,</span> <span>color</span><span>=</span><span>1</span><span>,</span> <span>thickness</span><span>=</span><span>1</span><span>)</span>
    <span>cv2</span><span>.</span><span>imshow</span><span>(</span><span>'</span><span>Image after countouring</span><span>'</span><span>,</span> <span>contoured_image</span><span>)</span>
    <span>cv2</span><span>.</span><span>waitKey</span><span>(</span><span>0</span><span>)</span>
    <span>cv2</span><span>.</span><span>destroyAllWindows</span><span>()</span>

    <span>return</span> <span>contoured_image</span>
def findCountours(image): contoured_image = image gray = cv2.cvtColor(contoured_image, cv2.COLOR_BGR2GRAY) edged = cv2.Canny(gray, 30, 100) contours, hierarchy = cv2.findContours(edged, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) cv2.drawContours(contoured_image, contours, contourIdx=-1, color=1, thickness=1) cv2.imshow('Image after countouring', contoured_image) cv2.waitKey(0) cv2.destroyAllWindows() return contoured_image

Enter fullscreen mode Exit fullscreen mode

after that, we do a color quantization:

<span>def</span> <span>ColorQuantization</span><span>(</span><span>image</span><span>,</span> <span>K</span><span>=</span><span>4</span><span>):</span>
<span>Z</span> <span>=</span> <span>image</span><span>.</span><span>reshape</span><span>((</span><span>-</span><span>1</span><span>,</span> <span>3</span><span>))</span>
<span>def</span> <span>ColorQuantization</span><span>(</span><span>image</span><span>,</span> <span>K</span><span>=</span><span>4</span><span>):</span>
    <span>Z</span> <span>=</span> <span>image</span><span>.</span><span>reshape</span><span>((</span><span>-</span><span>1</span><span>,</span> <span>3</span><span>))</span> 
def ColorQuantization(image, K=4): Z = image.reshape((-1, 3))

Enter fullscreen mode Exit fullscreen mode

then we convert image to numpy float32:

<span>Z</span> <span>=</span> <span>np</span><span>.</span><span>float32</span><span>(</span><span>Z</span><span>)</span>
    <span>Z</span> <span>=</span> <span>np</span><span>.</span><span>float32</span><span>(</span><span>Z</span><span>)</span> 
Z = np.float32(Z)

Enter fullscreen mode Exit fullscreen mode

also we need to define critera and apply kmeans:

<span>criteria</span> <span>=</span> <span>(</span><span>cv2</span><span>.</span><span>TERM_CRITERIA_EPS</span> <span>+</span> <span>cv2</span><span>.</span><span>TERM_CRITERIA_MAX_ITER</span><span>,</span> <span>10000</span><span>,</span> <span>0.0001</span><span>)</span>
<span>compactness</span><span>,</span> <span>label</span><span>,</span> <span>center</span> <span>=</span> <span>cv2</span><span>.</span><span>kmeans</span><span>(</span><span>Z</span><span>,</span> <span>K</span><span>,</span> <span>None</span><span>,</span> <span>criteria</span><span>,</span> <span>1</span><span>,</span> <span>cv2</span><span>.</span><span>KMEANS_RANDOM_CENTERS</span><span>)</span>
    <span>criteria</span> <span>=</span> <span>(</span><span>cv2</span><span>.</span><span>TERM_CRITERIA_EPS</span> <span>+</span> <span>cv2</span><span>.</span><span>TERM_CRITERIA_MAX_ITER</span><span>,</span> <span>10000</span><span>,</span> <span>0.0001</span><span>)</span>
    <span>compactness</span><span>,</span> <span>label</span><span>,</span> <span>center</span> <span>=</span> <span>cv2</span><span>.</span><span>kmeans</span><span>(</span><span>Z</span><span>,</span> <span>K</span><span>,</span> <span>None</span><span>,</span> <span>criteria</span><span>,</span> <span>1</span><span>,</span> <span>cv2</span><span>.</span><span>KMEANS_RANDOM_CENTERS</span><span>)</span>
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10000, 0.0001) compactness, label, center = cv2.kmeans(Z, K, None, criteria, 1, cv2.KMEANS_RANDOM_CENTERS)

Enter fullscreen mode Exit fullscreen mode

then we convert to uint8 and apply to original image:

<span>center</span> <span>=</span> <span>np</span><span>.</span><span>uint8</span><span>(</span><span>center</span><span>)</span>
<span>res</span> <span>=</span> <span>center</span><span>[</span><span>label</span><span>.</span><span>flatten</span><span>()]</span>
<span>res2</span> <span>=</span> <span>res</span><span>.</span><span>reshape</span><span>((</span><span>image</span><span>.</span><span>shape</span><span>))</span>
<span>return</span> <span>res2</span>
   <span>center</span> <span>=</span> <span>np</span><span>.</span><span>uint8</span><span>(</span><span>center</span><span>)</span>
   <span>res</span> <span>=</span> <span>center</span><span>[</span><span>label</span><span>.</span><span>flatten</span><span>()]</span>
   <span>res2</span> <span>=</span> <span>res</span><span>.</span><span>reshape</span><span>((</span><span>image</span><span>.</span><span>shape</span><span>))</span>

   <span>return</span> <span>res2</span>
center = np.uint8(center) res = center[label.flatten()] res2 = res.reshape((image.shape)) return res2

Enter fullscreen mode Exit fullscreen mode

<span>if</span> <span>__name__</span> <span>==</span> <span>"</span><span>__main__</span><span>"</span><span>:</span>
<span>image</span> <span>=</span> <span>cv2</span><span>.</span><span>imread</span><span>(</span><span>filename</span><span>)</span>
<span>resized_image</span> <span>=</span> <span>resizeImage</span><span>(</span><span>image</span><span>)</span>
<span>coloured</span> <span>=</span> <span>ColorQuantization</span><span>(</span><span>resized_image</span><span>)</span>
<span>contoured</span> <span>=</span> <span>findCountours</span><span>(</span><span>coloured</span><span>)</span>
<span>final_image</span> <span>=</span> <span>contoured</span>
<span>save_q</span> <span>=</span> <span>input</span><span>(</span><span>"</span><span>Save the image? [y]/[n] </span><span>"</span><span>)</span>
<span>if</span> <span>save_q</span> <span>==</span> <span>"</span><span>y</span><span>"</span><span>:</span>
<span>cv2</span><span>.</span><span>imwrite</span><span>(</span><span>"</span><span>cartoonized_</span><span>"</span><span>+</span> <span>filename</span><span>,</span> <span>final_image</span><span>)</span>
<span>print</span><span>(</span><span>"</span><span>Image saved!</span><span>"</span><span>)</span>
<span>if</span> <span>__name__</span> <span>==</span> <span>"</span><span>__main__</span><span>"</span><span>:</span>

    <span>image</span> <span>=</span> <span>cv2</span><span>.</span><span>imread</span><span>(</span><span>filename</span><span>)</span>
    <span>resized_image</span> <span>=</span> <span>resizeImage</span><span>(</span><span>image</span><span>)</span>
    <span>coloured</span> <span>=</span> <span>ColorQuantization</span><span>(</span><span>resized_image</span><span>)</span>
    <span>contoured</span> <span>=</span> <span>findCountours</span><span>(</span><span>coloured</span><span>)</span>
    <span>final_image</span> <span>=</span> <span>contoured</span>
    <span>save_q</span> <span>=</span> <span>input</span><span>(</span><span>"</span><span>Save the image? [y]/[n] </span><span>"</span><span>)</span>

    <span>if</span> <span>save_q</span> <span>==</span> <span>"</span><span>y</span><span>"</span><span>:</span>

        <span>cv2</span><span>.</span><span>imwrite</span><span>(</span><span>"</span><span>cartoonized_</span><span>"</span><span>+</span> <span>filename</span><span>,</span> <span>final_image</span><span>)</span>
        <span>print</span><span>(</span><span>"</span><span>Image saved!</span><span>"</span><span>)</span>
if __name__ == "__main__": image = cv2.imread(filename) resized_image = resizeImage(image) coloured = ColorQuantization(resized_image) contoured = findCountours(coloured) final_image = contoured save_q = input("Save the image? [y]/[n] ") if save_q == "y": cv2.imwrite("cartoonized_"+ filename, final_image) print("Image saved!")

Enter fullscreen mode Exit fullscreen mode

This is our final result:

Thank you all.

原文链接:How to cartoonize an image with Python

© 版权声明
THE END
喜欢就支持一下吧
点赞14 分享
The reason why a great man is great is that he resolves to be a great man.
伟人之所以伟大,是因为他立志要成为伟大的人
评论 抢沙发

请登录后发表评论

    暂无评论内容