2010/07/30

PCを新調しました

最近、iMacの調子が悪いので、PCを新しく買いました。
OpenCVで遊ぶことも考えて、Windows7の32ビット版を選びました。

新しいPCで開発環境を整えようと、VC++2008 Expressをインストールし、
OpenCV2.1のインストーラを使ってインストールしたところ、
以前出ていたインテリセンスが表示されなくなっていました。

インストーラでやるとインテリセンスのデータベースにOpenCVの関数が反映されないっぽいです。

というわけで、ちょっと時間がかかりますが、自分でビルドすることにしました。
ビルドする方法は下記のサイトで詳しく説明されてましたので、参考にさせてもらいました。
OpenCV2.1の入手・ダウンロード・インストール@画像処理ソリューション

今回は、1つの処理を複数のコアに分担させるIntelのスレッディング・ビルディング・ブロック(TBB)も一緒にインストールしてみました。

TBBの本がオライリーから出てたはずなので、そのうち買って勉強しようと思います。

ではまた。

2010/07/28

OpenCVとOpenGLの組み合わせ

Youtubeやニコニコ動画のAR系の動画には、OpenGLで戦車なり目玉なりを
描画しているものが多いので、私もOpenGLをちょっと触ってみることにしました。

OpenGL入門のサイトを色々と巡ってみましたが、OpenGLが複雑でよくわからず。


試行錯誤で何とかマーカーの傾きや位置を描画する物体に
反映させることができるようになりました。



さらにOpenGLを勉強して、マーカーのど真ん中に急須を表示出来るようにしたいです。

ではまた。

2010/07/24

RANSACを実装してみました

この前、Excelで実験を行ったRANSACのコードを実際に書いてみました。

今回は正解の点400点、はずれの点400点のデータ群から
直線を検出することを目標にしました。(Y=AX+BのAとBを推定)

その結果が下記の図になります。
灰色の小さな点がはずれの点で、黄色の点がRANSACアルゴリズムによって"もっともらしい"と判断された点です。
緑色の直線がRANSACの「推定」ステージで求めた直線で、青の直線が「検証」ステージで求めた直線となります。





















ソースコードは別館の方においてあります。

ではまた。

2010/07/22

RANSACを調べてみました

パラメータのロバスト推定によく使用されているというRANSAC。
コンピュータビジョンの本にもところどころ出てきていますが、
どんなものなのかははっきりわかっていませんでした。

というわけで、色々と調査してみました。

Czech Technica大学の教材のPDFおべんきょうWikiを見て調べたところ、

RANSACのアルゴリズムは、下記のようになっていました。

1.総データ個数がU個あるデータから、ランダムでn個のデータを取り出します。
2.取り出したn個のデータから、パラメータを求めます。
 (取り出すデータの個数ですが、これは求めるべきパラメータの数に比例するようです)
3.求めたパラメータを、総データ点数から取り出したn個のデータを除いたものに式を当てはめ、
観測されたデータと2.で求めたパラメータの誤差を計算します。
4.誤差が許容範囲内であれば、パラメータに対して投票を行います。
5.1~4を繰り返し、投票数が一番多かったパラメータをひとまず採用します。
(これを仮パラメータとします)

6.仮パラメータを使ってすべてのデータに再度式を適用し、誤差が許容範囲内のものを抽出します。(この時点で雑音データがほぼ取り除かれます)

7.抽出したデータを元に、再度パラメータを求めます。
8.求まったパラメータがこのデータのもっともらしいパラメータとなります。



というわけで、Excelを使って実験をしてみました。
実験の条件は下記の通りです。

実験データ個数:600個
うち300個は正解データ、残りの300個は雑音データとしました。
正解データの数式は  Y=(1-rand()/10) *X で生成しており、
正解データはYの0.9倍から1倍の範囲にあり、平均すると0.95倍になる、、はずです。
雑音データの数式はY=rand()*X としました。Xが0から300まであるので、最小値0、最大値300の雑音データがランダムで発生しています。

パラメータ推定の対象となるデータをグラフにしたものが以下のものとなります。



上記のデータに、RANSACで式を当てはめてみます。
今回は原点を通る直線の式になるので、式は
 Y=AX
と簡単なものになります。
未知のパラメータが1個なので、ランダムで取り出すサンプルの個数は2個としました。


取り出した点PとQのX,Yの値を(Px,Py)、(Qx,Qy)とします。
A=傾き=Yの増加量/Xの増加量=(Qy-Py)/(Qx-Px) で、仮のAが求まります。
そして、仮のAをサンプル以外のデータに適用し、誤差を調べます。

今回は誤差が10%以下のものに限り投票してよいことにしました。



上記のことを600回(回数は適当に決めました)行い、得票数が一番多かったパラメータ(今回はA=0.91が得票数が一番多くなりました)を使って、誤差が範囲内にあるデータの集合を求めます。
誤差が範囲内にあるデータの集合は、雑音がほぼ取り除かれたデータとなるので、
このデータの集合を元に、再度パラメータを推定します。
今回は各データのY/Xを計算して、平均をとったところ、A=0.95となりました。
下の図のピンクがRANSACで求めたパラメータの直線です。


















おぉ~

見事に雑音が無視されていますね。

あとはこれをCで書けば、今後のパラメータ推定に役立ちそうです。

ではまた。

2010/07/21

パノラマ写真を作ろう その2

前回の内容から逆行するような形になりますが、
まずは一番簡単なところからはじめていきたいと思います。

画像の条件:
・スケーリングや回転はなし
・透視変換も一切なし
・画像間の変化はx軸とy軸に平行な移動のみ
というものです。


今回はx方向とy方向の差分を求めればよいのですが、
そのためには画像Aにある特徴が画像Bのどこにあるかを最初に見つける必要があります。

この辺はOpenCVのサンプルプログラムの中で検出してくれているので特に考える必要はありません。

今回は最小二乗法を使って、x方向とy方向の移動量を求めました。

その結果が下記の通りとなります。
1枚目は8枚の画像を合わせていく過程で、2枚目が画像を貼り合わせた
パノラマ画像となります。












まぁ、そこそこいい感じに出来たみたいです。

今回のソースコードは別館のほうに置いておきました。

今後の目標は下記の通りです。
・RANSACを使って、移動量をもう少し正確に求める(最小二乗法は、エラーの点も計算に含むので、エラーの点の影響を受けやすいようです)
・入力される画像の順番がバラバラでもパノラマ画像を作れるようにする
・画像の回転に対応する
・画像の拡大・縮小に対応する
・プログラムをもっと効率的にする


あと、パノラマ画像作成のプロジェクトのページを見つけたので、リンクを貼っておきます。
Automating Joiners ・・・パノラマ画像作成の論文や、スライドがあります。
Computational Photography・・・カーネギーメロン大学のComputer Photographyという講義のページ。パノラマ画像作成以外にも、モーフィングやモノクロ画像の自動着色プロジェクトがあります。この講義は結構楽しそうな感じです。

ではまた。

2010/07/19

OpenCVで自動的にパノラマ写真を作る(OpenCV Panography)

以前、コンピュータビジョンの勉強用資料として紹介した、"Computer Vision Algorithms and Applications" に、
パノラマ写真の作り方が載っていたので実際にやってみました。
(パノラマ写真を作ることを英語でpanographyとかImage stitingと言うようです。)

※今回はOpenCVのサンプルにあるfind_obj.cppをベースに作っています。


デジカメで撮った複数枚の画像から大きなパノラマ画像を作る方法は下記の通りです。
1.カメラの位置をなるべく動かさず(回転はOK)、複数枚の画像を撮ります。
2.それぞれの画像の中から、特徴量を抽出します(今回はSURFを使っています)
3.異なる2枚の画像の特徴量を比較し、2枚の画像間のホモグラフィ行列を求めます。
4.求めたホモグラフィ行列を利用して、1枚ずつパノラマ画像に貼っていきます。

では、早速作っていきましょう。
1.材料の準備
今回の材料は下記の3枚です。
(自転車でちょっと峠まで行って写真を撮ってきました。)



2.特徴を探す
画像の特徴をひとまず目で探してみましょう。
image1の右側にある水色で囲った部分と、image2の水色の部分が同じもので、
image2の右側にあるオレンジで囲った部分とimage3のオレンジの部分が同じものであることがわかります。
(ほかにも特徴はありますが、ぱっと見てわかりやすいのが上記の2つです。)

この特徴探しをコンピュータにやってもらうのですが、今回はOpenCVに実装されているSURF特徴量を使います。
SURFを使うと、移動はもちろん、回転やスケーリングにも強い特徴を求めることが出来ます。

3.特徴のマッチング
画像ごとの特徴のリストが作られたので、次はこれを比較します。
2つの画像間で同じ物体が存在する場合は、2つの特徴リストの中に一致する特徴があるはずです。
今回、一致するものを探すために最近傍探索を使用しています。
(正直この辺はよくわかってないのですが、とりあえず特徴リストAにある特徴Anと、
特徴リストBにある特徴Bm(nとmは任意の数)の差が最小になるものを探し、それを特徴のペアとすることのようです)

特徴リスト間で対応する特徴の組が求まったら、それを元にホモグラフィ行列を求めます。
対応する特徴間の差(つまり特徴のX方向とY方向の移動量)のリストを求めて、
OpenCVの関数cvFindHomographyにホモグラフィ行列を求めてもらいます。

4.画像を合成する
今回は画像が3枚なので、image1とimage2間のホモグラフィ行列H12と、image2とimage3間のホモグラフィ行列H13がわかっていますが、
image1とimage3間のホモグラフィ行列はわかっていません。

ですが、image1とimage2間、image2間とimage3間の関係はホモグラフィ行列を使い、
下記のように表せるので、
image1 = H12 image2
image2 = H23 image3

image1とimage3間の関係は
image1=H12 H23 image3
となるはずです。

以上のことを踏まえてプログラムを作ると、下記のような結果になりました。


右下方向に拡大していっているのが気になりますが、それっぽく合成されてるようです。


あとは、↓こうなってるのを



こんな感じに補正してやれば
それっぽいパノラマ画像が出来そうです。

現在のパノラマ画像を作るところの処理は
・image1を左上に貼り付ける
・image2の透視変換画像(H12を使用)を求めて、貼り付ける
・image3の一時的な透視変換画像(ホモグラフィ行列H12を使用)を求めて、
さらにその一時的な画像にホモグラフィ行列H23を使用した投資変換画像を求めて貼り付ける

といった感じになってるので、

・image1を左上に貼り付ける
・image2の透視変換画像(H12を使用)を求める
・image2の歪みを直して貼り付ける
・image3の一時的な透視変換画像(ホモグラフィ行列H12を使用)を求めて、
さらにその一時的な画像にホモグラフィ行列H23を使用した投資変換画像を求める
・image3の歪みを直して貼り付ける

といった感じにすれば、キレイなパノラマ画像が作れそうです。


2011-06-28 追記
OpenCV2.3に、ベータ版ですがパノラマ写真作成ソフトがつきました。


ではまた。

2010/07/13

Computer Visionの資料 その3

最近は勉強用資料の発掘に勤しんでます。


よさそうな資料がおいてあるサイトを2つ見つけたので、リンクを貼っておきます。

1つ目はフロリダセントラル大学の"CAP5415 - Computer Vision"という講義のページです。
http://www.cs.ucf.edu/courses/cap6411/cap5415/
Reference Textの中央付近に、Fundamentals of Computer Vision というオンライン書籍?のリンクがあります。133ページのPDFで、エッジ検出やカメラのパラメータ推定などが取り上げられています。
また、ページの下のほうには練習問題っぽいものがありました。

2つ目はワシントン大学のComputer Visionの講義のページです。
Computer Vision: A Modern Approach という1000ページ弱のPDFがダウンロードできます。
http://www.cs.washington.edu/education/courses/455/02wi/
その他、Projectsというページにも面白そうな課題が載っていました。


ではまた。

2010/07/11

透視変換ツール

「詳解 OpenCV」の練習問題で、下記のようなお題がありました。
・テンキーの数字キーを押したら、該当の透視変換行列のセルに関連する
値を増減させるものを作ってみる。
・ズームインとズームアウトの機能をつける。
・回転する機能を追加できれば追加する。


とりあえず作ったものの結果が下記の通りとなります。
元の画像、アフィン変換(外形が平行四辺形になる)のもの、
透視変換(外形が台形になるもの)、適当に変換したもの です。




















とりあえず今回作ったもの(やっつけですが)は下記の通りとなります。
rを押すとリセット、cを押すと行列に加える数値のプラスとマイナスを変更できます。
qで終了です。
ズームとパンは、数字の3を押せば表現できます。
回転はとばしました。


//////////////////////////////////////
// 
// OpenCVで遊ぼう!
// http://playwithopencv.blogspot.com/
// 透視変換をします。

#include "cv.h"
#include "highgui.h"
#include "iostream"

CvMat* warp_matrix =cvCreateMat(3,3,CV_32FC1);
double inc;

void ResetMatrix()
{
 cvZero(warp_matrix);
 cvSetReal2D(warp_matrix,0,0,1); 
 cvSetReal2D(warp_matrix,1,1,1); 
 cvSetReal2D(warp_matrix,2,2,1); 
}
void changeMatrix( int row, int col,double ratio)
{
 double n;
 n = cvGetReal2D(warp_matrix,row,col)+inc*ratio;
 cvSetReal2D(warp_matrix,row,col,n); 
}

int main(int argc, char **argv) 
{

  IplImage *src,*dst;
  char filename[80];

  std::cout<< "Input image filename." <<std::endl;
  std::cin >> filename;

  FILE *fp;
  if ( (fp = fopen(filename,"r")) != NULL ){
      fclose( fp );
     // ファイルが存在する
  }
  else
  {
     std::cout<< "Invaild filepath" <<std::endl;
    return -1;// ファイルは存在しない
  }


  src=cvLoadImage(filename,1);
  dst = cvCloneImage(src);

  dst->origin = src->origin;
  cvZero(dst);


  char c;
  cvNamedWindow("WarpPerspective",1);
  inc=0.01;
  
  ResetMatrix();
  while(true)
  {

   cvWarpPerspective(src,dst,warp_matrix);
  // cvSave("c:\\warp.txt",warp_matrix);

   cvShowImage("WarpPerspective",dst);
   c= cvWaitKey();
  
   //配置
   // 7  8  9
   // 4  5  6
   // 1  2  3
   // cを押すと、プラスとマイナスを変更できる。
   // zを押すと、ズーム
   // pを押すと、パン
   // rを押すと、{1,0,0,0,1,0,0,0,1}にリセットする
   // 9と6は押しても画像に変化はありません。
   if(c=='7') { changeMatrix(0,0,1);}  
   if(c=='8') { changeMatrix(0,1,1);}
   if(c=='9') { changeMatrix(0,2,1);}
   if(c=='4') { changeMatrix(1,0,1);}
   if(c=='5') { changeMatrix(1,1,1);}  
   if(c=='6') { changeMatrix(1,2,1);}
   if(c=='1') { changeMatrix(2,0,0.005);}
   if(c=='2') { changeMatrix(2,1,0.005);}
   if(c=='3') { changeMatrix(2,2,1);}  
   if(c=='c') { inc=inc *-1;}
   if(c=='q') break;
   if(c=='r')  { ResetMatrix(); };
  }
  cvReleaseImage(&dst);
  cvReleaseMat(&warp_matrix);
  cvReleaseImage(&src);
  cvDestroyWindow("WarpPerspective");


 return 0;



}

2010/07/08

Computer Visionの勉強用資料 その2

またまたComputer Visionの勉強用資料を発見しました。
Microsoftの研究所(たぶん)のRichard Szeliskiさんが書いたものです。
http://szeliski.org/Book/

ダウンロードして個人で使用しても大丈夫とのことなので、ダウンロードしてキンドルに入れてみました。今もっているのは小さいほうのキンドルなので、A4の書籍はさすがに文字が小さくなります。(どれくらい小さいかを実感してみたい方は、A4に印刷したものを25%の倍率(もしくはA4→A6)でコピーしてみてください。)


資料の話題に戻って、この資料では
・イメージプロセッシング
・物体検出とマッチング
・分割
・特徴に基づくアライメント
・SFM(動画からの再構築?)
・動きの推定
・イメージステッチング(複数枚の画像を大きな1枚の画像に合成することらしいです。)
・3Dの再構築
・画像の理解(顔検出、特定の物体検出)

と、さまざまなことが取り上げられています。

結構詳しく書かれている貴重な資料(しかも無料で)になると思うので、
前のスライドとともにちょっとずつ翻訳しながら読んでいきたいと思います。




---------------------------------------------------

最近はPDFで色々と資料が手に入るのですが、最適な閲覧方法がなかなか見つかりません。

以前はノートパソコンを横にして見ていましたが、腕や目が疲れるので長時間の利用は厳しいです。しかし、PDFのしおりやリンク機能が使え、フルカラーで閲覧できます。

キンドルは軽く、バックライトが無いので目が疲れにくいのですが、PDFのしおり機能やリンクが利用できません。また、すばやくペラペラめくる操作は今のところ出来ません。

紙に印刷すると読みやすいけれど置き場所に困ります。ページ数が多いとインク代も気になるところです。

各媒体でメリット・デメリットはありますが、今のところキンドルDXがPDFを見るのにはいいのではないかなぁと考えています。

2010/07/02

マシンビジョンの資料

最近はGoogle Books等で、色々とマシンビジョンの資料を探していました。
探している中で、よさそうな資料を見つけました。
「Multiple View Geometry in Computer Vision」という本の著者が作った240Pにわたるスライドです。
http://users.cecs.anu.edu.au/~hartley/Papers/CVPR99-tutorial/tutorial.pdf

内容としては、カメラのキャリブレーションに関するものや、ステレオビジョン、複数の画像からの3次元再構築などです。

スライド形式なので単語が少ないので翻訳も楽ちんです。
ひとまずしばらくはこれで勉強していく予定です。