2011年10月25日

OptiXのSample6について

FFTもまだ色々できそうでしたが、OptiXに戻ってきました。

Sample6は、以下のような内容です。(by NVIDIA-OptiX-SDK-samples.html)

OBJメッシュファイルを読み込んでレンダリングします。シーンカメラでインタラクションできます。
機能:
・インタラクティブカメラ(回転、パン、ズーム)sutilのGLUTDisplayクラス使ってます。
・sutilのOBJLoaderクラスを使って外部モデルを読み込んでいます。
・プログレッシブなアンビエントオクルージョンシェーディングできます。

というわけで、sutilをいじってPMDファイルを読み込めるようにしてみました。
テクスチャとかはまだですが、頂点と法線は読み込めました。

実行結果

アンビエントオクルージョンシェーディングの結果です。隙間など閉鎖領域が黒くなるそうです。
プログレッシブなので段階的に変わっていきます。

OptiX_test_002.png

一度ノーマルシェーダ(SM_NORMAL)でキャッシュを作ってからSM_AOにしないと重くてグラボが停止してしまいました。SM_ONE_BOUNCE_DIFFUSEはキャッシュを作っても無理でした。グラボの性能不足でしょうか。

せっかくFFTを試したことですし次回は水面のレイトレーシングとかやってみたいですね。GPUでFFTとレイトレーシング両方は厳しそうですかね・・・。
web拍手 by FC2
posted by シンドラー at 21:44 | Comment(0) | TrackBack(0) | OptiX | このブログの読者になる | 更新情報をチェックする

2011年10月24日

CUDAで3次元FFT その1

前回の続きです。

ボクセルデータを3次元FFTでRGB+ボクセルがある場所を255、ない場所を0として、4種類の3次元DFTを実行してみました。

こんな感じで3次元になっただけで使い方は変わっていません。

	/* GPU用メモリ割り当て */
cudaMalloc((void**)&devPtr, sizeof(cufftComplex)*dataSize);

/* GPU用メモリに転送 */
cudaMemcpy(devPtr, hostPtr, sizeof(cufftComplex)*dataSize, cudaMemcpyHostToDevice);

/* 3D FFT plan作成 */
cufftPlan3d(&plan, nx, ny, nz, CUFFT_C2C);

/* FFT処理実施 */
cufftExecC2C(plan, devPtr, devPtr, CUFFT_FORWARD);

/* 計算結果をGPUメモリから転送 */
cudaMemcpy(hostPtr, devPtr, sizeof(cufftComplex)*dataSize, cudaMemcpyDeviceToHost);


高周波成分をカットして復元してもあまり変化がなかったので、256x256x256の周波数成分から、32x32x32といった低周波成分だけ取り出して再構築してみました。

実行結果

      32x32x32             64x64x64           128x128x128 
voxel_32.png voxel_64.png voxel_128.png
    256x256x256(原)         320x320x320
voxel_256.png voxel_320.png

縞模様がでてあまりきれいになりませんでしたね。スカートのような細い面が消えてしまっていますし。
一応256x256x256のデータを使って320x320x320といった拡大もできるのですが(DCTによる画像の拡大と同様に、256x256x256の低周波成分とその外側は0の高周波成分とみなす)、高周波成分カットと同じ効果なのでやはり縞模様が目立つ感じですね。

256x256x256(×4)だと逆FFTだけでも結構メモリと計算時間を使うようですし、あまり使い道もなさそうですね。

まぁ一応目的の3次元FFTでLODのようなものができたということにしておきます。

web拍手 by FC2
posted by シンドラー at 21:59 | Comment(0) | TrackBack(0) | OpenGL & Metasequoia | このブログの読者になる | 更新情報をチェックする

2011年10月20日

CUDAで3次元FFT その0

なんとなくCUDAの3次元FFTを試してみたくなりました。今回はCUDAまで辿り着けなかったので「その0」です。
手段が目的になっていて困ったものですね。

1次元→音声、2次元→画像ときたら3次元→3Dモデルですよね。
3Dモデルを含む空間をボクセル化して、その4次元?データ(x,y,z,色)を3次元フーリエ変換して、高周波成分をカットして復元すれば、3DモデルのLoDみたいなものができるのではないかなと思います。

リアルタイムでできないと思いますし事前に計算するとしてもボーンアニメーションなどに対応できないのでまったく意味がないとは思いますが。

まずは3Dモデルのボクセル化ですが、下記サイトのデプスバッファを使ったボクセル化を参考にさせていただきました。
http://marina.sys.wakayama-u.ac.jp/~tokoi/?date=20091015

以下手順

FBOを作って、6方向からみた3Dモデルの色(RGB)と深さ(vertex.z/vertex.w)を6枚のRGBAテクスチャに書き込みます。この時、モデルビュープロジェクション行列(ワールド座標を視点から見た座標に変換する行列)6つも計算しておきます。

ボクセルのワールド座標(-size,-size,-size)~(size,size,size)に、それぞれのモデルビュープロジェクション行列をかけて、そのボクセル座標の深さ値(voxelPos.z/voxelPos.w)を計算します。

6枚のテクスチャ画像からそれぞれの深さ値をとりだして、6個のデータ全てにおいて「モデル表面の深さ値<ボクセル座標の深さ値」であれば、6方向どこから見てもモデル表面より奥にあることになりますので、物体の内部であると判定することができます。

ついでにモデル表面の深さ値とボクセル座標の深さ値の差が一番小さいものが一番近い表面になりますので、そのボクセルの色は一番近い表面の色(と距離によって暗くする)にします。

こうすれば一応ボクセルの中身にも色がつきます。

↓スライス画像の例
voxel108.png

これで(0,0,0)~(VOXEL_SIZE,VOXEL_SIZE,VOXEL_SIZE)という点のRGB値が作れましたので、このデータを3次元FFTしてどうなるかというのを次回試してみたいと思います。

ボクセル化の実行結果

128x128x128
voxel_001.png

web拍手 by FC2
posted by シンドラー at 20:05 | Comment(0) | TrackBack(0) | OpenGL & Metasequoia | このブログの読者になる | 更新情報をチェックする

2011年10月15日

OpenCVとCUDA FFTでパターン認識 その3

昨日の続きです。

とりあえずLevel2の1~4まで試してみました。
5と6は肌色検出の閾値を調整すればうまくいくかもしれませんが、それもどうなのかと思いますので気が向いたら別の方法を考えてみます。

1. 肌色検出で前処理追加
背景が入って、手の領域以外にも肌色が出てくるようになりましたので、輪郭の長さが閾値以下のものは取り除くことにしました。
また、手と肌色の背景が混ざってしまうこともありましたので、収縮・膨張処理を追加しました。
この辺りはOpenCVの関数を呼べばいいだけなのでとても楽ですね。

// 収縮(erosions回 収縮処理を行う)
cvErode(imgSkin, imgSkin, 0, 3);
// 膨張(dilations回 膨張処理を行う)
cvDilate(imgSkin, imgSkin, 0, 3);

4. のc-means法ですが、初期クラスはランダムで割り振っているので、その影響でたまにチョキとパーが混ざってしまうこともあります。
ランダムではなくデータの平均や分散の大きさで3クラスに分けた方がいいのかもしれません。

5. 判定結果ですが、画像としてみないと正解かどうか分からないので輪郭線に色をつけて表示してみました。(グー:赤、チョキ:緑、パー:青)

実行結果(Level-2の画像2と4)

result_2_2.png result_2_4.png

c-meansで偏らない限りは、Level1の6枚+Level2の4枚を足した10枚(手24個)について100%認識できていました。もっと教師画像があれば最尤推定法等も試してみたいのですが。

処理時間はFFTより輪郭線抽出あたりに時間がかかっている気がします。FFTも100msぐらいかかっていそうな感じですので、全部を合計するとリアルタイムでは無理そうです。

web拍手 by FC2
posted by シンドラー at 16:57 | Comment(0) | TrackBack(0) | Image Processing | このブログの読者になる | 更新情報をチェックする

2011年10月14日

OpenCVとCUDA FFTでパターン認識 その2

昨日の続きです。

パターン認識までやってみました。

1. 肌色検出で手の領域を抽出
2. 手の領域の輪郭線を抽出
3. 輪郭線をフーリエ記述子で表現
4. c-means法でクラスタリング
5. 判定

G型フーリエ記述子ですが、サンプリング点の個数を変えても(減らし過ぎない限り)高周波成分の係数が増えるだけで低周波部分は変わらないんですね。

CUDAのFFTはbatch処理すると少し速くなるようなので、6枚のLevel-1画像(12個の手の輪郭)を一気にFFTすることにしました。
その場合、サンプリング点の個数が異なるとうまくいかない気がしたので、全ての輪郭で360点固定としました。

360個のデータが12個ですので、前回の参考サイトにおけるNXが360、BATCHが12となります。

FFTを行って得られたデータ360個のうち、0番目は平均値になるので無視して、1~10、350~359の20個の低周波成分を使ってパターン認識を行います。

グー、チョキ、パーそれぞれの係数の例は下記グラフのようになっていました。(青が実部、紫が虚部)

gu.png choki.png pa.png

グーは一番低い周波数成分の所が殆どで、チョキやパーは指の部分で少しずつ他の周波数成分が増えてくる傾向がありましたので、この情報を使えば分類できそうでした。

4. の分類方法ですが、グー、チョキ、パーの3クラスと固定ですので、c-means法を使って分けることにしました。
特徴ベクトルは20個の振幅スペクトルのユークリッド距離を使いました。
位相スペクトルの方が良かったかもしれませんがまだ試していません。

5. 判定
これで3クラスに分けられましたが、どれがグーなのかなどが判定できません。
とりあえず各クラスの振幅スペクトルの平均が一番小さいのがグー、2番目がチョキ、一番大きいのがパーと判定することにしました。

その結果、Level-1については100%分類できました。
画像1左, 平均8.217626, チョキ
画像1右, 平均9.573138, パー
画像2左, 平均4.271329, グー
画像2右, 平均8.217526, チョキ
...

Level-2も一応やってみましたが、5,6枚目の画像で肌色検出がうまくできていなかったので、ちゃんと手の輪郭を取得できないと使えそうにないです。

Kinectで深度情報と肌色情報使ってなどもやってみたくはありますがどうなんでしょうね。

web拍手 by FC2
posted by シンドラー at 19:04 | Comment(0) | TrackBack(0) | Image Processing | このブログの読者になる | 更新情報をチェックする

2011年10月13日

OpenCVとCUDA FFTでパターン認識 その1

今更ながらPRMUのアルゴリズムコンテスト2011課題をやってみたいと思います。
ttp://www.ccm.media.kyoto-u.ac.jp/alcon2011/

既存のものを使うだけでアルゴリズム的に新しい所はありません。
また、難しいことは考えていないのでLevel-1の課題だけやります。

課題はじゃんけんの勝敗判定を画像処理で行うものです。

今回考えた処理の流れは以下の通りです。

1. 肌色検出で手の領域を抽出
2. 手の領域の輪郭線を抽出
3. 輪郭線をフーリエ記述子で表現
4. フーリエ記述子でパターン認識

なぜフーリエ記述子を使うのかというと、CUDAのFFTを試してみたかったからです。

1. 肌色検出

肌色検出で検索すると、HSVのHueを使う方法とYCrCbのCrCbを使う方法があるようです。
両方試してみましたが、今回の課題の画像ではCrCbを使った方がきれいに取れましたので、それを使います。

Hue(6~38:OpenCVで8bit画像の場合0~180に切り詰められるので3~19)
参考サイト:ttp://d.hatena.ne.jp/shokai/20090202/1233563393

Hue0.png

CrCb結果
閾値は次の卒論を参考にさせていただきました:
ttp://cafe.mis.ous.ac.jp/2004/sawasemi/Azuma/%E6%9D%B11.pdf

CrCb0.png

2. 輪郭線抽出
OpenCVの関数を使えばできます。
ttp://opencv.jp/sample/segmentation_and_connection.html

3. CUDA FFTでフーリエ記述子
G型フーリエ記述子を使いました。暇があれば他の型も試します。
ttp://e-vod.cs.shinshu-u.ac.jp/it-univ/study/2003/06itoh-r/10.htm

CUDA FFTの使い方で参考にしたサイト:
ttp://www.gsic.titech.ac.jp/~ccwww/tebiki/tesla/tesla6.html

曲線上の位置を複素平面で表して、その座標(xは実部、yは虚部)を1次元のフーリエ変換したものがG型フーリエ記述子になります。

実行結果

高周波成分をカットして20個の低周波成分で再構築した輪郭線
(青い点はC0成分です。)

zfd_20_0.png

約1000個の係数のうち20個だけ使用しているので荒いですが、指が潰れて本数が減ったりはしていないのでこれぐらいでいい気がします。

4. はまだです。フーリエ記述子はパターン認識に使えるはずだと思うんですがどうなんでしょうね。
輪郭線の長さによってサンプリング点の個数が変わるのはどうすればいいんですかね。


web拍手 by FC2
posted by シンドラー at 21:11 | Comment(0) | TrackBack(0) | Image Processing | このブログの読者になる | 更新情報をチェックする

広告


この広告は60日以上更新がないブログに表示がされております。

以下のいずれかの方法で非表示にすることが可能です。

・記事の投稿、編集をおこなう
・マイブログの【設定】 > 【広告設定】 より、「60日間更新が無い場合」 の 「広告を表示しない」にチェックを入れて保存する。