|
|
●概要 空間フィルタは目星がついたのでランクフィルタの試作をした。 ●予備実験 取りあえず、現行方式をそのままC++に移行した。C++が担うのは、簡易輝度にした拡張済Long配列を受け取り、局所空間の画素濃度をソートし、指定順位の画素を結果バイト配列に格納すると言うもの。 そのため、新たに、クイックソート関数もC++で作成した。しかし、期待に反して、VB + マーシャル転送 より遅くなった。1.2〜1.5倍程度。ガックリ。 試しに、VB のArray.Sort メソッドと、C++ のクイックソートを省いて実行すると、C++ が断然速くなった。VB の3〜5 倍。原因は、クイックソートである。.NET のArray.Sort の方式は不明であるが、作成したクイックソートは、再帰呼び出しをしており、しかも、画像の画素数分の回数だけ呼び出されるので、多分、オーバーヘッドが大きいかもしれない。Long(C++ では、long long )をやめ、Integer にしても、同じであった。比較的ソートデータ数が小さく(大きくても100前後)、呼び出し回数が圧倒的に多いのが敗因か?Webを調べると、同じような意見が出ていた。 ●新アルゴリズムの検討 C++を折角始めたのに、ここで挫折したくないので、全体として高速化でき、しかもC++が優位になるような手法を検討する。 ○ソート方式の検討 クイックソートの高速化はやめ、再帰呼び出し不要なアルゴリズムを検討することにした。最も速いのは、バケットソートである。これは、O(n) の時間見積りになる。しかし、このソートは原始的なハッシュ法なので、実用する場合は、データ値が、ある連続空間にないといけないし、データ値分の入れ物が必要になる。現在は、Long値がデータなので、このままでは適用できない。 ○データ空間を限定化する 現在は、(R+G+B)*232 + (R,G,B)32 である。下32ビットは、ソートされた値から、元のRGB値を再生するためのものであり、また、R+G+Bが同じ値の場合は、R、G、B の優先度で順位を決められることも狙っている。 ところで、簡易濃度はこの際、YCC空間の輝度Yにすれば、256までに圧縮できるし、輝度として比較的正確に表現できる。これにより、(Y,R,G,B)32 と、8ビット単位でパックした下図のようなUInteger値にする。
○構想 以下のように考える。
○カーネル VBでの処理である。C++ も全く同じとなる。 MSz :局所領域サイズ(フィルタ要素数) Dim AT(MSz - 1) As Integer '局所領域アドレステーブル Dim BS(255) As Integer 'バケットソート領域 '一つの局所領域の処理 Array.Clear(BS, 0,
256)
'ソート領域をクリア '指定のランクの画素は、 IY = DR(bpp + AT(BS(CInt(mm * Rank)))) で取り出せる。 ●結果 メディアンハイフィルタ、1024 X 1024 画像、フィルタサイズ 15 X 15 にて実測した。 3者とも同じ結果が得られたことも確認できた。
|