この記事でscratchからOpenCVを使って画像をアニメ化してみます。基本的な手順は、画像の輪郭を抽出するー画像を減色処理、ノイズ減少処理するーこの2つを結合することです。

1.OpenCVをインストールする

1)Anaconda Promptを開く

2)Anaconda Promptで以下のコマンドよりOpenCVをインストールする

pip install opencv-python

2.元画像の読み出し

1)必要なライブラリをインポートする

import cv2
import numpy as np
import matplotlib.image as img
from matplotlib import pyplot as plt

2)元画像の読み出し

以下のコードで画像が出てきます。

img=cv2.imread("icon.jpg")
cv2.imshow("img",img)
cv2.waitKey()
cv2.destroyAllWindows()

1628496761(1).png

3.輪郭を抽出する

まず、cv2.cvtColorより元画像をグレースケールに変換します。さらに、cv2.medianBlur関数より平滑化処理します。最後に、cv2.adaptiveThresholdえ()を使って輪郭を抽出します。

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray_blur = cv2.medianBlur(gray,7)
edges = cv2.adaptiveThreshold(gray_blur, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY,7,7)

以下のコードで抽出した輪郭を見てみます。

cv2.imshow("edges",edges)
cv2.waitKey()
cv2.destroyAllWindows()

598dc10a7060938729383af31f6f6df.png

グレースケール画像と平滑化した画像もチェックしてみます。

1628497975(1).png

1628498012(1).png

4.減色処理する

アニメ化画像の色の数量は元画像より少ないべきです。こちらでK-means法を使って減色処理をします。8個の色にしたいなので、kの値を8にします。以下のコードで減色処理をしました。

data = np.float32(img).reshape((-1, 3))
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 20, 0.001)
ret, label, center = cv2.kmeans(data, 8, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
center = np.uint8(center)
result = center[label.flatten()]
result = result.reshape(img.shape)

以下のコードで減色処理した結果を見てみます。

cv2.imshow("result",result)
cv2.waitKey()
cv2.destroyAllWindows()

f1146b7fcc71147433aa85d93b45e3b.png

5.ノイズを消す

このステップで、cv2.bilateralFilterを使って画像のノイズを消します。生成された画像の解像度を下げます。

blurred = cv2.bilateralFilter(result, d=10, sigmaColor=250,sigmaSpace=250)

以下のコードで生成された画像を見てみます。

cv2.imshow("blurred",blurred)
cv2.waitKey()
cv2.destroyAllWindows()

29e6310675f015ab95d0911adfcfa3d.png

6.減色処理とノイズ減少処理した画像を輪郭と結合する

cv2.bitwise_and関数を使って減色処理とノイズ減少処理した画像を輪郭と結合します。

anime = cv2.bitwise_and(blurred, blurred,mask=edges)

最後のアニメ化した画像をチェックしてみます。

cv2.imshow("anime",anime)
cv2.waitKey()
cv2.destroyAllWindows()

9b15d9b96938d4168f747734a4b831d.png

アニメ化画像みたいと思います。