2011年1月20日木曜日

「AR(拡張現実)で何が変わるのか?」とか「食える数学」とか

最近読んだ2冊の本がとても面白かったので感想などをポツリと。

「AR(拡張現実)で何が変わるのか?」



「東のエデン」とのコラボ作品などで有名なAR3兄弟によるARの解説本。
AR3兄弟自らが作った作品紹介をおりまぜつつ、「ARとは何か」、「ARで何が変わるのか」、「ARの未来は」といったことに関して言及していく。

すごく興味深かったのが「都市ガスはARなんじゃないか?」というお話。
ぱっと聞いただけでは何を言ってるんだかよくわからない。
いわく、本来無味無臭のガスに匂いを付加した都市ガスというのは、ガスの「性質」みたいなものを拡張している、という観点から考えると、AR(拡張現実)なんじゃないか、と。
他にも「風鈴」とか、変わったところだと「ディズニーランド」なんてものまでそういったARに含まれるんじゃないかと。

それまで持っていた「カメラ画像に合った画像をリアルタイムで表示させるための技術」といった狭い考えを覆し、ARの本質に触れられた(ような気がした)一冊でした。


「食える数学」



数学者とエンジニア、二つの職業を経験した著者が数学の実用性を身近な例を使って紹介していく、というもの。
紹介されているのはSuica、暗号、スパムフィルタリングなど、普段何気なく使っている技術。
これらの技術にどのように数学が応用されているかについて分かりやすく解説されている。
数式もほとんど出てこないし、文章も柔らかく、しかし表現が完結で短めなので、サクサク読めます。
「数学に興味はあるけどニガテ…」といった人でも難なく読み進められると思います。

だからといって理数系が得意な工学畑の人が読んでツマラナイかといったらそんなことは全然無い。
というかむしろ、工学畑の人が見るべきなのでは?とか思ったり。

著者さんは「武器としての数学」といったことを述べられています。
欧米に追い越せ、追い付けだった昔は目標、目的が明確に定まっていたが今はそうでは無い。
自分で目標を設定し、そこにたどり着くすべを自ら模索しなければならない、と。
そういった時に必要になってくるのが数学。

この「武器としての数学」を工業大学を出た自分がうまく使いこなせているのか、と自問してみると、かなりアヤシイ…。
あくまで「手段」と割りきってる節があり、証明をよく読まないこともしばしば。
こうなると本質を理解していないために、文字通り「付け焼刃」になってしまう…。

本の中では「数学は体育」とも述べられている。
食らいつかなければ身につかないと。
真に「自らの武器」とすべく、表面を追うだけではなく、しっかりと身につけなければなーと反省させられる部分も。

数学に詳しい人も、そうでない人にもオススメな万人向けの一冊。

2010年12月19日日曜日

Bezier曲線

OpenGLで曲面を描画する方法について調べている。
その中でベジエ曲線とかB-splite曲線とかいろいろ出てきた。

文章や図を眺めてるだけだけじゃイマイチ理解が深まらないので、Procceing上でベジエ曲線描画するプログラムを自力実装してみた(注:Processingにはベジエ曲線を描画するための関数、bezier()があるので純粋に描画したいだけならそれ使った方が早いです)。


int w = 500;
int h = 500;

void setup(){
smooth();
noStroke();
fill(200,0,0,200);
size(w,h);
float[][] pArray ={{50.,200.},
{200.,100.},
{300.,400.},
{450.,200.}};
fill(0,200,0,200);
Bezier(pArray);


fill(200,0,0,200);
for(int i = 0;i < pArray.length;i++){
ellipse(pArray[i][0],pArray[i][1],10,10);
}
}

void draw(){
}

int combination(int n,int k){
int c = 0;

c = factorial(n) / (factorial(k) * factorial(n - k));

return c;
}

int factorial(int n){

if(n == 0){
return 1;
}

int f = 0;

if(n == 1){
return n;
}
else{
f = n * factorial(n - 1);
}
return f;
}

float Berstein(int i,int N,float t){
float b = 0;
b = combination(N,i) * pow((1 - t),(N - i)) * pow(t,i);
return b;
}

void Bezier(float[][] pArray){
final int numT = 1000;
final int x = 0;
final int y = 1;

for(int ti = 0;ti <= numT;ti++){
float t = ti / float(numT);
float px = 0;
float py = 0;
for(int i = 0;i < pArray.length;i++){
float b = Berstein(i,pArray.length - 1,t);
px += b * pArray[i][x];
py += b * pArray[i][y];
}
ellipse(px,py,10,10);
}
}


出力結果はこんな感じ。

2010年12月15日水曜日

OpenGLのキーボード入力

OpenGL触ってて、色々と引っかかったのでメモ。

・OpenGLで矢印とかファンクションキーから入力を受け付けたい場合は、glutSpecialFunc()に特殊キーのコールバック関数を設定する必要がある(C++の場合。Pythonの場合は特殊キーがどうとか考えなくてOK←追記:PyQtでOpenGLウィジェットを用いる場合の話です。OpenGL単体で使う場合は必要)。

※こんな感じ

void specialKeyFunc(unsigned char key,int x,int y){
if(key == GLUT_KEY_LEFT){
//process
}
else if(key == GLUT_KEY_RIGHT) {
//process
}
}

glutSpecialFunc(specialKeyFunc);


・文字を描画する際にはglutBitmapCharacter()を利用する(ココとかココを参考に)。

2010年12月13日月曜日

続OpenCV(光学迷彩的な何か

引き続きOpenCV。
光学迷彩的な何かを作ってみた。

やってることは至極単純で、事前に撮影した室内の画像とwebカムからキャプチャした画像の差分を計算しているだけ。


↑こんなん。左上が処理後、右上がキャプチャ画像、左下がもとの背景画像。
デコ部分の処理が甘く浮き上がってしまっている…。


それにしても、1000円かそこらのwebカムと無料のソフトウェアライブラリでここまで遊べるとは…。
引き続きいろいろ試してみたい所存でございます。

2010年12月12日日曜日

OpenCVが楽しすぎる件について

C++の勉強がてらOpenCVを触っているんだけど、これがかなり楽しい。

とりあえず、Webカムからリアルタイムに画像取得→画像から顔認識して顔部分の色を変化させる、くらいまでは簡単に出来た。




※左がカメラキャプチャした元画像、右が顔認識した部分の色を変化させたもの


一応下に使用したC++のソースを載せておく。


#include <cv.h>
#include <highgui.h>
#include <ctype.h>

int main (int argc, char **argv)
{
CvCapture *capture = 0;
IplImage *frame = 0;
IplImage *out = 0;
double w = 320, h = 240;
int c;

if (argc == 1 || (argc == 2 && strlen (argv[1]) == 1 && isdigit (argv[1][0])))
capture = cvCreateCameraCapture (argc == 2 ? argv[1][0] - '0' : 0);

cvSetCaptureProperty (capture, CV_CAP_PROP_FRAME_WIDTH, w);
cvSetCaptureProperty (capture, CV_CAP_PROP_FRAME_HEIGHT, h);

CvHaarClassifierCascade* cascade = cvLoadHaarClassifierCascade( "C:/OpenCV2.0/data/haarcascades/haarcascade_frontalface_default.xml",cvSize(1,1));
CvMemStorage* storage = cvCreateMemStorage(0);

cvNamedWindow ("Capture", CV_WINDOW_AUTOSIZE);
cvNamedWindow("Face detection", CV_WINDOW_AUTOSIZE);
while (1) {
frame = cvQueryFrame (capture);
cvShowImage ("Capture", frame);

out = frame;

CvSeq* objects = cvHaarDetectObjects(
frame,
cascade,
storage,
1.1,
2,
0,
cvSize(30,30));

for(int i = 0;i < (objects ? objects->total : 0);i++){
CvRect* r = (CvRect*) cvGetSeqElem(objects,i);
cvSetImageROI(out,cvRect(r->x,r->y,r->width,r->height));
cvAddS(out,cvScalar(200),out);
cvResetImageROI(out);
}

cvShowImage("Face detection",out);

c = cvWaitKey (2);
if (c == '\x1b')
break;
}

cvReleaseCapture (&capture);
cvDestroyWindow ("Capture");
cvDestroyWindow ("Face detection");

return 0;
}



※おまけ


お約束。

EclipseとCDTとPythonとOpenCVとわた(ry

今日も引き続きEclipseの環境構築。

OpenCVなぞをインストールしていた。

手順に関してはココを参考にしておけば間違いない。

とにかく問題になったのはOpenCVの最新バージョン2.2をインストールしてしまったこと。
上記サイトでは2.0をインストールしていて、そのとおりにやってみると確かに動く。

これが2.2をインストールしてしまうと、CDTでもPythonでも動かなかった(少なくとも自分の使っているマシンでは)…。

ソフトウェアモジュールはできるだけ安定して動くバージョンをインストールしよう、というお話。

2010年12月11日土曜日

EclipseとCDTとOpenGLと私

Eclipse+CDT+OpenGLメモ

・glutの設定はココに書いてある通り行うべし
・OpenGLプログラムを作成する際、描画関数内で頂点情報を指定したあと、swapBufferes()を忘れずに記述すること
※2010/12/12/追記:swapBuffers()は無くてもOK