本日はお姫ちん(四条貴音)の誕生日ですね。僕のお気に入りキャラの1人です。
今回はですね、ミリマスキャラの誕生日に自動的にTwitterのアイコンを変えるようなスクリプトを組んでみたのでちょっと紹介。 (ネタが無いんじゃ)
自分がキャラの誕生日にこんなに反応するようになるとは思っていませんでしたけどね。ミリマス恐ろしや~
ということで今回自動変更を行うためにやった手順は以下のとおりです。
こんな感じですね。上から順番に説明していきます。
1. グリマスのカード画像を一覧サイトから全キャラ分回収
まずはアイコンの素材となる画像を用意します。今回はグリマスのカード画像を使用します。
ただ、これって著作権云々があるので本当は自分で書いたほうがいいんですよね。まあ、見逃してください。
で、普通にグリマスから回収してもいいんですが、僕あのサイトをスクレイピング出来る程の技術は無いので一覧にしてくれているサイトから回収します。
こちらのサイトを使用させていただきます。
このサイトの構造について詳しく解説するとちょっとあれなので、軽くだけ...
Searchでキーワードにキャラ名を入れるとそのキャラのカードが一覧で出てきます。ちなみにキーワードはGETメソッドでURLに入ります。これが1つ目のポイント!
次にカードの画像はカードIDによって管理されており、ある規則に従ってサーバー上のディレクトリに保存されているようです。これが2つ目のポイント!
最後に画像にはフレーム有りと無しがあり、それぞれframe~とnoframe~という名前になっています。これが3つ目のポイント!
さて、これらを踏まえた上で作ったスクリプトがこちら
GitHubに上げてあります。download.pyが本体です。Python 3で書いてあります。てか、今回のスクリプトは全部Pythonっす
内容は1つ目の引数の内容で検索をして、一覧からカードID回収して、そのIDのカード画像を第2引数のフォルダーに保存するって感じです。
動かし方はざっくり言うとpipでbs4とwgetを入れて、上の説明で言った引数を与えて実行します。
で、実はこのサイトは検索ワードを何も指定しないと全カードが出るのですが、それだと後々面倒なのでキャラごとに1人ずつスクリプトを実行します。
それがdownload.batです。小鳥さんも含めた53人分を一気に実行します。ん?53人?
そうです、間違えて歌織さんと紬を入れてしまってますw
後々、フォルダーが必要になるので放置して実行しました。(何も入りません)
このままだと、歌織さんと紬の画像が無いので適当なサイトからミリシタのカード画像を持ってきて入れておきます。
これでとりあえずアイコンを作るための素材が集まりました。
※02/24追記:作業してて気づいたんですけど、恵美の読み方が「めぐみ」じゃなくて「えみ」になってますね。こんなキャラの名前を間違えるようなプロデューサーは穴掘って埋まってきますぅ~
2. カード画像からアイコンを自動生成
次にこれらの素材からアイコンを作るのですが、流石に全画像を見てトリミングしていくのは辛いですよね。
ということで、今回はTPTSで培った技術を使います。そうです、顔検出でアイコンを作ってしまいます。
普通のアイコンは顔が真ん中にあるといい感じになりますよね。ならない?
ならば、中心に顔検出した顔があれば立派なアイコンになると思ってやってみました。これも初の試みです。
説明をするより先にスクリプトを
なんかリポジトリを水増ししてる感じがありますけど、全部一応独立して動作するというか汎用性があるので...
こいつの動作にはopencv-python、dlib、joblibが必要なので入れてください。
あとはrawとiconというフォルダーを作って、rawにキャラ別フォルダーを入れます。フォルダー名がそのキャラのアイコン名になります。
あとはmain.pyを実行するだけ!CPUのコア数分ぶん回してくれます。
では、説明です。
まず、TPTSの根幹である顔検出(顔+目)にはdlibの物体検知を使用しています。これに使用しているモデルは自分で学習させたものです。
ということでこの根幹機能だけを抜き出して、ローカルにある画像に対して検出をかけるとこんな感じになります。
とてもいい感じ!杏奈かわいい!
なのですが、このままだと顔ギリギリを取りすぎなので領域を拡張します。今回は顔領域を中心として領域が4倍(縦横2倍)になるように広げました。
するとこうなります。
これならアイコンにした際にいい感じのサイズになりそうです。この領域を切り抜くようにします。
ですが、このままだとアイコンがカード枚数分出てしまいます。
今回はこれを回避するために切り抜いた際に一番大きいサイズのものだけをアイコンとして残すようにしました。
また、領域が広がった分別のキャラが入る可能性があるので、それを極力避けるため広げた後にもう一度顔検出を行っています。(実際は必要無かった可能性が)
これらを組み込んだスクリプト(リポジトリにあるやつ)を実行した結果がこちら!
うーん、とてもよい!
実は今回モデルを変えて3回ほど実行したのですが、どれも結果が変化してとても面白かったです。
おそらくTwitterを見ていた人なら知ってると思いますが...
その3回実行した中で一番良かった画像をアイコンとして採用しました。これでアイコン完成です。
(実はこの時点である問題が発生してます。プロデューサーの皆さんなら上の画像で気づくかと...)
3. キャラ名・誕生日・アイコン画像を一覧化
さて、ここまでくれば後は自動化するだけです。そのためには誕生日の一覧が必要になります。
ということで、さくっとcsvにして一覧にしました。そのファイルは後ほど紹介します。
で、この一覧を作成してる最中に先ほど言った問題に気づきました。
はい、亜美と真美が同じ誕生日なんですよね。双子だからねー
ということで、この2人に関してはいい感じのカードを自分でトリミングしました。
4. 日付を確認して自動で変更するスクリプトを組む
これが出来ればほぼ完成です。
今回は「日付確認→誕生日だったらそのキャラのアイコンに変更→誕生日が終了したら元のアイコンに変更」みたいな感じで組みました。
そのスクリプトがこちら
main.pyが本体です。birth.csvは先ほど作成した誕生日一覧です。
このスクリプトの実行にはtweepyが必要ですので、インストールしておきます。
で、重要なのがbirth.csvです。このファイルは「キャラ名,誕生日,アイコンファイルパス」が一覧で記載してあります。
main.pyの最初でこの一覧ファイルを元に辞書(連想配列)を作成します。今回はキーが誕生日で、値がキャラ名とファイルパスになっているという2つの辞書を作っています。
その後、日付を取得し、これをキーとして辞書に存在するか探します。
値が存在した、つまり誕生日であればアイコン変更処理となります。まず、元々設定してあるアイコンをicon.jpgとして保存しておきます。
ちなみに連続した日付であった(icon.jpgが存在した)場合は保存しません。
取得後にアイコンを変更し、そのキャラの誕生日であることをつぶやきます。
存在しなかった、つまり誕生日でなければ終了処理を行います。この時にicon.jpgが存在した場合、このアイコンに戻し、icon.jpgを削除します。これで元々のアイコンに戻ります。
こんな感じです。結構単純ですね。
5. サーバーに実装
で、これを適当に常時起動してPCなどに置いて日付変更時(0時)に実行するようにしておきます。
今回はcrontabを使用し、ここのサーバーに置きました。別にこの辺りは自由にしていただければいいかと...
はい、これで全部!
テストを全然してなかったので、初めて動かした時(今日)動かなかったりしましたが何とか完成しました。(実はアイコンが元に戻るかがテスト出来てない)
色々と分割しているので、「グリマスのカード画像が欲しい」「アイコンを自動で生成したい」「アイコンを自動で変化させたい」などにも対応出来ると思います。
僕的には、アイコンの元となった画像をアイコン変更時に一緒につぶやくのもありかなーって考えているのでそれを実装するかもしれません。
では