エンジニアだって子供にぬりえを作れるぞ

更新日から1年以上経過しています。情報が古い可能性がございます。

こんなツイートを見ました。

え、エンジニアだってぬりえ作れるんだからねっ!
と言う、無駄な対抗心を燃やしてみました。
あ、ツイートは埋め込みなら無許可引用可能という利用規約に則っています。

OpenCVでぬりえを作る

という訳でやっていきましょう。
Python使いなので、PythonでOpenCVを使っていきます。

使用バージョンは以下の通り。
・Python 3.6.3
・numpy 1.13.3
・OpenCV 3.3.0
・matplotlib 2.1.0

ぬりえにする画像は何でも良いのですが、
今回はいらすとやさんのサーバルを用いてみます。

では必要なモジュールをインポートしていきましょう。

import numpy as np
import cv2

from matplotlib import pyplot as plt
%matplotlib inline

plt.rcParams['figure.figsize'] = (10, 10)

グレースケールで読み込む

サーバルの画像は、Jupyterワークスペースにdataと言うフォルダを作り、
そこに入れています。

img = cv2.imread('data/animal_serval.png', cv2.IMREAD_GRAYSCALE)
plt.imshow(img, cmap='gray')

グレースケールになりました。
これを基に加工していきます。

膨らます

フィルターを掛けて画像の輪郭を膨らませます。
フィルターはこんな感じの物を用意します。

neiborhood4 = np.array([[0,1,0],
                        [1,1,1],
                        [0,1,0]],np.uint8)
neiborhood8 = np.array([[1,1,1],
                        [1,1,1],
                        [1,1,1]],np.uint8)
neiborhood24 = np.ones((5, 5), dtype=np.uint8)

これは近隣のピクセルをどう処理するかのフィルターです。
細い線が欲しければneiborhood4を、太い線が欲しいときはneiborhood24を用います。
今回はneiborhood24を使っていきます。

dilated = cv2.dilate(img, neiborhood24, iterations=1)
plt.imshow(dilated, cmap='gray')


グレースケール画像との違いが分かりにくいのですが、輪郭線が広がっています。

元画像との差分を取る

続いて元画像との差分を取っていきます。

diff = cv2.absdiff(dilated, img)
plt.imshow(diff, cmap='gray')

はい、それっぽくなってきましたね。

白黒反転

各ピクセルは0~255の階調となっているので、255から減算することで反転できます。
このデータ構造はnp.ndarrayとなっているため、数値と減算すると全ピクセルに適応してくれます。

contour = 255 - diff
plt.imshow(contour, cmap='gray')

はい、ぬりえの完成です!
最後に画像ファイルとして出力します。

cv2.imwrite('nurie.png', contour)

最後に

これでエンジニアでも簡単にぬりえを作ることができました。
線を濃くしたいときは、cv2.thresholdを使うと良い感じにしてくれるかもしれません。

お子さんのいる方、正月に親戚の小さい子供にぬりえをあげたい方、
是非活用してみてください。

絵を描くスキルが無いなら、コーディング技術で解決だっ!

コメントする

メールアドレスが公開されることはありません。