CV リファレンス マニュアル
-
画像処理(Image Processing)
- 勾配,エッジ,コーナー(Gradients, Edges and Corners)
- サンプリング,補間,幾何変換(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形式でもよい.
ヒストグラム(Histograms)
CvHistogram
多次元ヒストグラムの構造体
typedef struct CvHistogram { int type; CvArr* bins; float thresh[CV_MAX_DIM][2]; /* 一様分布ヒストグラム用の配列 */ float** thresh2; /* 非一様分布ヒストグラム用の配列 */ CvMatND mat; /* ヒストグラム配列用に組み込まれた行列のヘッダ */ } CvHistogram;
CreateHist
ヒストグラムを生成する
CvHistogram* cvCreateHist( int dims, int* sizes, int type,
float** ranges=NULL, int uniform=1 );
- dims
- ヒストグラムの次元数.
- sizes
- ヒストグラム各次元のサイズを示す配列.
- type
- ヒストグラム表現フォーマット.CV_HIST_ARRAY は,ヒストグラムデータが多次元で密な配列CvMatNDで表現されていることを意味する. CV_HIST_SPARSE は,ヒストグラムデータが多次元で疎な配列 CvSparseMat で表現されていることを意味する.
- ranges
- ヒストグラムのビン(bin)(値域)を示す配列.このパラメータの意味はパラメータuniformに依存している.このレンジは,ヒストグラムを計算したり,またどのヒストグラムのビンが入力画像のどの値やどのデータ要素に対応するかを決めるためのバックプロジェクションで用いられる.
- uniform
- 一様性に関するフラグ.非0の場合,ヒストグラムは等間隔のビンを持ち, 0<=i<dims の範囲のranges[i] は,それぞれi番目の次元のヒストグラムの下位と上位の境界を示す2つの値からなる配列である.各ヒストグラムのビンについて,i番目の入力タプル値のレンジを決めるために,[lower, upper]で表される全レンジは, sizes[i]個に等しく分割される.0の場合,ranges配列のi番目の要素は,lower0, upper0, lower1, upper1 == lower2, ..., uppersizes[i]-1というsizes[i]+1 個の要素を持つ.ここで,lowerj , upperjはj番目のビンに対するi番目の入力タプル値の上下の境界をそれぞれ表す.このフラグが0であろうとなかろうと,ヒストグラムのビンの指定された範囲を越えるような入力値は,cvCalcHist ではカウントされず,cvCalcBackProject では0で満たされる.
関数 cvCreateHist は,指定サイズのヒストグラムを生成し,そのヒストグラムのポインタを返す. 配列 ranges が 0 の場合は,ヒストグラムのビンは,後から関数 cvSetHistBinRanges を用いて決定される. しかし,cvCalcHist と cvCalcBackProject においてはビンのレンジを設定せずに,8ビット画像を,0..255 の等間隔ビンであると仮定して処理する.
SetHistBinRanges
ヒストグラムのビンのレンジをセットする
void cvSetHistBinRanges( CvHistogram* hist, float** ranges, int uniform=1 );
- hist
- ヒストグラム.
- ranges
- ビンのレンジの配列.cvCreateHist参照.
- uniform
- 一様性フラグ.cvCreateHist参照.
関数 cvSetHistBinRanges は,ヒストグラムのビンのレンジをセットする独立関数である. パラメータranges,uniform の詳しい説明は 関数 cvCalcHist を参照のこと.この関数ではレンジの初期化も可能である. ヒストグラムのビンのレンジは,ヒストグラムやバックプロジェクションの計算前にセットしておかなければならない.
ReleaseHist
ヒストグラムを解放する
void cvReleaseHist( CvHistogram** hist );
- hist
- 解放するヒストグラムへのポインタのポインタ.
関数 cvReleaseHist は,ヒストグラム(ヘッダ・データ共)を解放する. ヒストグラムへのポインタは,この関数でクリアされる. ポインタ*hist が既にNULLである場合,この関数は何も行わない.
ClearHist
ヒストグラムをクリアする
void cvClearHist( CvHistogram* hist );
- hist
- ヒストグラム.
関数 cvClearHist は,密なヒストグラムの場合,全てのヒストグラムのビンを0にセットする, また疎なヒストグラムの場合は,すべてのヒストグラムのビンを削除する.
MakeHistHeaderForArray
配列からヒストグラムを作成する
CvHistogram* cvMakeHistHeaderForArray( int dims, int* sizes, CvHistogram* hist,
float* data, float** ranges=NULL, int uniform=1 );
- dims
- ヒストグラムの次元数.
- sizes
- ヒストグラムの各次元のサイズの配列.
- hist
- ヒストグラムのヘッダ.この関数で初期化される.
- data
- ヒストグラムのビンを保存するための配列.
- ranges
- ヒストグラムのビンのレンジ.cvCreateHist参照.
- uniform
- 一様性フラグ.cvCreateHist参照.
関数 cvMakeHistHeaderForArray は,ユーザによって領域確保されたヘッダとビンを持つヒストグラムを初期化する.最後に,関数 cvReleaseHist を呼び出す必要はない. 密なヒストグラムのみ,この方法で初期化する事が可能である.この関数は hist を返す.
QueryHistValue_*D
ヒストグラムのビンの値の問い合わせを行う
#define cvQueryHistValue_1D( hist, idx0 ) \ cvGetReal1D( (hist)->bins, (idx0) ) #define cvQueryHistValue_2D( hist, idx0, idx1 ) \ cvGetReal2D( (hist)->bins, (idx0), (idx1) ) #define cvQueryHistValue_3D( hist, idx0, idx1, idx2 ) \ cvGetReal3D( (hist)->bins, (idx0), (idx1), (idx2) ) #define cvQueryHistValue_nD( hist, idx ) \ cvGetRealND( (hist)->bins, (idx) )
- hist
- ヒストグラム.
- idx0, idx1, idx2, idx3
- ビンのインデックス.
- idx
- インデックスの配列.
マクロ cvQueryHistValue_*D は,1〜n次元ヒストグラムの指定されたビンの値を返す. 疎なヒストグラムの場合で,ビンがヒストグラムに存在せず,新しいビンも作成されない場合,この関数は0を返す.
GetHistValue_*D
ヒストグラムのビンへのポインタを返す
#define cvGetHistValue_1D( hist, idx0 ) \ ((float*)(cvPtr1D( (hist)->bins, (idx0), 0 )) #define cvGetHistValue_2D( hist, idx0, idx1 ) \ ((float*)(cvPtr2D( (hist)->bins, (idx0), (idx1), 0 )) #define cvGetHistValue_3D( hist, idx0, idx1, idx2 ) \ ((float*)(cvPtr3D( (hist)->bins, (idx0), (idx1), (idx2), 0 )) #define cvGetHistValue_nD( hist, idx ) \ ((float*)(cvPtrND( (hist)->bins, (idx), 0 ))
- hist
- ヒストグラム.
- idx0, idx1, idx2, idx3
- ビンのインデックス.
- idx
- インデックスの配列.
マクロ cvGetHistValue_*D は,1〜n次元ヒストグラムの指定されたビンへのポインタを返す. 疎なヒストグラムの場合で,既にビンが存在している場合以外は,この関数が新しいビンを作成し,0にセットする.
GetMinMaxHistValue
最大値,最小値を持つビンを求める
void cvGetMinMaxHistValue( const CvHistogram* hist,
float* min_value, float* max_value,
int* min_idx=NULL, int* max_idx=NULL );
- hist
- ヒストグラム.
- min_value
- ヒストグラムの最小値へのポインタ.
- max_value
- ヒストグラムの最大値へのポインタ.
- min_idx
- 最小値の場所の配列へのポインタ.
- max_idx
- 最大値の場所の配列へのポインタ.
関数 cvGetMinMaxHistValue ヒストグラムのビンの最小値/最大値とそれらの場所を求める. 出力引数のいくつかはオプションである.同じ値の最大値や最小値が複数存在する場合,辞書順に並べたときに最も先頭になるインデックスが返される.
NormalizeHist
ヒストグラムの正規化を行う
void cvNormalizeHist( CvHistogram* hist, double factor );
- hist
- ヒストグラムへのポインタ.
- factor
- 正規化係数.
関数 cvNormalizeHist は,ビンの値の合計が factor に等しくなるようにスケーリングする事で,ヒストグラムのビンを正規化する.
ThreshHist
ヒストグラムの閾値処理を行う
void cvThreshHist( CvHistogram* hist, double threshold );
- hist
- ヒストグラムへのポインタ.
- threshold
- 閾値レベル.
関数 cvThreshHist は,指定した閾値以下のヒストグラムのビンをクリアする.
CompareHist
二つの密なヒストグラムを比較する
double cvCompareHist( const CvHistogram* hist1, const CvHistogram* hist2, int method );
- hist1
- 一番目の密なヒストグラム.
- hist2
- 二番目の密なヒストグラム.
- method
- 比較手法.以下のいずれか.
- CV_COMP_CORREL
- CV_COMP_CHISQR
- CV_COMP_INTERSECT
- CV_COMP_BHATTACHARYYA
関数 cvCompareHist は,以下に示すように,指定された手法を用いて二つの密なヒストグラムを比較する(ヒストグラム間の距離を求める). (H1 は,一番目のヒストグラムを,H2 は二番目のヒストグラムを それぞれ表す)
相関 (method=CV_COMP_CORREL): d(H1,H2)=sumI(H'1(I)•H'2(I))/sqrt(sumI[H'1(I)2]•sumI[H'2(I)2]) ここで, H'k(I)=Hk(I)-1/N•sumJHk(J) (N=ヒストグラムのビンの個数) カイ二乗 (method=CV_COMP_CHISQR): d(H1,H2)=sumI[(H1(I)-H2(I))/(H1(I)+H2(I))] 交差 (method=CV_COMP_INTERSECT): d(H1,H2)=sumImin(H1(I),H2(I)) Bhattacharyya距離 (method=CV_COMP_BHATTACHARYYA): d(H1,H2)=sqrt(1-sumI(sqrt(H1(I)•H2(I))))
この関数は,上で計算された値d(H1,H2)を返す.
注意:手法CV_COMP_BHATTACHARYYA は,正規化されたヒストグラムでのみ実行可能である.
疎なヒストグラム,あるいは重み付けされた点が集まったような,より一般的な構造を比較するためには, 関数cvCalcEMD2 を用いる方が良い場合もある.
CopyHist
ヒストグラムのコピーを行う
void cvCopyHist( const CvHistogram* src, CvHistogram** dst );
- src
- コピー元のヒストグラム.
- dst
- コピー先のヒストグラムへのポインタ.
関数 cvCopyHist は,ヒストグラムのコピーを作成する. コピー先のヒストグラムへのポインタ*dstがNULLの場合は, srcと同じサイズの新しいヒストグラムが作成される. それ以外の場合は,二つのヒストグラムは同一タイプ,サイズでないといけない. この関数はコピー元のヒストグラムのビンの値を,コピー先にコピーし, src内に定義されているのと同じビンの値域をセットする.
CalcHist
画像(群)のヒストグラムを計算する
void cvCalcHist( IplImage** image, CvHistogram* hist,
int accumulate=0, const CvArr* mask=NULL );
- image
- 入力画像群( CvMat** 形式でも構わない).全て同じサイズ・タイプ.
- hist
- ヒストグラムへのポインタ.
- accumulate
- 計算フラグ.セットされている場合は,ヒストグラムは処理前には最初にクリアされない. この特徴により,ユーザが複数の画像から単一のヒストグラムを作成する事や,オンラインでヒストグラムを更新する事が可能である.
- mask
- 処理マスク.入力画像中のどのピクセルをカウントするかを決定する.
関数 cvCalcHist は,一つ以上のシングルチャンネル画像からヒストグラムを計算する. ヒストグラムのビンを増加(インクリメント)するために用いられるタプルの各要素は, 対応する入力画像群の同じ場所から取り出される.
(例)カラー画像における色相−彩度の2次元ヒストグラムの計算と表示
#include <cv.h> #include <highgui.h> int main( int argc, char** argv ) { IplImage* src; if( argc == 2 && (src=cvLoadImage(argv[1], 1))!= 0) { IplImage* h_plane = cvCreateImage( cvGetSize(src), 8, 1 ); IplImage* s_plane = cvCreateImage( cvGetSize(src), 8, 1 ); IplImage* v_plane = cvCreateImage( cvGetSize(src), 8, 1 ); IplImage* planes[] = { h_plane, s_plane }; IplImage* hsv = cvCreateImage( cvGetSize(src), 8, 3 ); int h_bins = 30, s_bins = 32; int hist_size[] = {h_bins, s_bins}; /* 色相は0(0度,赤)から180(360度,赤)まで変化する */ float h_ranges[] = { 0, 180 }; /* 彩度は0(黒-グレー-白)から255(純粋なスペクトラムカラー)まで変化する */ float s_ranges[] = { 0, 255 }; float* ranges[] = { h_ranges, s_ranges }; int scale = 10; IplImage* hist_img = cvCreateImage( cvSize(h_bins*scale,s_bins*scale), 8, 3 ); CvHistogram* hist; float max_value = 0; int h, s; cvCvtColor( src, hsv, CV_BGR2HSV ); cvCvtPixToPlane( hsv, h_plane, s_plane, v_plane, 0 ); hist = cvCreateHist( 2, hist_size, CV_HIST_ARRAY, ranges, 1 ); cvCalcHist( planes, hist, 0, 0 ); cvGetMinMaxHistValue( hist, 0, &max_value, 0, 0 ); cvZero( hist_img ); for( h = 0; h < h_bins; h++ ) { for( s = 0; s < s_bins; s++ ) { float bin_val = cvQueryHistValue_2D( hist, h, s ); int intensity = cvRound(bin_val*255/max_value); cvRectangle( hist_img, cvPoint( h*scale, s*scale ), cvPoint( (h+1)*scale - 1, (s+1)*scale - 1), /* グレースケールのヒストグラムを描画する*/ CV_RGB(intensity,intensity,intensity), CV_FILLED ); } } cvNamedWindow( "Source", 1 ); cvShowImage( "Source", src ); cvNamedWindow( "H-S Histogram", 1 ); cvShowImage( "H-S Histogram", hist_img ); cvWaitKey(0); } }
CalcBackProject
バックプロジェクションの計算を行う
void cvCalcBackProject( IplImage** image, CvArr* back_project, const CvHistogram* hist );
- image
- 入力画像群( CvMat** 形式でも構わない).すべて同一サイズ,同一タイプ.
- back_project
- 出力のバックプロジェクション画像.入力画像群と同じタイプ.
- hist
- ヒストグラム.
関数 cvCalcBackProject は, ヒストグラムのバックプロジェクションを計算する. すべての入力シングルチャンネル画像の同じ位置のピクセル群の各タプルについて, 関数はそのタプルに対応したヒストグラムのビンの値を出力画像のピクセル値としてセットする. 統計学的には,出力画像の各ピクセル値は, 与えられた分布(ヒストグラム)における観測タプルの出現確率であると言える. 例えば,画像中から赤いオブジェクトを見つけるためには,以下に示す方法がある.
- 画像にオブジェクトだけが写っていると仮定し,その赤いオブジェクトの色相に関するヒストグラムを計算する.このヒストグラムは赤に対応する最大値を持つ可能性が高い.
- ヒストグラムを用いてオブジェクトの位置を計算するために,入力画像の色相平面のバックプロジェクションを計算し,画像に対して閾値処理を行う.
- 閾値処理された2値画像中の連結成分を検索し,ある評価基準(例えば,最大サイズの連結成分など)に基づき,正しい連結成分を選び出す.
CalcBackProjectPatch
ヒストグラムの比較に基づき画像内部でのテンプレート位置を求める
void cvCalcBackProjectPatch( IplImage** images, CvArr* dst,
CvSize patch_size, CvHistogram* hist,
int method, float factor );
- images
- 入力画像群( CvMat** 形式でも構わない).すべて同じサイズ.
- dst
- 出力画像.
- patch_size
- 入力画像群上をスライドさせるテンプレートのサイズ.
- hist
- テンプレートのヒストグラム.
- method
- 比較方法.値は関数 cvCompareHist に渡される(この関数に関する記述を参照).
- factor
- ヒストグラムの正規化係数.出力画像の正規化スケールに影響する.値に確信がない場合は,1にする.
関数 cvCalcBackProjectPatch は,入力されたヒストグラムと, 入力画像 images における指定されたサイズの各矩形領域に関して計算されたヒストグラム, とを比較し,その結果を出力マップ dst に保存する.
擬似コードでは,この処理は以下のように表現できる.
for (x,y) in images (until (x+patch_size.width-1,y+patch_size.height-1) is inside the images) do 画像中のROI (x,y,x+patch_size.width,y+patch_size.height) についてヒストグラムを計算する (cvCalcHist 参照) 係数を用いてヒストグラムを正規化する (cvNormalizeHist 参照) 正規化されたヒストグラムと入力ヒストグラムhistを指定された手法で比較する (cvCompareHist 参照) 結果をdst(x,y)へ保存する end forこれと類似した関数 cvMatchTemplate も参照のこと.
テンプレートによるバックプロジェクションの計算
CalcProbDensity
一つのヒストグラムをもう一方のヒストグラムで割る
void cvCalcProbDensity( const CvHistogram* hist1, const CvHistogram* hist2,
CvHistogram* dst_hist, double scale=255 );
- hist1
- 一番目のヒストグラム(除数).
- hist2
- 二番目のヒストグラム.
- dst_hist
- 出力ヒストグラム.
- scale
- 出力ヒストグラムのスケール係数.
関数 cvCalcProbDensity は,以下のように二つのヒストグラムからオブジェクトの確率密度を計算する.
hist1(I)==0 の場合 dist_hist(I)=0 hist1(I)!=0 && hist2(I)>hist1(I) の場合 scale hist1(I)!=0 && hist2(I)<=hist1(I) の場合 hist2(I)*scale/hist1(I)
出力ヒストグラムのビンの値は,scaleに等しいか小さくなる.
EqualizeHist
グレースケール画像のヒストグラムを均一化する.
void cvEqualizeHist( const CvArr* src, CvArr* dst );
- src
- 入力画像.8ビットシングルチャンネル.
- dst
- 出力画像.srcと同じサイズ・同じデータタイプ.
関数 cvEqualizeHist は以下のアルゴリズムを用いて,入力画像のヒストグラムを均一化する.
1. src に対して,ヒストグラム H を計算する. 2. ヒストグラムを,ビンの総和が255になるように正規化する 3. ヒストグラムの積分(総和)を以下のように計算する. H(i) = sum0≤j≤iH(j) 4. ルックアップテーブル dst(x,y)=H(src(x,y)) を用いて,入力画像を変換する
このアルゴリズムは輝度を均一化し,画像のコントラストを上げる.