nikkie-ftnextの日記

イベントレポートや読書メモを発信

イベントレポート | #imas_hack にてPythonでアイドルのシルエットをアスキーアートっぽくしました

はじめに

いつも心は虹色に! nikkieです。
忙しい年の瀬ではありますが、アイマスハッカソンに参加してきました。
作りたいプロダクトのアイデアを一通り試すことができ、他の方の取り組みからエンジニアという副業をアイマスでハックするという視点に気づくことができました。

イベントの概要

【増枠】アイマスハッカソン2018 - connpass

プロデューサーの皆様のあふれんばかり愛を表現する場として今回のハッカソンを企画しました。
皆様のアイドルへの愛を表現する場として、 また同僚のアイドルへの愛を感じる場として、是非お楽しみください!

2016年の初回から存在は知っていたアイマスハッカソン
バリバリ活動されている方の中に入ることに参加前は不安も感じていました。
プロデューサーとして愛はあれども副業メインすぎるためです。
参加してみたところ、不安は杞憂で、1日楽しめました。

プロデューサーとしてのnikkie

取り組んだこと

ニコニコ動画で見た、アイドルのシルエットのアスキーアートをプログラムから自動生成することに取り組みました。

▼こんなアスキーアートを作りたい f:id:nikkie-ftnext:20181223003240j:plain

シルエットの切り出しについては、前日に触っています:イベントレポート | 第94回 #pyhack にてDjango Girls Tutorial Extensionで手を動かし、Background Removal APIを触りました - nikkie-ftnextの日記
シルエットが切り出された前提で、アスキーアートのように画像を加工することに取り組みました。

  • 色付きの四角と白い四角を並べて表現することにする(まずMVPを作る)
  • 色付きの四角はアイドルのイメージカラーとする2
  • 四角に置き換える際は、以前取り組んだモザイクアートのプログラムが流用できそう
  • まずシルエットを2色に減色する。四角で置き換えるため格子状に区切り、どちらの色が多いかで、色付きの四角で置き換えるか、白い四角で置き換えるか判断する

成果物

f:id:nikkie-ftnext:20181224232020p:plain

ソースコードはこちら:
20181223 #imas_hack · GitHub

開発環境

  • Python 3.6.6
  • jupyter==1.0.0
  • matplotlib==3.0.2
  • numpy==1.15.4
  • Pillow==5.3.0
  • scikit-learn==0.20.2

notebookのポイント

画像の原色処理には以下を使います。

Pillowを使う理由は、キャラクターを抜き出した画像の仕様によります。
remove.bg で抜き出しているのですが、背景の部分の画素はA(alpha 透過度)が0に設定されているだけで、RGBの色情報を持ちます。
次のQiita記事を試したところ、背景込みで2色に原色した画像ができました:【機械学習】scikit learnでの画像減色プログラム - Qiita
(なお、KMeansでのクラスタリングでRGBの値のみを使うのは妥当と考えています)
元の画像のAの情報を保持する必要があるようなので、opencvから使い慣れたPillowにスイッチしました。
減色後に元の画像と同様のAの値を設定することで背景を消すことができました。

減色処理に使う画素の範囲についても2通り考えられます。
一つは背景込みで全部の画素を使う方法、もう一つはA=0となっている背景の画素を除く方法です。
現時点ではどちらを使うかは画像によるという結論です。
ソースコード箱崎星梨花のケースでは全部の画素を使ったところイマイチだったので、背景の画素を除きました)

numpyでの画像の扱いについて

  1. Pillowで画像を読み込み、RGBAのタプルからなるリストを作る(画像の縦と横の情報を消し、一列に並べた状態):getdata
  2. 1のリストの各要素からRGBの値のみ取得して新たなリストを作る(このRGBのデータをクラスタリングに使う。ここで背景の画素を除く場合もある)
  3. 2のRGBのリストを行列に変換(2で画素を除いていない場合、サイズ:(画像の縦 × 横, 3チャネルRGB))
  4. 3の行列をKMeansに渡してクラスタリング。2色を見つける
  5. 3の行列について各画素がどちらの色になるか判定する。このとき1で読み込んだ画素のAの情報を追加する(2で画素を除いていない場合、サイズ:(画像の縦 × 横, 4チャネルRGBA)という行列ができる)
  6. 画像を表す状態に行列のサイズを変換する:reshape
  7. 行列からRGBAの画像に変換する:fromarray

5ではnp.uint8という型を指定する必要がありました。(これを指定しないと画像が表示されません)
また5でnp.append()を使って一次元配列の末尾に要素を追加するのにハマりました。
参考:配列末尾へ要素を追加するNumPyのappendの使い方 - DeepAge

第三引数を指定しないと第一、第二引数で指定された配列のshapeとは関係なく一次元配列が生成されます。

2色に減色した画像を色付きの四角と白い四角で作成する処理は、過去に作ったモザイクアートのプログラムをベースにしています。

  • 画像を5×5の格子に分割(余りが出ないようにするためにサイズが5の倍数になるようにcropしておく)
  • 減色処理のうちどちらの色が多いか数える。ここで多い方の色で塗ると減色した2色からなるモザイク調になる
  • 塗り方の指定をアイドルのイメージカラーと白色に変更(ここは人の目で見て対応させています)

改良点はいくつかありますが、アイデアが実現できたのでハッカソンでの進捗には満足しています。

  • ノートブックを複製しているので、パッケージ化する
  • 減色する色を3−4色に増やし、この色はイメージカラーの四角、この色は白い四角というように人の目で判断する
  • 四角以外の図形を導入してみる

あにべんLT再演しました

副業メインでも愛を叫びたかったので、5分LTしました。
「もう時間がないんです」を差し込んでもらえたり、春香カラーのサイリウム降っていただけたり、発表してよかったです。

他の方の取り組みから

今回参加して気づいたのはエンジニアという副業をアイマスでハックする視点です。
具体的には、

  • 新しい技術を触るときにアイマスへのコントリビュートを兼ねた開発をする(例:Vue.jsを触ってアイマスの〇〇を作る)
  • 開発体験をアイマスでハックする(テストデータにアイドルの名前を使うことでノッて開発できる)

の2つで、「個人開発の中に取り入れたいな」と思っています。

皆さんの取り組みは非常に興味深くて、

  • 曲同士の似た部分を判定
  • Dockerコンテナの名前をアイマスっぽくする

などなど、成果物が気になる取り組みがたくさんありました。
また、コードが書けることはコントリビュートに必須ではないことも分かりました。
Microsoft Flow」などノンコーディングなツールでカバーできるため、大事なのはコントリビュートしたい強い気持ちと言えそうです。

知った中で気になったものを挙げておきます。

感想

技術で真剣に遊ぶのはやっぱりいいですね。
もくもく会で少しずつでも積み上げてきたから、今回やりたいことが一通り実現できたのだと考えています。
全力で遊んで少しはできるようになった減色処理やnumpyでの画像の扱いが、エンジニアとしての幅を広げることにもなると考えています。

参加者は文脈を共有しているので、LTはめちゃくちゃ盛り上がりました。
LT中にアップルパイつまみ食いしちゃったり4、マイニング始めたりと、字面だけ見たらカオスすぎですが、楽しませていただきました。
LTを盛り上げられるのも、歴戦のプロデューサーだからこそだと思います。

会場スポンサーのSpeeeさん、オフィスの蔵書量がすごかったです。
図書館になっていて、同じ背表紙の色のオライリー本で各段が埋まっていて圧巻でした。
同じスペースでOSS Daysというイベントを定期的に開催されているそうで、またお邪魔してみたいです。

参加者、運営者、スポンサーの皆さま、1日どうもありがとうございました。
本当に楽しかったので、今後も参加していきたいです。


  1. いわしまんさんのブログ記事 【イベント】WEBエンジニア勉強会#10にお邪魔してきた話 - Rのつく財団入り口 より。ハッカソンに飛び込むのにこの言葉に背中を押していただきました。ありがとうございます。(次回お会いしたら、直接お礼をお伝えしよう)

  2. アイドルのイメージカラー - アイマスDB(情報まとめ)

  3. https://kotobank.jp/word/RDF-49

  4. 「アップルパイ・プリンセス」でアップルパイを作る - #つくりおき