どんな画像も謎ノ美兎になるページを作った

どんな画像も謎ノ美兎になる。元画像がピクセルの並べ替えで謎ノ美兎に変わる3段階
目次

どんな画像も謎ノ美兎になるページ

導入

ミコンスキー

月ノ美兎さんの画像が、謎ノ美兎に変化してほしい…と思ったことはありませんか?

ミコンスキー

ということで、作ってみました!

上のページで「画像を読み込む」から好きな画像を選ぶと、ピクセルを並べ替えるだけで謎ノ美兎に組み変わります。色は1つも足していませんし、捨ててもいません。

ざっくり言うと、元画像のピクセルを1マスずつ「どこに座らせれば謎ノ美兎に見えるか」決めて、そこまで動かしているだけです。

元画像のピクセルが散らばりながら移動し、謎ノ美兎の形に並び替わる3段階
左から 元画像(元の配置)/移動中/並べ替え後(初期設定のまま)

最初から最後まで、使っている色は同じです。変わっているのは置き場所だけ。詳しい仕組みは後半で説明します。

謎ノ美兎の元ネタ動画:つきのみと没カット集(月ノ美兎)

この記事で分かること

  • 元ネタ「obamify」が何をしているか
  • 並べ替えだけで別の画像になる仕組み
  • 同じ結果を再現できるパラメータ

元ネタ:obamify

元ネタは、ノルウェーのクリエイターSpu7Nixさんが公開した「obamify」です。どんな画像もオバマ元大統領の顔に変えてしまうツールで、ソースはGitHubでRust製のものが公開されています。

今回はその考え方を参考に、ブラウザで動く版をゼロから書きました。コードの流用ではなく、別実装です。

元ネタとの違い

項目obamifyこのツール
動作環境デスクトップアプリ、Web版ブログ記事内のウィジェット
解法厳密解(ハンガリアン法)と高速な近似の2種高速な近似(山登り法)のみ
動きの演出全ピクセルが移動時間差「ずらし」とイージングを追加

仕組み:やっているのは「席替え」だけ

このツールがやっているのは、元画像のピクセルを目標画像のどのマスに座らせるか決める「席替え」です。数学的には割当問題と呼ばれます。

席替えのイメージ:同じ25枚のタイルを並べ替えて顔にする元画像の配置並べ替え後濃い色3枚・赤5枚・薄い色17枚(左右で同じ)
図1 タイルは1枚も増えず減らず、置き場所だけが変わる(イメージ図)

良い席替えの基準

各マスについて「色のズレ」と「動いた距離」のペナルティを足し、全体の合計が小さいほど良い席替えとします。

\text{cost} = \sum_{j} \Big( \lVert c_{\text{src}}(s_j) - c_{\text{tgt}}(j) \rVert^2 + \big( k \, \lVert p(s_j) - p(j) \rVert^2 \big)^2 \Big)
  • 前半は色のズレ。RGBを0〜1にして差の2乗を取る
  • 後半は移動のペナルティ。距離の2乗をさらに2乗するので、実質は距離の4乗
  • kは画面上の「移動のしにくさ」×0.22。座標は画像の幅を1として正規化

4乗なのがポイントです。少し動くのはほぼタダですが、画面の反対側まで飛ぶと急に高くつきます。そのため元画像の配置が「地模様」として残ります。

動いた距離と移動のペナルティ0123400.250.50.751色のズレの最大値 3(白と黒)4分の1動いても 0.03約0.78で色のズレの最大を超える動いた距離(画像の幅=1)ペナルティ
図2 移動のしにくさ13(k=2.86)のとき。距離の4乗なので、近場の移動はほぼタダ

解き方:入れ替えて良くなれば採用

  1. 最初は元画像そのままの配置から始める
  2. ランダムにマスを1つ選び、探索半径の中からもう1つ選ぶ
  3. 2つを入れ替えて合計コストが下がるなら採用、上がるなら戻す
  4. 一定回数ごとに探索半径を0.99倍にする
  5. 半径が1マスを切ったら終了
入れ替えの判定:2マスを入れ替えてコストが下がれば採用① 2マスを選ぶAB赤枠=探索半径の中からBを選ぶ② 入れ替えて比べる入れ替え前のコストA の席 + B の席入れ替え後のコストB の席 + A の席後のほうが小さい → 採用大きい → 元に戻す
図3 これを1世代あたり「マス数×24回」くり返す(計算の丁寧さ「標準」)

探索半径は最初「マス数の半分」です。64×64なら32マスから始まり、約345世代で1マスまで縮みます。最初に大まかな構図が決まり、後半で細部が整う流れです。

世代ごとの探索半径(64×64)081624320100200300最初は32マス:大まかな構図345世代で終了:細部世代探索半径(マス)
図4 64×64では半径32マスから始まり、345世代で1マスを切って終わる

動きは「席までの移動」を補間しているだけ

席替えが決まれば、あとは各ピクセルを元の座標から新しい席まで動かすだけです。このツールでは、ピクセルごとに出発をずらす「ずらし」を足して、崩れて組み上がる感じを出しています。

実測:「移動のしにくさ」で何が変わるか

移動のしにくさを0、13、30で比べると、どれも謎ノ美兎と分かる形になり、違いは元画像の残り方に出ました。

移動のしにくさの比較。左から元画像、移動のしにくさ0、13、30、目標の謎ノ美兎
左から 元画像/0/13/30/目標

測定条件:64×64マス、計算の丁寧さ「標準」(1世代あたりマス数×24回)、乱数シード12345。元画像は月ノ美兎さんの配信サムネイルを、両目が謎ノ美兎のマスクの目に重なるように切り抜いて使用。

移動のしにくさ見た目
0距離を気にせず色だけで席を選ぶので、赤い文字のピクセルが服や顔に大きく飛び散る
13(初期値)謎ノ美兎の形を保ちつつ、赤がまとまって残る
30元の場所から動きにくくなり、赤い文字が画面下側に固まって残る

元画像の「雑談(5時間)」の赤い文字が、謎ノ美兎の服や指先の赤に流れ込むのが見どころです。目標にない色は、近い色の席に妥協して座るためです。

自分の画像で試す

目標画像も自分で選べる汎用版を置いています。顔同士なら、両目の位置が近い画像ほどきれいにまとまります。

使い方のコツ

  • 画像は中央で正方形に切り抜かれるので、顔が中央にある画像が向いている
  • 目標画像に多い色が元画像に少ないと、その部分は近い色で埋まる
  • スマホでは64×64のままが無難。128×128は計算量が約4倍
  • 画像はブラウザの中だけで処理され、サーバーには送られない

再現条件

乱数の種を固定しているので、同じ画像と同じ設定なら毎回同じ結果になります。

パラメータ値
乱数xorshift32、シード12345
マスの数48×48/64×64(初期値)/96×96/128×128
移動のしにくさ0〜50、初期値13。式の k = 値 × 0.22
探索半径初期値=マス数の半分、1世代ごとに0.99倍、1未満で終了
1世代の試行回数マス数 × 8(速い)/24(標準)/64(丁寧)
色の扱いRGBを0〜1に正規化、透明部分は白として扱う
切り抜き中央で正方形
イージングイーズインアウト(三次)/オーバーシュート(係数1.70158)/リニア

※ ブラウザが画像を縮小するときの補間方式はブラウザごとに微妙に違うため、ブラウザをまたぐと結果がわずかに変わることがある。

クレジット

どんな画像も謎ノ美兎になる。元画像がピクセルの並べ替えで謎ノ美兎に変わる3段階

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA


日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

目次