SSブログ

ランダムドットステレオグラムアプリ - その11 [ランダムドットステレオグラムアプリ]

佳境に入ったランダムドットステレオグラムアプリ。実装に突入する。

2  実装

さて、実装。

2.1  入力データの形式

Height mapがユーザから与えられるとする。その方法は
  • グレーのビットマップイメージ(具体的にはTIFFやPNGなど)
  • CSV形式
  • 適当なデリミタを持ったテキスト形式
なんかで表現してもらって、それを読み込むことにする。CSVは一般的な形式を前提にすると難しいので、単にコンマで数値が区切られたものだけを読み込むことにする。どのみちそれ以外のデータが含まれていてもどうしようもない。

読み込んだデータはすべて左から右、さらにそれが上から下へ並んでいると解釈する。

ほんとはGISのデータを読めるようにすれば地図の標高をステレオグラムに変換できるので、面白いんだけど、GISは汎用性が高く、構造が複雑で標高データに変換するだけでもめんどくさい。ファイル形式はXMLなのでFoundationフレームワークに備わったXMLの解析クラスを使えば簡単に読めるんだけど、それでもかなりの手間がかかる。気がむいたらやることにする(ということはやらないと言っているに等しいんだけど)。

2.2  エレベーションマップの内部形式

読み込んだエレベーションマップは内部形式に変換する。といってもそんな大げさなものではなく、floatの配列。その際
  • 配列の縦横の長さ
  • 値の最大値と最小値
  • 深さ方向表現の感度
を保持して配列の中身そのものは[0,1]に規格化してしまう。

もし、データが0をまたいだら、その「0」の輻輳がマーカの輻輳と一致するように最終的な描画を行う。これはまたあとで整理する。

深さ方向表現の感度とは、エレベーションマップの最大高さがどのくらい飛び出して見えるようにするか、という量でこれまでαという定数で代表させていた。これはユーザに別途指定してもらうか、指定がない場合にも表示できるようにデフォルトの値を決めておく。

2.3  表示の中間形式

アルゴリズムの整理のところで導入したD(pq)の配列を作る。これもfloatの配列で十分。アルゴリズム通りに実装できるので、それほど問題はないだろう。

2.4  テクスチャデータ

テクスチャデータfloatの配列として生成する。値は[0, 1]区間におさめる。

テクスチャは曲線迷路を作ったときのをそのまま流用するが、今回は
  • グレー
  • カラー(RGB)
  • バイナリ
の3種類から選べるようにする。昨日書いたようにFFTでは高い空間周波数が含まれない。眠い絵になりがちで見た目が退屈なのでもう一種類、バイナリと同じような非線形処理をしたカラーを増やすことにする。これは昨日の思いつき。

2.4.1  グレー

グレーは曲線迷路とまったく同じに生成する。ただし、生成後規格化する、つまり
  • 最小値を0
  • 最大値を1
にマップし直す。アルゴリズムの整理のところで書いたコントラストの最大化の作業である。

2.4.2  カラー

カラーはRGB3チャンネルそれぞれにグレー生成と同じことをするだけである。

2.4.3  バイナリ

バイナリはグレーを生成した後、平均値を閾値にして0と1に2値化する。平均値はグレーを生成する過程でFourier変換側の原点の値を覚えておけばいい。

2.4.4  生成のパラメータ

パラメータは
  • 画像の幅(輻輳の距離)
  • グレー/カラー/バイナリの選択
  • 縦横の粒度
ぐらい。もちろんテクスチャの高さはHeight Mapの高さと一致させる。

2.4.5  外部データの使用

テクスチャを自動生成するのではなく、外部の画像データを読み込んでそれをテクスチャとして利用できるようにしたほうがいいだろう。しかしこの場合、こまかな問題がいろいろおこる。
  • エレベーションマップの高さと画像データの高さが違う場合(というかそれが普通だろう)にどうするか
  • 画像データの横幅と輻輳距離を合わせるかどうか
  • 組み合わせによって縦横比を保持できなくなるが、保持するようなオプションを設けるか
  • 場合によっては輻輳が大きすぎたり小さすぎたりするのをどう扱うか
などという煩わしい事態になる。とりあえずver.1は外部データを読み込むのはやめよう。ということはこれも、もうやらないと言っているに等しいんだけど。

2.5  ステレオグラムデータ

ステレオグラムS(pq)は直接表示できるようにNSBitmapImageRepのサブクラスとして実装するのがいいだろう。しかしNSBitmapImageRepはcomponentの型がfloatのカラーデータをサポートしてないので、RGB各8ビットの形式に変換する必要がある。ということはどうせだからグレーもバイナリも8ビットに統一したほうが楽ではある。

そう考えるとテクスチャデータをfloatではなく8ビット符号なし整数にしたほうが相性はいいけど、補間のことがあるのでこっちはfloatのまま残しておくのがいいだろう。

2.5.1  NSBitmapImageRepのサブクラス化

また例のごとくサブクラスにするのがいいか、カテゴリでいいか、それとも新しいクラスでNSBitmapImageRepを保持しているのがいいか、は実際にコーディングをする段階で決めることにする。今回はカテゴリで十分という気もする。

2.6  表示のオプション

その他に表示に関連してユーザに指定してもらう必要のあるパラメータがある。
  • 縦横の入れ替え/上下の反転
  • 縦方向のグリッド
  • その他
ほんとは座標軸なんかも描きたいけど、輻輳距離が切りのいい値でない限りうまく描くことができない。これはあきらめる。

縦横の入れ替えというのは、Height Mapの2次元配列を90°回転するかどうかを指定する。上下反転は単にデータが上から並んでるか下から並んでるかの違いを吸収するためのもの。どちらもデフォルトでは行列を表示するのと同じにする。

縦方向のグリッドというのは決まった高さに対応する輻輳距離に細線でグリッドを引く。上に金網を張ったような表現になって目の調整がやりやすくなる場合がある。いつもそうとは限らないけど。

2.7  ユーザインターフェイス

アプリを書くたびにユーザインターフェイスをどうするか、というのはいつも悩む。なるべく素直にドキュメントアプリにしたいけど、以前の迷路生成アプリのように、なにかを作るだけで編集しないアプリというのはドキュメントスタイルからちょっとはずれることになって、それをどういう表現にするか、というのは難しい。迷路生成アプリは「新規メニュー」でいったん生成のために基礎となるデータをまず入力させるダイアログを表示している。これがMacOSXアプリらしくない動作になっている。

今回も編集はないアプリなので、同じ悩みを抱えることになる。

今回は「新規」はなしで、「開く」だけにするか。まず最初にエレベーションマップのファイルを指定して始めるというかたち。そうすると、「開く」のダイアログでほかのパラメータも全部一緒に指定するようになっていないといけない。

で、開いてしまうとすぐステレオグラムをそのパラメータにしたがって生成して表示する。そしてパラメータ変更のためにパネルを表示して、そのうえでパラメータを書き換えると表示に反映させる、というのがいいだろうな。あまり大きなマップだとFFTが律速して、テクスチャ生成に時間がかかることになる。中間配列を使うことにしたので、深さ方向表現の感度を変えない限りはテクスチャを変更してもマッピングはそれほど重くないはず。

それほど複雑なアプリではないので、こんなもんでいいだろう。

さくっと実装してみよう。って、今から始めると徹夜になってしまう。い、いかん、いかん。明日は早いのでさっさと寝ることにする。
nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

献立07/24献立07/25 ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。