About BBS

物体追跡

作成者: 怡土順一, 最終変更者: 怡土順一, 最終変更リビジョン: 464, 最終変更日時: 2009-05-14 11:58:13 +0900 (木, 14 5月 2009)

■ 動的輪郭追跡

動的輪郭追跡とは,変形する輪郭(物体形状そのものの輪郭が変形しない場合でも,画像に投影された輪郭が変形する場合がある) を逐次計算する(多くの場合は反復計算)手法である. 追跡対象となる物体は,それらの手法により,三次元形状物体,変形物体,関節構造体など様々である.
Opencvで実装されているsnakeは,動的輪郭追跡手法の最も基本的な手法の一つである. snakeでは,内部エネルギーと外部エネルギーの和が最小になるような輪郭を求める. 適切な輪郭を得る為には各エネルギーの重みとなるパラメータが重要な役割を果たすが, これらのパラメータを決定するためには,追跡物体形状や背景画像の特徴がある程度既知である必要がある. また,基本的なsnakeでは,探索空間が二次元画像そのもので表される空間なので,輪郭の自由度が高い分,影などの外乱の影響を受けやすい.

サンプル


snakeによる輪郭追跡(静止画) cvSnakeImage

snakeにより動的輪郭追跡を行う(今回は対象が静止画なので,どちらかというと輪郭検出)

サンプルコード

#include <cv.h> #include <highgui.h> #include <math.h> #include <stdio.h> typedef struct parameter Parameter; struct parameter { float alpha; float beta; float gamma; }; int main (int argc, char **argv) { int i, j = 0, c; IplImage *src_img, *dst_img; CvPoint *contour; CvPoint center; int length = 60; /* 動的輪郭を構成する点数 */ Parameter snake_param = { 0.45, 0.35, 0.2 }; /* cvSnakeImage のパラメータ */ CvFont font; char iter[8]; // (1)画像を読み込む if (argc < 2 || (src_img = cvLoadImage (argv[1], CV_LOAD_IMAGE_GRAYSCALE)) == 0) return -1; dst_img = cvCreateImage (cvGetSize (src_img), IPL_DEPTH_8U, 3); cvInitFont (&font, CV_FONT_HERSHEY_DUPLEX, 0.7, 0.7); center.x = src_img->width / 2; center.y = src_img->height / 2; // (2)動的輪郭の初期化 contour = (CvPoint *) cvAlloc (sizeof (CvPoint) * length); for (i = 0; i < length; i++) { contour[i].x = (int) (center.x * cos (2 * CV_PI * i / length) + center.x); contour[i].y = (int) (center.y * sin (2 * CV_PI * i / length) + center.y); } // (3)初期輪郭の描画 cvCvtColor (src_img, dst_img, CV_GRAY2RGB); for (i = 0; i < length - 1; i++) { cvLine (dst_img, contour[i], contour[i + 1], CV_RGB (255, 0, 0), 2, 8, 0); } cvLine (dst_img, contour[length - 1], contour[0], CV_RGB (255, 0, 0), 2, 8, 0); cvNamedWindow ("Snakes", CV_WINDOW_AUTOSIZE); cvShowImage ("Snakes", dst_img); cvWaitKey (0); /* 動的輪郭の収束計算(過程を表示する) */ while (1) { // (4)動的輪郭の輪郭計算 cvSnakeImage (src_img, contour, length, &snake_param.alpha, &snake_param.beta, &snake_param.gamma, CV_VALUE, cvSize (15, 15), cvTermCriteria (CV_TERMCRIT_ITER, 1, 0.0), 1); // (5)計算された動的輪郭の描画 cvCvtColor (src_img, dst_img, CV_GRAY2RGB); for (i = 0; i < length - 1; i++) { cvLine (dst_img, contour[i], contour[i + 1], CV_RGB (255, 0, 0), 2); } cvLine (dst_img, contour[length - 1], contour[0], CV_RGB (255, 0, 0), 2); snprintf (iter, 8, "%03d", ++j); cvPutText (dst_img, iter, cvPoint (15, 30), &font, CV_RGB (0, 0, 255)); // (6)結果の表示 cvShowImage ("Snakes", dst_img); c = cvWaitKey (0); if (c == '\x1b') break; } cvDestroyWindow ("Snakes"); cvReleaseImage (&src_img); cvReleaseImage (&dst_img); return 0; }

// (1)画像を読み込む
コマンド引数で指定されたファイル名の画像(入力画像)をオープンし,関数 cvLoadImage()で読み込む.2番目の引数にCV_LOAD_IMAGE_GRAYSCALE を指定することで,元画像をグレースケール画像として読み込む. また,結果を表示するために,入力画像と同一サイズのカラー画像を作成する.

// (2)動的輪郭の初期化
初期輪郭の位置を決定する.本来は,追跡される物体の形状に応じた適切な初期輪郭が設定されるべきであるが, 今回は単に,与えられた画像矩形に内接するような楕円を初期輪郭として利用している.

// (3)初期輪郭の描画
初期化された輪郭を描画して,実際に表示する.何かキーが押下されるまで待つ.

// (4)動的輪郭の輪郭計算
動的輪郭の輪郭を計算する.このサンプルでは,入力画像に対する前処理など は何も行っていないが,実際には,例えばノイズの除去やコントラストの強調, あるいはエッジの検出などが前処理として行われる場合がある.
ここでは,輪郭が収束する過程を表示するために,関数 cvSnakeImage()が1回の反復計算しか行わないようにパラメータを設定している(CvTermCriteria). 例えば,以下のようにすると, 「100回反復計算が行われるか,あるいは各反復計算において移動する点の数 が0以下(全ての点が移動しなくなる)まで」,関数cvSnakeImage()内で反復計算が行われてから返る. つまり,通常は,反復計算の為のループは必要ない.

cvSnakeImage( src_img, contour, length, &snake_param.alpha, &snake_param.beta, &snake_param.gamma,
	      CV_VALUE, cvSize(15, 15), cvTermCriteria( CV_TERMCRIT_ITER, 100, 0.0), 1);
また,勾配フラグ(関数cvSnakeImage()の最後の引数)が1なので,画像勾配がエネルギー場として利用される. その他,各引数の詳細については,リファレンスマニュアルを参照のこと.

// (5)計算された動的輪郭の描画
計算され,更新された輪郭(ここでは,1ステップ分),および,現在の反復数を画像上に描画する.

// (6)結果の表示
処理結果を表示する. "Esc"キーが押された場合は終了し,それ以外が押された場合は,次の反復計算に入る.

実行結果例

初期位置 iter=10 iter=30 iter=50

OpenCV-1.0 リファレンス マニュアル
OpenCV-1.1pre リファレンス マニュアル
OpenCVサンプルコード


画素値の直接操作
部分画像のシャッフル
画像の連結
画像のコピー
画像形状の変形
タイリング
画像の反転
逆行列(擬似逆行列)の計算
色空間の写像
離散フーリエ変換
階層構造を持つ輪郭の座標取得
図形の描画
ポリゴンの描画
凸ポリゴンの描画
テキストの描画
IplImage構造体情報の保存
マップのシーケンスを保存
IplImage構造体情報の読み込み
マップのシーケンスを読み込む
K-means法によるクラスタリング
クラスタリングによる減色処理
エッジの検出
コーナーの検出
並進移動のためのピクセルサンプリング
回転移動のためのピクセルサンプリング
画像のサイズ変更
画像のアフィン変換(1)
画像のアフィン変換(2)
画像の透視投影変換
全方位画像の透視投影変換
モルフォロジー変換
平滑化
ユーザ定義フィルタ
境界線の作成
画像の二値化
画像の二値化(大津の手法)
画像ピラミッドの作成
画像ピラミッドを用いた画像の領域分割
平均値シフト法による画像のセグメント化
Watershedアルゴリズムによる画像の領域分割
輪郭の検出と描画
画像のモーメントを計算
ハフ変換による直線検出
ハフ変換による円検出
距離変換とその可視化
不要オブジェクトの除去
ヒストグラムの描画
ヒストグラム間の距離
二次元のヒストグラム
バックプロジェクションパッチ
ヒストグラムの均一化
テンプレートマッチング
形状のマッチング
点列を包含する矩形
輪郭領域の面積と輪郭の長さ
二つの矩形を包含する矩形
楕円のフィッティング
点列を包含する図形
動的背景更新による物体検出
snakeによる輪郭追跡(静止画)
オプティカルフロー1
オプティカルフロー2
オプティカルフロー3
Condensation
顔の検出
カメラキャリブレーション
歪み補正
マップを利用した歪み補正
サポートベクターマシン
画像の各ピクセル値を特徴ベクトルとしたSVMの学習
画像の各ピクセル値を特徴ベクトルとしたSVMによる物体検出
マウスイベントの取得
トラックバーの利用
カメラからの画像キャプチャ
動画としてファイルへ書き出す
ラベリング