Kasasagi’s memorandum

JavaとかProcessingとか。最近はAtcoderとか。

らりょすをビスケットに焼き付けた話

この記事はらりょすAdvent Calendar の14日目の記事です。

誰ですか?

鬼の手下です(伝わるか?)


らりょすさん

高専界隈で著名なのでTwitterをフォローしたら、フォロバしてくれたのでいい人なんだと思います。

そこにいるわけでもないのに、#procon28 や #procon29 の会場で「らりょす」というフレーズを何度も耳にしたので、とても有名人なんだと思います。

去年のAdvent Calendarを観てておもしろかったので、今年は書かせていただくことにしました。


本題

高専祭でビスケットに3Dプリンターで絵を焼き付けるという展示がありました。

ビスケットもクッキーも本質は一緒だろということでらりょすさんを焼き付けることにしました。


データの作成

ビスケットに焼き付けるには、線のデータを作成する必要があります。画像処理を用いて解決することにしました。PythonOpenCVを利用します。

ソースコード

import cv2

im = cv2.imread('img/raryosu.jpg')
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)

img = cv2.medianBlur(imgray,5)
_,thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
_,contours,_ = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

imfig = cv2.drawContours(im, contours, -1, (0,255,0), 1)

cv2.imwrite('raryosu_bin.png',thresh)
cv2.imwrite('raryosu_edge.png',imfig)

2値化には大津アルゴリズムというものを用い、閾値を自動的に決定しています。
あとは輪郭を検出して、描画している感じです。

実行結果はこちら。

f:id:yh9092:20181209135118p:plainf:id:yh9092:20181209135955p:plain

うまくいってませんね。
どうやら元画像の明るさが均一でないため、2値化がうまくいかなかったようです。
そこで、次の手法をとることにしました。


適応型閾値処理

画像を小領域に切り分け、領域ごとに閾値を計算する手法です。

ソースコード

import cv2

im = cv2.imread('img/raryosu.jpg')
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)

img = cv2.medianBlur(imgray,5)
thresh = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,11,2)
_,contours,_ = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

imfig = cv2.drawContours(im, contours, -1, (0,255,0), 1)

cv2.imwrite('raryosu_bin.png',thresh)
cv2.imwrite('raryosu_edge.png',imfig)

領域ごとに光源の強さが変化するような画像では、この方法で良い結果が得られます。
実行してみます。

<実行結果>
f:id:yh9092:20181209140847p:plain

ということで、モダンアートの完成です。

おわり















ません。

入力画像を使いやすそうなコラ画像にして実行すると、こうなりました。(2次利用してごめんなさい)

f:id:yh9092:20181209141310p:plainf:id:yh9092:20181209141317p:plain

ということで、これで完成とします。

あとはsvg形式に変換して、3Dプリンターに投げると、自動で印刷してくれます。


結果

思ったよりオリジナルっぽくなりました。
らりょすさんの反応はこちら。

ちなみにビスケットはちゃんと割ってからいただきました。


明日はco_rantan1131さんの記事です。

それでは。