公式で配布されてるキルミーベイベーのTwitter用アイコンにK-meansかましてクラスタリングしてみた


半分遊びながら,お酒飲みながら書きました,ごめんなさい.ある日,キルミーベイベーのTwitter用アイコンが配布されたと聞きました.そういえば少し前に

screen-shot_tweet-1
https://twitter.com/k_m_baby/status/287813741649743873

みたいなことを公式アカウントが言っていたので,もしかしてこの作業をやっていたのかな?と思ってみたり.下の画像は実際に配布告知のつぶやきをしたものをキャプチャしてきたもの.
screen-shot_tweet-2
https://twitter.com/k_m_baby/status/292106025513914372

さてどうしたものか,と思いつつ,こういうものはあまり権利の関係上適当に遊ぶのはよくないような気がしたので,だいぶ悩んだのだけども,公式サイトが
screen-shot-1

と言っているのを見つけたので,そういう点は目をつぶって遊んでみた.

関係各所のリンク


1. 画像を集めてくる

公 式 サ イ ト か ら 
全 部 ダ ウ ン ロ ー ド し て く る 
(真 顔)
補足:面倒な人はクローラ{作る|使う}.

2. どうしようか考える

今回はクラスタリングしてみた.クラスタリングというのはデータを似てる者同士,グループに分ける操作.キルミーベイベーに登場するキャラの画像を見ながら「あ,これはやすなの画像」,「お,ソーニャちゃんの画像」,「あ,あぎりさんの画像だ〜」といってやっていくあの操作.もうちょっと抽象的に言うと,下の図みたいに同じ形に属しているもの,みたいなのに同じ色を塗るみたいな感じ.
clusters_11b_notitle2
(http://www.ml.uni-saarland.de/code/pSpectralClustering/pSpectralClustering.html より)


画像の特徴ベクトルを本当は求める必要があるが,今回は全ての画素(R,G,B)の値を平均したものを特徴ベクトルにした.特徴ベクトル(3次元)の間の距離は,普通のユークリッド距離を採用.マジメにやれというツッコミはなし…

3. OpenCVで画像を操作する方法を調べる

Mac上のPythonとHomebrewで入れたOpenCVで書いた.最近のバージョンだとcv2ちゃんのおかげで,
import cv2
imoprt numpy as np

if __name__ == '__main___':
    img = cv2.imread('filename.png')
    # numpyのarray上でのimgの操作をする

のように書くと,画像の画素情報が詰まった行列を返してくれる.楽ちん楽ちん.

4. K-meansの実装

具体的にはそのうちクソみたいなコード公開予定.
画像を表現した行列を平均して特徴ベクトルを割り出し,あとは用意した画像の間の距離を計算する.画像が5枚あると距離の組み合わせは5×4で20パターン計算しないといけない.といってもプログラムに計算させて自分は優雅にお酒でも飲んでるだけなのだけど.K-means中の流れは

  1. 初期値として各クラスタの中心(特徴ベクトル)を選ぶ.K個の画像をランダムに選んで利用する(random.sample)
  2. 以下を中心が動かなくなるまで繰り返す
    1. 各画像がどの中心に近いかどうかを計算する
    2. 各クラスタ毎に,そのクラスタに近いと判定された画像の特徴ベクトルを平均して,新しい中心を計算する.

5. 一部のデータを使ってテストしてみる: 100枚→6グループ

全部で680枚ほど公開されたとして,680枚から2つずつ距離を計算すると,おそらく20万ペアほど計算しないといけないので,一部の100枚弱を利用して計算してみる.一応Pythonのコード中では,一度計算したら後から再利用出来るように,pickleを使ってdumpしながら処理してた.実際に実行すると次みたいな画像になる.(あ,画像になるのはそう書いてるから)

ソーニャちゃんソーニャちゃんソーニャちゃんソーニャちゃんソーニャちゃんソーニャちゃん
cluster1


やすな…?
cluster4


あぎり…さん…?
cluster2


い け る … ?

6. 全部使って作ってみた

大 正 義 ソ ー ニ ャ

sonya


600枚を6グループに分けた場合の1枚.これは実際のところ,たまたまうまくまとまったように見えたもので,ソーニャちゃんの髪の色が面積も広くて特徴的なので,黄色が高い値になりやすいのでこうなります.もっと細かくグループ分け(例えば20グループとか)にすると,もっと上手く切れるものもあり,失敗するものもあると思います.実際,6グループのうち1つはなんでも入ってる(やすな+ソーニャ+あぎり+その他)みたいな感じの画像になりました.

まとめ

  • K-means+色平均ペクトル+ユークリッド距離によるクラスタリングを実装した
  • 意外といけた(小学生並みの感想)
  • OpenCV+Numpy+Python大正義
  • ソーニャちゃんマジ天使

作業時間等

  • データを集めてくる: 15分ぐらい
  • OpenCVの使い方を調べる: 15分ぐらい
  • Pythonの使い方を思い出す: 5分ぐらい
  • Numpyの使い方を思い出す: 15分ぐらい
  • 処理を書く: 2時間ぐらい
  • 600枚ぐらいの実行を待つ: 30分ぐらい
  • お酒を飲む: 作業中ずっと
  • 結果でニヤニヤする: 数分
  • ブログを書く: その後お酒飲みながら

ソースコード

  • 覚えていたら後日公開

返信を残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です