Archive for 11月, 2010

OpenCVで画像を回転させる

火曜日, 11月 30th, 2010
このエントリーを含むはてなブックマークはてなブックマーク - OpenCVで画像を回転させる

OpenCVを用いて、画像を一定角度回転させる関数です。回転角が90度や180度などの場合には画像の軸を入れ替えるだけで回転を実現できるのですが、回転角が60度などの場合にはこの方法では上手く動作しません。

そこで、回転行列と並進行列を合わせた行列を用いて、任意角度の回転を実現します。

void rotateImage(IplImage *img, double angle)
{
	IplImage *tmp = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 3);
	CvMat M;
	float m[6];
	
	m[0] = (float) (cos (angle));
	m[1] = (float) (-sin (angle));
	m[2] = img->width * 0.5;
	m[3] = -m[1];
	m[4] = m[0];
	m[5] = img->height * 0.5;
	cvInitMatHeader (&M, 2, 3, CV_32FC1, m, CV_AUTOSTEP);
	cvGetQuadrangleSubPix (img, tmp, &M);
	
	cvCopy(tmp, img, NULL);
	cvReleaseImage(&tmp);
}

回転並進行列は次式の1で表されます。頭の2行2列の部分が回転行列、tx, tyが並進行列になっています。

この行列の場合、角度θを回転させ、(tx, ty)だけ平行移動する行列になります。

プログラムにおいては、m[0], m[1], m[3], m[4]が回転行列を、m[2], m[5]が並進行列を構成しています。cvInitMatHeaderでこの回転並進行列を作成し、cvGetQuadrangleSubPixで実際に行列を各ピクセルに適応することで、画像の回転を実現しています。

iPhoenでタイマー処理

日曜日, 11月 28th, 2010
このエントリーを含むはてなブックマークはてなブックマーク - iPhoenでタイマー処理

数秒後に実行したい処理がある場合、iPhoneアプリではNSTimerクラスを使うのが常套手段のようです。使い方は、以下のとおり。


-(void)myFunc:(NSTimer*)timer
{
}

-(void)someFunc
{
    NSTimer* timer;
    timer = [NSTimer scheduledTimerWithTimeInterval:1 
    target:self 
    selector:@selector(myFunc:)
    userInfo:nil 
    repeats:YES];
}

scheduledTimerWithTimeInterval:target:selector:userInfo:repeatsメソッドの引数は順番に、タイマーのインターバル、コールバック先、コールバック関数名、パラメータ、繰り返しのON・OFFになっています。

ただ、数秒後に一度だけ関数を実行したい場合には、もう少し便利な performSelector:withObject:afterDelay:メソッドが存在します。このメソッドの引数は順番に、コールバック関数、引数、何秒後に実行するか、となっています。

使い方はいたって簡単で、以下のとおり。

-(void)myFunc:(NSTimer*)timer
{
}

-(void)someFunc
{
[self performSelector:@selector(myFunc) withObject:nil afterDelay:1.0];
}

UIActivityIndicatorViewの動作

土曜日, 11月 27th, 2010
このエントリーを含むはてなブックマークはてなブックマーク - UIActivityIndicatorViewの動作

UIActivityIndicatorViewを使用する際に、同一スレッド内で開始処理、停止処理を記述しても、インディケータは動作してくれません。

具体的には、

-(void) myFunction
{
[indicator startAnimating];

// 処理

[indicator stopAnimating];
}

のように記述してもUIActivityIndicatorViewが思い通りに動作することはありません。正しくUIActivityIndicatorViewを動作させるためには、startAnimatingとstopAnimatingを別スレッドでコールしてやる必要があります。

そこで、performSelectorInBackground:withObjectメソッドを使って別スレッドを生成し、その中で処理を行うことで、UIActivityIndicatorViewを正しく動作させることが出来るようになります。参考プログラムを下に書いておきます。

-(void) anotherFunction
{
    NSAutoreleasePool *pool;
    pool = [[NSAutoreleasePool alloc] init];

 // 処理

    [indicator stopAnimating];
    [pool drain];
}

-(void) myFunction
{
    [indicator startAnimating];
    [self performSelectorInBackground:
         @selector(anotherFunction) 
         withObject:nil];
}

画像のベクトル化

金曜日, 11月 26th, 2010
このエントリーを含むはてなブックマークはてなブックマーク - 画像のベクトル化

ビットマップ画像をベクトル画像に変換するアルゴリズムをいろいろ調べていました。画像をベクトル化するということは、すべてのエッジを曲線の方程式で近似するということです。その変換方法としては、Potraceというアルゴリズムが有名なようですね。

論文は、ここから入手できます。

Potrace: a polygon-based tracing algorithm. Peter Selinger. September 20, 2003

基本的には、

1. 輪郭座標の抽出
2. ポリゴン化
3. ベジェ曲線で近似

という流れのようです。ぼちぼち、iPhoneに実装していきたいです。ただ、このアルゴリズム、そのままだと重すぎて動かない気がする(笑)まぁ、行き詰ってから考えよっと。

フーリエ変換の本質

水曜日, 11月 24th, 2010
このエントリーを含むはてなブックマークはてなブックマーク - フーリエ変換の本質

工学系の大学生なら、2回生ぐらいで習うフーリエ変換。フーリエ級数やらフーリエ展開やらの式だけ覚えさせられて、フーリエ変換の意味を理解してない人が多いようです。

そこで、フーリエ変換とは何か?をサクっと説明してみましょう。

fourier1

全ての信号は、上図のようにsin波の足しあわせで表現することが出来ます。

具体的には、周波数が1のsinxと周波数が2のsin2xと周波数が3のsin3xと・・・周波数がnのsinnxを足し合わせることで、あらゆる信号を表現することが出来るのです。

しかし、ただ単にy=sinx+sin2x+sin3x+・・・としたのでは1種類の信号しか表現できません。そこで、各周波数の振幅を変化させることで、あらゆる信号を表現するのです。

上記の信号の場合、y=4*sinx+0.5*sin2x+2*sin3x+sin4xと表現できます。

fourier2

さて、先程の図を用いて、周波数を横軸に、振幅の大きさ(パワー値)を縦軸にとってグラフを書きなおしてみます。周波数が1の波(sinx)の振幅は4なので、f=1ではパワー値が4になります。同様に、f=2でP=0.5、f=3でP=2、f=4でP=1をとると上図の右のグラフのようになります。

これこそが、フーリエ変換の結果なのです。

fourier3

さて、ではこの結果は何を意味しているのでしょうか?この結果は、左図の信号に周波数1の波が大きさ4で含まれていること、周波数2の波が大きさ0.5で含まれていること、周波数3の波が・・・ということを意味しています。

要するに、フーリエ変換を行えば、「信号に含まれる周波数の成分比」を得ることが出来ます。本質はこれだけです。
 
 

参考図書

 
 
「フーリエの冒険」
フーリエ変換についてゼロから勉強するなら、まずは本書がとってもお薦めです。この本では難しい数学や数式を使うこと無く、かみ砕いてフーリエ変換の本質を説明してくれています。微積や三角関数の説明も丁寧にしてくれていて、作者の「フーリエ変換の本質を伝えたい」という気持ちが伝わってくるような一冊です。

フーリエの冒険
フーリエの冒険
posted with amazlet at 11.06.14
ヒッポファミリークラブ
売り上げランキング: 18159

 
 
「今日から使えるフーリエ変換」
上記の参考書と同様、フーリエ変換の本質についてサックリ明解に説明してくれている参考書です。もちろん、フーリエ変換の本質だけでなく、数学的な話から実用的な話までカバーしているので、工学系にいる人には必須の一冊です。入門書と中級書をつないでくれる非常に良書だと思います。
 

今日から使えるフーリエ変換 (今日から使えるシリーズ)
三谷 政昭
講談社
売り上げランキング: 211251

 
「これなら分かる応用数学教室」
この本は絶対に「買い」です!理由不要です(笑)本書では最小二乗からフーリエ変換、顔認識、ウェーブレットまでを説明しています。この何も関係なさそうなカテゴリが本書を読めば一本の糸で繋がります。とにかく、知的感動を味わいたいならぜひ!
 

これなら分かる応用数学教室―最小二乗法からウェーブレットまで
金谷 健一
共立出版
売り上げランキング: 29039

 
 
あと・・・
僕の作ったアプリもよろしく(笑)
iPhoneで一眼レフカメラで撮影したような画像を作れます!