CV リファレンス マニュアル
- 画像処理(Image Processing)
- 勾配,エッジ,コーナー,特徴(Gradients, Edges, Corners and Features)
- サンプリング,補間,幾何変換(Sampling, Interpolation and Geometrical Transforms)
- モルフォロジー演算(Morphological Operations)
- フィルタと色変換(Filters and Color Conversion)
- ピラミッドとその応用(Pyramids and the Applications)
- 画像分割,領域結合,輪郭検出(Image Segmentation, Connected Components and Contour Retrieval)
- 画像と形状のモーメント(Image and Contour Moments)
- 特殊な画像変換(Special Image Transforms)
- ヒストグラム(Histograms)
- マッチング(Matching)
- 構造解析(Structural Analysis)
- モーション解析と物体追跡(Motion Analysis and Object Tracking)
- パターン認識(Pattern Recognition)
- カメラキャリブレーションと3次元再構成(Camera Calibration and 3D Reconstruction)
- 参考文献
画像処理(Image Processing)
注釈:
この章では画像処理及び解析のための関数について述べる.ほとんどの関数はピクセルの2次元配列に対して実行される.OpenCVでは配列を「画像」として取り扱う.しかしその配列はIplImage形式である必要はなく,CvMat形式またはCvMatND形式でもよい.
勾配,エッジ,コーナー,特徴(Gradients, Edges, Corners and Features)
Sobel
拡張Sobel演算子を用いて1次,2次,3次または混合次数の微分画像を計算する
void cvSobel( const CvArr* src, CvArr* dst, int xorder, int yorder, int aperture_size=3 );
- src
- 入力画像.
- dst
- 出力画像.
- xorder
- x-導関数の次数.
- yorder
- y-導関数の次数.
- aperture_size
- 拡張Sobelカーネルのサイズは1, 3, 5または7 のいずれかである必要がある.aperture_size=1 の場合を除いて,aperture_size × aperture_size の,(二つのベクトルの積に)分離可能なカーネルが導関数の計算に用いられる. aperture_size=1 の場合は,3x1 あるいは 1x3 のカーネルが用いられる(ガウシアン(Gaussian)による平滑化は行わない). 特別な値であるaperture_size=CV_SCHARR(=-1) もあり,3x3 Sobelよりも精度の良い結果が得られる3x3 のSharr のフィルタである.ここでScharrのアパーチャは以下の通り.
| -3 0 3| |-10 0 10| | -3 0 3|
これはx-導関数のためのカーネルであり,転置することによってy-導関数のためのカーネルとなる.
関数 cvSobel は以下のように,画像と適切なカーネルの畳み込みによって,微分画像を計算する.
dst(x,y) = dxorder+yordersrc/dxxorder•dyyorder |(x,y)Sobel演算子はガウシアンによる平滑化と,微分の重ね合わせ処理であるので,その結果はノイズに対してある程度頑健である. 1次のx-微分画像 あるいは y-微分画像を計算するときには,ほとんどの場合,引数はそれぞれ(xorder=1, yorder=0, aperture_size=3)または (xorder=0, yorder=1, aperture_size=3) を用いる.前者の場合,Sobelカーネルは
|-1 0 1| |-2 0 2| |-1 0 1|
であり,後者のSobelカーネルは
|-1 -2 -1| | 0 0 0| | 1 2 1| あるいは | 1 2 1| | 0 0 0| |-1 -2 -1|となる.どちらになるかは画像原点(IplImage構造体のoriginフィールド)に依存する. スケーリングは行われないので,出力画像の各ピクセル値は,ほとんどの場合入力画像のそれよりも大きな値になる.オーバーフローを避けるために,例えば入力画像が8ビットの場合,出力画像として16ビット画像を指定する必要がある.このような16ビット画像は,関数cvConvertScaleかcvConvertScaleAbsを用いて,8ビット画像に戻すことができる.一方でこの関数は,8ビット画像だけでなく,32ビット浮動小数点型画像の処理も可能である.入力画像,出力画像共に,同じサイズあるいは同じROIサイズのシングルチャンネル画像である必要がある.
Laplace
画像のラプラシアン(Laplacian)を計算する
void cvLaplace( const CvArr* src, CvArr* dst, int aperture_size=3 );
- src
- 入力画像.
- dst
- 出力画像.
- aperture_size
- アパーチャサイズ(cvSobelと同じ).
関数 cvLaplace は,以下のようにSobel演算子を用いて計算されたxとyの2次微分を加算することで,入力画像のラプラシアン(Laplacian)を計算する.
dst(x,y) = d2src/dx2 + d2src/dy2
aperture_size=1 を指定した場合は,以下のカーネルを用いた入力画像との畳み込みと同じ処理を,高速に行う.
|0 1 0| |1 -4 1| |0 1 0|
関数 cvSobel と同様に,スケーリングは行わない.そしてこれらの関数がサポートする入力と出力のフォーマットの組み合わせも同じである.
Canny
エッジ検出のためのCannyアルゴリズムを実装する
void cvCanny( const CvArr* image, CvArr* edges, double threshold1,
double threshold2, int aperture_size=3 );
- image
- 入力画像.
- edges
- この関数によって得られたエッジ画像.
- threshold1
- 1番目の閾値.
- threshold2
- 2番目の閾値.
- aperture_size
- Sobel演算子のアパーチャサイズ(cvSobel参照).
関数cvCannyは,Cannyアルゴリズムを使用して, 入力画像 imageに含まれているエッジを検出し, それを出力画像 edges に保存する. threshold1 と threshold2 のうち小さいほうがエッジ同士を接続するために用いられ,大きいほうが強いエッジの初期検出に用いられる.
PreCornerDetect
コーナー検出のための特徴マップを計算する
void cvPreCornerDetect( const CvArr* image, CvArr* corners, int aperture_size=3 );
- image
- 入力画像.
- corners
- コーナーの候補を保存する画像.
- aperture_size
- Sobel演算子のアパーチャサイズ(cvSobel参照).
関数 cvPreCornerDetect は関数 Dx2Dyy+Dy2Dxx - 2DxDyDxy を計算する. ここでD? は画像の1次微分を D??は画像の2次微分を表す.コーナーは,以下のようにこの関数の極大値を求めることで検出される.
// ここでは,画像が浮動小数点型であることを仮定する IplImage* corners = cvCloneImage(image); IplImage* dilated_corners = cvCloneImage(image); IplImage* corner_mask = cvCreateImage( cvGetSize(image), 8, 1 ); cvPreCornerDetect( image, corners, 3 ); cvDilate( corners, dilated_corners, 0, 1 ); cvSub( corners, dilated_corners, corners ); cvCmpS( corners, 0, corner_mask, CV_CMP_GE ); cvReleaseImage( &corners ); cvReleaseImage( &dilated_corners );
CornerEigenValsAndVecs
コーナー検出のために画像ブロックの固有値と固有ベクトルを計算する
void cvCornerEigenValsAndVecs( const CvArr* image, CvArr* eigenvv,
int block_size, int aperture_size=3 );
- image
- 入力画像.
- eigenvv
- 結果保存用の画像.入力画像の6倍のサイズが必要.
- block_size
- 隣接ブロックのサイズ(以下の説明を参照).
- aperture_size
- Sobel演算子のアパーチャサイズ(cvSobel参照).
関数 cvCornerEigenValsAndVecs は,すべてのピクセルについて注目ピクセルの block_size × block_size の隣接領域S(p) に着目する. まず,以下のように各隣接ブロックにおける導関数の共変動行列を計算する.
| sumS(p)(dI/dx)2 sumS(p)(dI/dx•dI/dy)| M = | | | sumS(p)(dI/dx•dI/dy) sumS(p)(dI/dy)2 |
この行列の固有値と固有ベクトルを計算した後,結果は(λ1, λ2, x1, y1, x2, y2)の形式で出力画像 eigenvv に保存される.
λ1, λ2 - 行列 M の固有値(ソートされていない)
(x1, y1) - λ1に対する固有ベクトル
(x2, y2) - λ2に対する固有ベクトル
CornerMinEigenVal
コーナー検出のために,画像ブロックの最小固有値を計算する
void cvCornerMinEigenVal( const CvArr* image, CvArr* eigenval, int block_size, int aperture_size=3 );
- image
- 入力画像.
- eigenval
- 最小固有値を保存する画像.image と同じサイズでなくてはならない.
- block_size
- 隣接ブロックのサイズ(cvCornerEigenValsAndVecsの説明を参照).
- aperture_size
- Sobel演算子のアパーチャサイズ(cvSobel参照).入力画像が浮動小数点型である場合,このパラメータは差分を計算するために用いられる固定小数点型フィルタの数を表す.
関数 cvCornerMinEigenVal は cvCornerEigenValsAndVecs と類似しているが, すべてのピクセルについて,隣接ブロックにおける導関数の共変動行列の最小固有値だけを求める関数である. つまり,前の関数におけるmin(λ1, λ2) に相当する.
CornerHarris
Harris エッジ検出器
void cvCornerHarris( const CvArr* image, CvArr* harris_dst,
int block_size, int aperture_size=3, double k=0.04 );
- image
- 入力画像.
- harris_dst
- 検出結果を保存する画像.入力画像 image と同じサイズでなくてはならない.
- block_size
- 隣接ブロックのサイズ (cvCornerEigenValsAndVecsの説明参照).
- aperture_size
- Sobel演算子のアパーチャサイズ(cvSobel参照).入力画像が浮動小数点型である場合,このパラメータは差分を計算するために用いられる固定小数点型フィルタの数を表す.
- k
- Harris検出器のパラメータ.以下に示す式を参照.
関数 cvCornerHarris は,Harrisの手法を用いて,入力画像中の特徴点(コーナー)を検出する. cvCornerMinEigenVal や cvCornerEigenValsAndVecsと同様の機能を持ち, それぞれのピクセルにおいて,block_size×block_size 隣接における 2×2 サイズの勾配から共変動行列M を計算する.その後,
det(M) - k*trace(M)2の値を,出力画像の対応するピクセルに保存する.出力画像の極大値を求めることで,画像中のコーナーを検出することができる.
FindCornerSubPix
コーナー位置を高精度化する
void cvFindCornerSubPix( const CvArr* image, CvPoint2D32f* corners,
int count, CvSize win, CvSize zero_zone,
CvTermCriteria criteria );
- image
- 入力画像.
- corners
- コーナーの初期座標が入力され,高精度化された座標が出力される.
- count
- コーナーの数.
- win
- 探索ウィンドウの半分のサイズ.(例)win=(5,5) ならば 5*2+1 × 5*2+1 = 11 × 11 が探索ウィンドウして使われる.
- zero_zone
- 以下に示す式において,総和を計算する際に含まれない,探索領域の中心に存在する総和対象外領域の半分のサイズ. この値は,自己相関行列において発生しうる特異点を避けるために用いられる. 値が (-1,-1) の場合は,そのようなサイズはないということを意味する.
- criteria
- コーナー座標の高精度化のための繰り返し処理の終了条件.コーナー位置の高精度化の繰り返し処理は,規定回数に達するか,目標精度に達したときに終了する.criteria には繰り返しの最大回数と目標精度のどちらか一方,または両方を指定する.
関数 cvFindCornerSubPix は,下図に示すようなサブピクセル精度のコーナー位置,あるいは鞍点を見つけるため繰り返し適用される.
サブピクセル精度のコーナー検索は,中心 q から q の隣接にある点 p への全てのベクトルが, p の画像勾配(これは,画像と観測ノイズに影響される)に直交するという知見に基づいている. これは,以下の式で表現できる.
εi=DIpiT•(q-pi)ここでDIpi は q の隣接に存在する点 pi における画像勾配を表す.q は εi を最小にするような値として得られる.連立方程式は以下のように εi' を 0 にすることで得られる
sumi(DIpi•DIpiT)•q - sumi(DIpi•DIpiT•pi) = 0
ここで画像勾配は q の隣接(探索窓)で総和される. 1次勾配を G ,2次勾配を b と呼び,次のように表す.
q=G-1•b
このアルゴリズムは,隣接の中心を,この新しい中心 q にセットしなおし,その中心が与えられた閾値(目標精度)の内に収まるまで繰り返し計算する.
GoodFeaturesToTrack
画像内の鮮明なコーナーを検出する
void cvGoodFeaturesToTrack( const CvArr* image, CvArr* eig_image, CvArr* temp_image,
CvPoint2D32f* corners, int* corner_count,
double quality_level, double min_distance,
const CvArr* mask=NULL, int block_size=3,
int use_harris=0, double k=0.04 );
- image
- 8ビット,または32ビット浮動小数点型シングルチャンネルの入力画像.
- eig_image
- 32ビット浮動小数点型のテンポラリ画像.サイズは image と同じである.
- temp_image
- 別のテンポラリ画像.サイズ・フォーマットともに eig_image と同じである.
- corners
- 出力パラメータ.検出されたコーナー.
- corner_count
- 出力パラメータ.検出されたコーナーの数.
- quality_level
- 最大・最小の固有値に乗ずる定数(検出される画像コーナの許容最低品質を指定する).
- min_distance
- 出力される画像コーナー間の許容最低距離(ユークリッド距離を用いる).
- mask
- 注目領域(ROI).指定された領域またはmask が NULL の場合は画像全体から点を選ぶ.
- block_size
- 平均化ブロックのサイズ.この関数で内部的に用いられる cvCornerMinEigenVal あるいは, cvCornerHarris に,この引数が渡される.
- use_harris
- 0でない場合は,デフォルトの cvCornerMinEigenVal の代わりに,Harris検出器(cvCornerHarris)を用いる.
- k
- Harris検出器のパラメータ(use_harris≠0 のときのみ使用).
関数 cvGoodFeaturesToTrack は,画像中から大きな固有値を持つコーナーを検出する.この関数は最初に,すべての入力画像のピクセルに対して, cvCornerMinEigenVal を用いて最小の固有値を計算し,結果を eig_image に保存する. 次に,non-maxima suppressionを実行する(3x3の隣接領域内の極大のみが残る). 次のステップでは, quality_level•max(eig_image(x,y)) より小さい最小固有値をもつコーナーを削除する. 最後に,この関数はコーナー点に着目し(最も強いコーナーが一番最初に対象となる),新しく着目した特徴点とそれ以前に対象とした特徴点群との距離が min_distance よりも大きいことをチェックすることで,すべての検出されたコーナーそれぞれの距離が十分離れていることを保証する. そのため,この関数は鮮明な特徴点との距離が近い特徴点を削除する.
ExtractSURF
画像中からSURF(Speeded Up Robust Features)を検出する
void cvExtractSURF( const CvArr* image, const CvArr* mask,
CvSeq** keypoints, CvSeq** descriptors,
CvMemStorage* storage, CvSURFParams params );
- image
- 8ビット,グレースケールの入力画像.
- mask
- オプション:8ビットのマスク画像.非0 のマスクピクセルが50%以上を占める領域からのみ,特徴点検出を行う.
- keypoints
- 出力パラメータ.キーポイントのシーケンスへのポインタのポインタ.
これは,CvSURFPoint 構造体のシーケンスに
なる:
typedef struct CvSURFPoint { CvPoint2D32f pt; // 画像中の特徴点の位置 int laplacian; // -1,0,+1.その点におけるラプラシアンの符号. // 特徴点の比較を高速化するために用いられる // (通常,ラプラシアンの符号が異なる特徴同士は一致しない) int size; // 特徴のサイズ float dir; // 特徴の方向:0〜360度 float hessian; // ヘッシアン:ヘッセ行列の行列式 // (特徴の強さのおおよその推定に用いられる.params.hessianThreshold を参照) } CvSURFPoint;
- descriptors
- オプション:出力パラメータ.ディスクリプタのシーケンスへのポインタのポインタ. シーケンスの各要素は,params.extended の値に依存して, 64-要素,あるいは 128-要素の浮動小数点数(CV_32F)ベクトルとなる. パラメータが NULL の場合,ディスクリプタは計算されない.
- storage
- キーポイントとディスクリプタが格納されるメモリストレージ.
- params
- CvSURFParams 構造体に入れられた,様々なアルゴリズムパラメータ:
typedef struct CvSURFParams { int extended; // 0:基本的なディスクリプタ(64要素) // 1:拡張されたディスクリプタ(128要素) double hessianThreshold; // keypoint.hessian の値がこの閾値よりも大きい特徴だけが検出される. // 適切なデフォルト値は,おおよそ300〜500 である // (画像の局所的なコントラストと鮮明さの平均に依存する). // ユーザは,hessian や,その他の特徴に基づいて, // 不要な特徴点を除去することができる. int nOctaves; // 特徴検出に用いられるオクターブ数 // オクターブが一つ上がる度に,特徴のサイズが2倍になる(デフォルトは3). int nOctaveLayers; // 各オクターブ内に存在するレイヤ数(デフォルトは4). } CvSURFParams; CvSURFParams cvSURFParams(double hessianThreshold, int extended=0); // デフォルトパラメータを返す.
関数 cvExtractSURF は, [Bay06] で述べられているように,画像からロバストな特徴を検出する. 各特徴に対して,位置,サイズ,方向が返される.オプションとして,基本(拡張)ディスクリプタも求められる. この関数は,オブジェクト追跡や位置特定,複数画像合成などに利用することができる. OpenCVサンプルディレクトリにある find_obj.cpp デモを参照すること.