2011-07-28
KiRiE
iPad アプリを作ってみました.
切り絵アプリです.
審査に通ったようです.
現在 iTunes App Store で公開されています.
iTunes App Store : KiRiE - 切り絵
有料ですがよろしければ,どうぞ.
2010-08-30
Shape from Silhouete 2
C++ |
こないだのやつの
ちょっと解像度を上げて復元レベルも上げたやつ
結構ちゃんと復元してくれてるんだけど
なんかオブジェクトの端っこが消えてる
手とか足とか,尻尾なんかほとんどなくなっちゃった
原因としては元画像のカメラパラメータの推定がよくないのかも
カメラパラメータの情報がなかったので
こっちで勝手に推定というか目測というか適当に設定した
カメラパラメータの推定をどうやるのかってのがここからの問題
ソースも載せたいけど量が多い,あと自信ない
2次元描画系からだからね,なぜか
逆に考えればそれだけ更新できるってことでもあるけどね
幸いなことに他に書くこと無いからね
無更新記録更新のプレッシャーに耐えられなくなったら少しずつ載せます
2010-08-14
Shape from Silhouete
C++ |
Visual Geometry Group Home Page
Dinosaur より...
レンダリングエンジンから自分で書いてみたりして
というか線を引くとこから多角形を塗りつぶすところから...
何やってんだか
2万ポリゴンくらいでやっぱりカクカク
でもまぁ全ての部分に自分の手が届くのがいいところ
あと自分の使いやすいように設計できるし〜
なんてね
Open CV くらいは使うべきか
ネタも無いくせにそれっぽく更新
何を言っても言い訳になるから何も言わないという言い訳
皆さん,暑いですがお変わりないでしょうか?
僕は良くも悪くも変わりません
停滞期.
多分,ここが大事!
なのですが
2010-05-03
PCAで3次元復元 2
C++ |
ちょっと分かりかけてきた
こないだまずかったのは運動行列を正規化してなかったからだ
射影は多分あってた,正射影ってやつ
ちゃんと運動行列を正規化してみたのがこちら
なんとかできてるっぽい...かな?
ましにはなってるね
正規化するために行列ばっりいじくり回してた
ちょー疲れた
行と列がぐっちゃぐちゃさ
縦ベクトルとか横ベクトルとかぐっちゃぐちゃ
数学できないと目が回るね,まったく
一番簡単そうな正射影でこれだからね
やっと第一歩というところです
2010-04-30
PCAで3次元復元?
C++ |
いやーさぼったさぼった
でもそんなにいつもいつも書くことあるってもんじゃないよね?
ただ書けばいいってもんじゃないよね?
今日はここの
点対応を用いた複数の2次元画像3次元形状復元-因子分解法の数理-
によると複数の2次元の対応点集合から3次元形状を復元できるらしい
正直数式は追いついてないですがどうやら因子分解によって2次元点集合の行列を
カメラの運動の行列と形状の行列に分解すればいいのだそうだ
そしてこれは主成分分析(特異値分解)して第3主成分までとればいいんだって
とりあえずやってみよう
3次元データは適当に検索して teapot にした
ファイル形式は OBJ 形式
まぁなんでもいいやね
んで読み込んでいくつか角度変えてそのまま2次元に落とす
今回は3枚の2次元点集合を使った
こんな感じ.
そしてこの3枚の2次元点集合を行列に突っ込んでPCAかけるだけ
かけた.かけました.
その結果がこれだ!
左がオリジナルのモデル.右が復元した3次元形状.
んーなんか変,ぼてっとなっとる
なんでやねん
あれかなー単純に2次元に落としたのがまずいのかな?
ちゃんと射影(投射?透視投影?)してあげなきゃダメなのかも?
まぁでもちゃんとできそうなことが分かったからこれからよく勉強しよう
実際に応用する際の問題点としては
全ての点の対応が分かってないといけないことと
全ての2次元画像に全ての点が含まれていないといけないこと
だから隠れ点は認められないし,各点の対応も自分で事前に見つけとかなきゃいけない
逆に言えばこの辺をどうにかできればカメラ画像から3次元形状を復元できるはず
なるほど
今回のソースはこちら.表示部分は省いとります.
あとPCAの部分とかは以前のを見てね.
//--------------------------------------------------------------------------- #include <iostream> #include <fstream> #include <vector> #include <sstream> #include <math.h> using namespace std; #include "pca.h" //--------------------------------------------------------------------------- //teapot 読み込み //--------------------------------------------------------------------------- void read_teapot(vector< vector<double> > &point,vector< vector<int> > &face) { ifstream ifs("data/teapot.obj"); string line; stringstream ss; if(!ifs) cout<<"file open error!"<<endl; while(getline(ifs,line)){ ss.str(line); ss.clear(stringstream::goodbit); string flg; ss>>flg; if(flg=="v"){ double tmp; vector<double> p; while(ss>>tmp){ p.push_back(tmp); } swap(p[1],p[2]); point.push_back(p); } else if(flg=="f"){ int tmp; vector<int> f; while(ss>>tmp){ f.push_back(tmp-1); } face.push_back(f); } } } //--------------------------------------------------------------------------- Matrix rmat_x(double a) { Matrix r(4,4); r[0][0]=1; r[0][1]=0; r[0][2]=0; r[0][3]=0; r[1][0]=0; r[1][1]=cos(a); r[1][2]=sin(a); r[1][3]=0; r[2][0]=0; r[2][1]=-sin(a);r[2][2]=cos(a); r[2][3]=0; r[3][0]=0; r[3][1]=0; r[3][2]=0; r[3][3]=1; return r; } //--------------------------------------------------------------------------- Matrix rmat_y(double a) { Matrix r(4,4); r[0][0]=cos(a); r[0][1]=0; r[0][2]=-sin(a);r[0][3]=0; r[1][0]=0; r[1][1]=1; r[1][2]=0; r[1][3]=0; r[2][0]=sin(a); r[2][1]=0; r[2][2]=cos(a); r[2][3]=0; r[3][0]=0; r[3][1]=0; r[3][2]=0; r[3][3]=1; return r; } //--------------------------------------------------------------------------- Matrix rmat_z(double a) { Matrix r(4,4); r[0][0]=cos(a); r[0][1]=sin(a); r[0][2]=0; r[0][3]=0; r[1][0]=-sin(a);r[1][1]=cos(a); r[1][2]=0; r[1][3]=0; r[2][0]=0; r[2][1]=0; r[2][2]=1; r[2][3]=0; r[3][0]=0; r[3][1]=0; r[3][2]=0; r[3][3]=1; return r; } //--------------------------------------------------------------------------- int main() { srand(time(NULL)); vector< vector<double> > point; vector< vector<int> > face; //teapot の3次元モデルを読み込み read_teapot(point,face); //Matrix に移し替える Matrix X(point.size(),4); for(int i=0;i<point.size();i++){ for(int j=0;j<3;j++) X[i][j]=point[i][j]; X[i][3]=1; } Matrix rx=rmat_x(90*M_PI/180); X=(rx*X.t()).t(); int F=3; //復元に使用する2次元データ枚数 int f=0; Matrix W(2*F,X.rdim()); //2次元データ集合の行列 for(int i=0;i<360;i+=360/F){ //適当に回転して rx=rmat_x(80*sin(i*M_PI/360)*M_PI/180); Matrix ry=rmat_y(i*M_PI/180); Matrix Y=(rx*ry*X.t()).t(); //そのまま2次元に落とす,ノイズ付き for(int j=0;j<Y.rdim();j++){ W[2*f+0][j]=Y[j][0]+(rand()%1000/10000.0-0.05); W[2*f+1][j]=Y[j][1]+(rand()%1000/10000.0-0.05); } f++; } //PCA Vector l; Matrix S=PCA::calc_pca(W,l); S=S.t(); //復元結果 Matrix V(S.rdim(),4); for(int i=0;i<S.rdim();i++){ V[i][0]=S[i][0]; V[i][1]=S[i][1]; V[i][2]=S[i][2]; V[i][3]=1; } cout<<"press enter>>"; getchar(); return 0; } //---------------------------------------------------------------------------









