祝! 補間計画発動

~真っ昼間からうれしさのあまり叫び声をあげたケモノ~

 え~と、このページはホントに真面目な話になっちゃうし、画像も使っているので、興味ない方はホントにつまんないと思います。
 でも、できれば見て欲しいな、なんて…。てゆうか、即戻る→ いや、むしろ今すぐゲットなりぃ

 すでに壁紙チェンジャーの旧バージョンで拡大表示をやってみた人は気づいているでしょうが、今までは何も補間していませんでした。
 いわゆるフルカラー24ビットのWindows標準ビットマップというものは、1ドットの点の色を、R(赤)G(緑)B(青)の3つの要素で表しています。
 RGBそれぞれの要素は256階調で、0~255の値をとります。
 (R, G, B) = (0, 0, 0) が黒を表し、(R, G, B) = (255, 255, 255) が白を表すというのはご存じだと思います。

 んで、今まではただ単に色の要素を倍率分だけ伸ばして拡大していたんですよ。
 たとえば、もとの画像パターンが、

  (0, 0, 0), (1, 1, 1), (2, 2, 2), (3, 3, 3) ※()内が1ドット。

 だとして、これを2倍に拡大しようとしたら、

  (0, 0, 0), (0, 0, 0), (1, 1, 1), (1, 1, 1), (2, 2, 2), (2, 2, 2), (3, 3, 3), (3, 3, 3)

 という風になっていました。
 今の例では、横方向だけに伸ばしましたが、通常、多くの場合において、画像は縦横両方向に伸ばします。
 するとどうなるでしょう。
 わかりやすいように、実際の絵を一部拡大したものをお見せしましょう。

オリジナルの画像(832×624)

 これを、1024×768に普通に拡大するとこうなってしまいます。

 見て解るとおり、とっても粗いです。
 倍率としては、約1.2倍ほどですが、これほどの差が出てしまいます。

 そこで、私は画像の補間方法にラグランジュ補間という方法を用いました。
 簡単に説明しますと、ある点の座標(複数)を与えて、それらをなめらかに結ぶ曲線を描くわけです。
 グラフ用紙に、点をプロットして、それを自在定規で結ぶようなものです。
 この場合は平面ですね。パラメータが2つ(X軸、Y軸)しかないですから。

 んじゃ、画像も同じかなと思っちゃいけません。

 画像の場合は「色」という3番目のパラメータが存在します。
 そうです、3次元で考えないといけないんです。
 しかも、画面いっぱいに表示したい(壁紙にしたい)と思う画像は、得てしてそれなりの大きさがあります。
 倍率が2倍を越えるなんてことは滅多にありません。1.2~1.8ぐらいがほとんどです。
 さらにさらに、ほとんどの場合が無限小数になってしまうんです。

 てことは、まず精度が悪くなります。
 次に、計算速度が遅くなります(数値計算は 加減算 < 乗算 < 除算の順に遅い)。
 要するに、浮動小数点を扱うメリットが無いんです。
 RGBの各成分は1バイトですから、小数値は絶対にとれませんし。

 いろいろ考えました。雑誌も読みあさりました。HPもいろんな所行きました。

 ようやくサンプルを見つけたんですが、それは浮動小数を使わずに、固定小数でやってました。
 C言語の規格に固定小数点はないのよね。
 解析するのに一苦労しましたよ。

 それを改変して、どうにかした結果の画像がこれです。
 必死に計算速度を上げようとしましたが、4秒縮めるのが精一杯でした(このテストでは約7.7秒)。

さらに拡大
補間無しの場合

 どうです、ちょっとはマシになってるでしょ?

 ちなみに、Paint Shop Pro 4.2Jでリサンプリングした画像がこれです。

 さすがにこっちの方がきれいです。
 でも、等倍でみればそれほど遜色ないです。

タイトルとURLをコピーしました