多次元ヒストグラム.
typedef struct CvHistogram
{
int type;
CvArr* bins;
float thresh[CV_MAX_DIM][2]; /* 一様分布ヒストグラム用 */
float** thresh2; /* 非一様分布ヒストグラム用 */
CvMatND mat; /* 内部で利用されるヒストグラム配列の行列ヘッダ */
}
CvHistogram;
バックプロジェクションを計算します.
パラメタ: |
|
---|
関数 cvCalcBackProject は,ヒストグラムのバックプロジェクションを求めます.この関数は,すべての入力画像(シングルチャンネル)上の同じ位置にあるピクセルのタプルに対して,そのタプルに対応したヒストグラムのビンの値を,出力画像のピクセル値としてセットします.統計学的には,出力画像の各ピクセル値は,与えられた分布(ヒストグラム)における観測タプルの出現確率であると言えます.例えば,画像中の赤い物体を見つけるためには,以下のような方法が考えられます:
これは,3番目のステップ以外は,Camshiftの色物体追跡器のアルゴリズムとほぼ同じです.Camshift追跡器では,この3番目のステップの代わりにCAMSHIFTアルゴリズムが用いられ,物体の前ステップでの位置が与えられると,バックプロジェクション上の物体の現在位置が求められます.
ヒストグラムを比較することで,画像中のテンプレート位置を求めます.
パラメタ: |
|
---|
関数 cvCalcBackProjectPatch は,与えられたヒストグラムと,入力画像の一部分のヒストグラムとを比較することで,バックプロジェクションを計算します.配列 image は,ある画像のROIを様々な方法で評価した結果から構成されます.その評価結果には,色相, x 方向微分, y 方向微分,ラプラシアンフィルタ,Gaborフィルタなどが考えられます(1つでも構いません).各手法の評価出力は,個別に集められてそれぞれ別の画像となります.画像配列 image は,これらの評価画像の集合です.また,多次元ヒストグラム hist は,画像配列 image からサンプリングした結果です.最終的なヒストグラムは,正規化されます.また,ヒストグラム hist は,配列 image の要素数と同じだけの次元を持ちます.
新しい画像はまず評価され,そのROI全体が画像配列 image に変換されます.その部分的なヒストグラムは,以下の図にあるように,中心にアンカーを持つ「パッチ」と重なった部分にある画像 image から計算されます. hist と比較できるように,このヒストグラムは,パラメータ norm_factor を利用して正規化されます.求められたヒストグラムは,比較手法に method を指定した関数 cvCompareHist を利用して,モデルヒストグラム hist と比較されます.その出力結果は,確率画像 dst の,パッチのアンカーに対応する場所に格納されます.毎回パッチをずらして,最終的にROI全体に対して処理が終わるまで,これを繰り返します.ヒストグラムの反復更新は,パッチの端の重ならなくなった部分のピクセル値を引き,さらに新しく重なる部分のピクセル値を加えることで,大幅に処理を削減できます.しかし,まだこれは実装されていません.
パッチによる投影計算
画像のヒストグラムを求めます.
パラメタ: |
|
---|
この関数は,1つあるいは複数のシングルチャンネル画像のヒストグラムを求めます.ヒストグラムのビンの値を増加させる入力タプルの要素は,対応する(複数の)入力画像の同じ位置から取り出されます.
#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);
}
}
あるヒストグラムを別のヒストグラムで割ります.
パラメタ: |
|
---|
この関数は,2つのヒストグラムから物体の確率密度を求めます:
出力ヒストグラムのビンの値は, scale 未満になります.
ヒストグラムをクリアします.
パラメタ: |
|
---|
この関数は,密な配列データをもつヒストグラムの場合はヒストグラムのすべてのビンの値を 0にし,疎な配列データを持つヒストグラムの場合はヒストグラムのすべてのビンを削除します.
2つの密なヒストグラムを比較します.
パラメタ: |
|
---|
この関数は,指定された手法を用いて2つの密なヒストグラムを比較します( は1番目のヒストグラムを, は2番目のヒストグラムを表します):
相関 (method=CV_COMP_CORREL)
ここで,
です.N はヒストグラムのビン数を表します.
カイ2乗 (method=CV_COMP_CHISQR)
交差 (method=CV_COMP_INTERSECT)
Bhattacharyya距離 (method=CV_COMP_BHATTACHARYYA)
この関数は, を返します.
注意:手法 CV_COMP_BHATTACHARYYA は,正規化されたヒストグラムでのみ動作します.
疎なヒストグラム,あるいはより一般的な構造である重み付き点群などを比較するためには,関数 CalcEMD2 の利用を検討してください.
ヒストグラムをコピーします.
パラメタ: |
|
---|
この関数は,ヒストグラムのコピーを作成します.2番目のヒストグラムポインタ *dst がNULLならば, src と同じサイズのヒストグラムが新たに作成されます.NULLでない場合は,2つのヒストグラムは同じ型,同じサイズでなければいけません.この関数は,コピー元のヒストグラムのビンの値をコピー先のヒストグラムにコピーし,ビンの範囲も src と同じになるようにセットします.
ヒストグラムを作成します.
パラメタ: |
|
---|
この関数は,指定されたサイズのヒストグラムを作成し,そのポインタを返します.配列 ranges が0の場合,後で関数 SetHistBinRanges によってヒストグラムのビンの範囲を指定しなければいけません.関数 CalcHist および CalcBackProject は,ビンの範囲を指定せずに 8 ビット画像を処理しますが,これは 0 から 255 までの等間隔のビンを仮定します.
ヒストグラムのビンへのポインタを返します.
パラメタ: |
|
---|
#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 )))
マクロ GetHistValue は,1次元,2次元,3次元,およびN-次元ヒストグラムの,指定されたビンへのポインタを返します.疎なヒストグラムにおいて,ヒストグラム中にビンが存在しない場合,この関数は新たにビンを作成し,その値を0にセットします.
最小値を持つビン,および最大値を持つビンを求めます.
パラメタ: |
|
---|
この関数は,最小値を持つビン,および最大値を持つビンとそれぞれの位置を求めます.出力に利用されるすべての引数は,オプションです.最小値や最大値が同値で複数存在する場合,(辞書順に並べた場合の)最小のインデックスを持つものが返されます.
配列からヒストグラムを作成します.
パラメタ: |
|
---|
この関数は,ヒストグラムを初期化します.そのヘッダとビンはユーザによって確保されるものです.後で ReleaseHist を呼ぶ必要はありません.また,この方法で初期化できるのは,密なヒストグラムだけです.この関数は, hist を返します.
ヒストグラムを正規化します.
パラメタ: |
|
---|
この関数は,ビンの値の合計が factor と等しくなるようにスケーリングを行うことで,ヒストグラムのビンの正規化を行います.
ヒストグラムのビンの値を取得します.
パラメタ: |
|
---|
#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) )
これらのマクロは,1次元,2次元,3次元,N次元ヒストグラムの指定したビンの値を返します.疎なヒストグラムにおいて指定されたビンが存在しない場合,新しいビンは作成されず,0が返されます.
ヒストグラムを解放します.
パラメタ: |
|
---|
この関数は,ヒストグラム(ヘッダとデータ)を解放します.この関数により,ヒストグラムへのポインタもクリアされます.ポインタ *hist が既に NULL の場合は,この関数は何もしません.
ヒストグラムのビンの上下限値をセットします.
パラメタ: |
|
---|
この関数は,ヒストグラムのビンの範囲をセットするための,単独で動作する関数です.パラメータ ranges と uniform のより詳しい説明は,同じように範囲を初期化できる関数 CreateHist を参照してください.ヒストグラムのビンの範囲は,ヒストグラムやヒストグラムのバックプロジェクションが計算されるよりも前にセットされていなければいけません.
ヒストグラムの閾値処理を行います.
パラメタ: |
|
---|
この関数は,指定した閾値以下のビンをクリアします.