更新日から1年以上経過しています。情報が古い可能性がございます。
こんなツイートを見ました。
子供に即興でぬりえを作ってやれるのが漫画家のいいところ pic.twitter.com/QNkvcDdV9R
— 横山了一@3日目東ミ22-ab (@yokoyama_bancho) 2017年11月2日
え、エンジニアだってぬりえ作れるんだからねっ!
と言う、無駄な対抗心を燃やしてみました。
あ、ツイートは埋め込みなら無許可引用可能という利用規約に則っています。
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を使うと良い感じにしてくれるかもしれません。
お子さんのいる方、正月に親戚の小さい子供にぬりえをあげたい方、
是非活用してみてください。
絵を描くスキルが無いなら、コーディング技術で解決だっ!