1)入力 入力画像は、濃淡画像の場合は1画素8bit、カラー画像の場合は1画素24bitの整数画像 として読み込まれる。オプティカルフローの計算をするには、はじめに1画素32bitのfloat 画像に変換してから計算するほうがよい。 // ファイルを読み込んで濃淡画像(8bit整数)に自動変換 IplImage* img1 = cvLoadImage( "input.png", CV_LOAD_IMAGE_GRAYSCALE ); CvSize size = cvGetSize(img1); IplImage* I1 = cvCreateImage( size, IPL_DEPTH_32F, 1); // float画像に変換 cvConvert( img1, I1 ); 2)空間勾配 空間勾配Ix,IyをもとめるにはSobelオペレータ演算を用いるとよい。 // 3x3のx方向Sobelオペレータ cvSobel( src, dst, 1, 0, 3 ); // 3x3のy方向Sobelオペレータ cvSobel( src, dst, 0, 1, 3 ); ただし、1画素あたりの勾配を求めるにはSobelの値を1/8にする必要がある。 // 各画素の値を1/8にする演算 cvConvertScale( src, dst, 0.125, 0 ); 3)時間勾配 時間勾配Itを求めるには、画素ごとの差分演算を用いるとよい。 // 時間差分 cvSub( src2, src1, dst ); // dst(x,y) = src2(x,y) - src1(x,y) for all (x, y) 4)係数演算 Ix*Ix, Ix*Iyなどを求めるには、画素ごとの乗算を用いるとよい。 // 乗算 cvMul( src1, src2, dst ); // dst(x,y) = src1(x,y) * src2(x,y) for all (x, y) 5)ガウス窓による総和 ガウス窓を用いた重み付け和を求めるには、平滑化フィルタをもちいるとよい。 cvSmoothは重みの総和が1となるように正規化されている。 // 標準偏差10画素のガウス窓を用いた平滑化 cvSmooth( src, dst, CV_GAUSSIAN, 0, 0, 10 ); // (Σgauss*Ix*Ix)/Σgauss 6)画素ごとのアクセス 画素ごとに画素値にアクセスするには、cvGetReal2D関数を使う(濃淡画像の場合)。 for ( int i=0; iheight; i++ ){ for ( int j=0; jwidth; j++ ){ float val = cvGetReal2D( img1, i, j ); // 画素値を変数valに代入 cvSetReal2D( img2, i, j, 2*val); // 2倍して別の画像に書き込み } } 7)画像のファイル保存 画像の保存はcvSaveImage関数を使う。拡張子にあわせて自動でフォーマット変換される。 // 画像をファイルに保存 cvSaveImage( "result.png", result ); 8)画像の画面への表示 画像を画面に表示するにはcvNameWIndow関数でウィンドウを生成し、そのウィンドウに 対してcvShowImage関数で画像を割り当て、その後でcvWaitKey関数を実行して表示する。 // ウィンドウの生成 ("Test"というタイトルがつく)。自動でウィンドウサイズが調整される。 cvNamedWindow( "Test", CV_WINDOW_AUTOSIZE ); // "Test"というタイトルのウィンドウに画像resultを割り付ける(まだ表示されない) cvShowImage( "Test", result ); // キー入力待ちすると同時に実際に画面表示。なにかキー入力があると処理続行 (void)cvWaitKey(0);