「C#でつるぺったん」のフォローアップ
過去作った動画を見てたら、フォトモザイクを生成していくプログラムが4万回再生されてたのを記念して(懐かしさもこめて)フォローアップしてみました。
今見るとかなりプログラムに甘いところがありますが、(あんまりいいPCを使っていなかったため普通に生成したら遅いので)当時行った高速化に用いた手法を書いておくと、下記3点でしょうか。
- 色はランダムサンプリングで抽出
- 最初に色と画像を対応する辞書を生成
- kd-treeの生成
最初の色の抽出は、基本は(32×32などの)適当な範囲を選択してランダムの値でピクセルを選んでいく方法をとっています。
今回の場合、対象としている絵がアニメ調なので隣り合う色は同じ色である可能性が高いです。なので、8ピクセルくらいの適当な定数でスキップさせた後ランダム値を足して選択していったと思います。(というより、高速に生成するためにわざわざアニメ調で、かつ、なるべく色の変化のないやつを選んでました。)
次に、なるべくスムーズなインタラクションを可能にするために、プログラムの起動時に色に対応する画像を割り当てた辞書を作ってました。
あとは、画像をズームイン/アウトする際、最小の計算コストにするためにkd-treeでインデックスを作ってたり。
ただ、最初に述べたように結構甘いところがあるので、
- スレッド数を増やす(上の動画のプログラムは、UIスレッドとワーカースレッドだけなので)
- kd-treeを見直す
- GPUを使う
のようなことをすればもっとよりよいものになるかなーと思います。
特に2番目のkd-treeは、C++言語で書いたネイティブコードをC#から逐一呼んでるので、今回の場合はC#側でツリーを持ちたいです。(ちなみにここで作ったkd-treeは、その後修正したものを、Apricotで使ってたりします)
あと、GDI+を使ってたので3番目のようなGPUを使ってれば、もっとズームイン/アウトのトランジション(拡大縮小)をスムーズにすることが出来たと思います。というかこの後GPU版を作ったので出来ました。(→http://d.hatena.ne.jp/kawatan/20070917)
最後に、動画を作って思ったのは、プログラムを動かしながらフォトモザイクを見るのと動画でフォトモザイクを見るのとでは全然違うのが面白いです。
具体的には、プログラムを動かしながら見る時より動画で見る場合は元画像のピクセルに対する画像を4倍以上増やさないとフォトモザイクを生成してるようには見えないのです。
これ以外にもロジックなどは動画では見えなかったりで、プログラムを動画で伝えるのって、ほんと難しいですねー