ヒストグラム ================== .. highlight:: c .. index:: CvHistogram .. _CvHistogram: CvHistogram ----------- `id=0.649432818443 Comments from the Wiki `__ .. ctype:: CvHistogram 多次元ヒストグラム. .. code-block:: c typedef struct CvHistogram { int type; CvArr* bins; float thresh[CV_MAX_DIM][2]; /* 一様分布ヒストグラム用 */ float** thresh2; /* 非一様分布ヒストグラム用 */ CvMatND mat; /* 内部で利用されるヒストグラム配列の行列ヘッダ */ } CvHistogram; .. .. index:: CalcBackProject .. _CalcBackProject: CalcBackProject --------------- `id=0.386226887618 Comments from the Wiki `__ .. cfunction:: void cvCalcBackProject( IplImage** image, CvArr* back_project, const CvHistogram* hist ) バックプロジェクションを計算します. :param image: 入力画像(CvMat** の形式で渡される場合もあります). :param back_project: 入力画像と同じ型のバックプロジェクション画像. :param hist: ヒストグラム. 関数 ``cvCalcBackProject`` は,ヒストグラムのバックプロジェクションを求めます.この関数は,すべての入力画像(シングルチャンネル)上の同じ位置にあるピクセルのタプルに対して,そのタプルに対応したヒストグラムのビンの値を,出力画像のピクセル値としてセットします.統計学的には,出力画像の各ピクセル値は,与えられた分布(ヒストグラム)における観測タプルの出現確率であると言えます.例えば,画像中の赤い物体を見つけるためには,以下のような方法が考えられます: #. 画像にその物体だけが写っていると仮定し,その赤いオブジェクトの色相に関するヒストグラムを計算します.このヒストグラムは赤色に対して強い最大値を持つ傾向があります. #. ヒストグラムを利用し,物体を探索する画像の色相平面のバックプロジェクションを求めます.そして,その画像に閾値処理を施します. #. その結果画像から連結成分を探し,別の基準(例えば,最大の連結成分など)を利用して正しい成分を選択します. これは,3番目のステップ以外は,Camshiftの色物体追跡器のアルゴリズムとほぼ同じです.Camshift追跡器では,この3番目のステップの代わりにCAMSHIFTアルゴリズムが用いられ,物体の前ステップでの位置が与えられると,バックプロジェクション上の物体の現在位置が求められます. .. index:: CalcBackProjectPatch .. _CalcBackProjectPatch: CalcBackProjectPatch -------------------- `id=0.175868245493 Comments from the Wiki `__ .. cfunction:: void cvCalcBackProjectPatch( IplImage** images, CvArr* dst, CvSize patch_size, CvHistogram* hist, int method, double factor ) ヒストグラムを比較することで,画像中のテンプレート位置を求めます. :param images: 入力画像(CvMat** の形式で渡される場合もあります). :param dst: 出力画像. :param patch_size: 入力画像上を移動するパッチのサイズ. :param hist: ヒストグラム. :param method: 比較手法.この値は :ref:`CompareHist` に渡されます(この関数の説明を参照してください). :param factor: ヒストグラムの正規化係数.出力画像の正規化スケールに影響します.分からない場合には1を与えてください. 関数 ``cvCalcBackProjectPatch`` は,与えられたヒストグラムと,入力画像の一部分のヒストグラムとを比較することで,バックプロジェクションを計算します.配列 ``image`` は,ある画像のROIを様々な方法で評価した結果から構成されます.その評価結果には,色相, ``x`` 方向微分, ``y`` 方向微分,ラプラシアンフィルタ,Gaborフィルタなどが考えられます(1つでも構いません).各手法の評価出力は,個別に集められてそれぞれ別の画像となります.画像配列 ``image`` は,これらの評価画像の集合です.また,多次元ヒストグラム ``hist`` は,画像配列 ``image`` からサンプリングした結果です.最終的なヒストグラムは,正規化されます.また,ヒストグラム ``hist`` は,配列 ``image`` の要素数と同じだけの次元を持ちます. 新しい画像はまず評価され,そのROI全体が画像配列 ``image`` に変換されます.その部分的なヒストグラムは,以下の図にあるように,中心にアンカーを持つ「パッチ」と重なった部分にある画像 ``image`` から計算されます. ``hist`` と比較できるように,このヒストグラムは,パラメータ ``norm_factor`` を利用して正規化されます.求められたヒストグラムは,比較手法に ``method`` を指定した関数 ``cvCompareHist`` を利用して,モデルヒストグラム ``hist`` と比較されます.その出力結果は,確率画像 ``dst`` の,パッチのアンカーに対応する場所に格納されます.毎回パッチをずらして,最終的にROI全体に対して処理が終わるまで,これを繰り返します.ヒストグラムの反復更新は,パッチの端の重ならなくなった部分のピクセル値を引き,さらに新しく重なる部分のピクセル値を加えることで,大幅に処理を削減できます.しかし,まだこれは実装されていません. パッチによる投影計算 .. image:: ../../pics/backprojectpatch.png .. index:: CalcHist .. _CalcHist: CalcHist -------- `id=0.404387584459 Comments from the Wiki `__ .. cfunction:: void cvCalcHist( IplImage** image, CvHistogram* hist, int accumulate=0, const CvArr* mask=NULL ) 画像のヒストグラムを求めます. :param image: 入力画像(CvMat** の形式で渡される場合もあります). :param hist: ヒストグラムへのポインタ. :param accumulate: 累積フラグ.これが指定されている場合,関数の最初でヒストグラムがクリアされません.これによって,複数の画像から1つのヒストグラムを計算したり,毎回ヒストグラムを更新したりすることができます. :param mask: 処理マスク.入力画像のどのピクセルをカウントするかを決めます. この関数は,1つあるいは複数のシングルチャンネル画像のヒストグラムを求めます.ヒストグラムのビンの値を増加させる入力タプルの要素は,対応する(複数の)入力画像の同じ位置から取り出されます. .. code-block:: c #include #include 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); } } .. .. index:: CalcProbDensity .. _CalcProbDensity: CalcProbDensity --------------- `id=0.282419193324 Comments from the Wiki `__ .. cfunction:: void cvCalcProbDensity( const CvHistogram* hist1, const CvHistogram* hist2, CvHistogram* dst_hist, double scale=255 ) あるヒストグラムを別のヒストグラムで割ります. :param hist1: 1 番目のヒストグラム(除数). :param hist2: 2 番目のヒストグラム. :param dst_hist: 出力ヒストグラム. :param scale: 出力ヒストグラムに対するスケール係数. この関数は,2つのヒストグラムから物体の確率密度を求めます: .. math:: \texttt{dist\_hist} (I)= \forkthree{0}{if $\texttt{hist1}(I)=0$}{\texttt{scale}}{if $\texttt{hist1}(I) \ne 0$ and $\texttt{hist2}(I) > \texttt{hist1}(I)$}{\frac{\texttt{hist2}(I) \cdot \texttt{scale}}{\texttt{hist1}(I)}}{if $\texttt{hist1}(I) \ne 0$ and $\texttt{hist2}(I) \le \texttt{hist1}(I)$} 出力ヒストグラムのビンの値は, ``scale`` 未満になります. .. index:: ClearHist .. _ClearHist: ClearHist --------- `id=0.218676842703 Comments from the Wiki `__ .. cfunction:: void cvClearHist( CvHistogram* hist ) ヒストグラムをクリアします. :param hist: ヒストグラム. この関数は,密な配列データをもつヒストグラムの場合はヒストグラムのすべてのビンの値を 0にし,疎な配列データを持つヒストグラムの場合はヒストグラムのすべてのビンを削除します. .. index:: CompareHist .. _CompareHist: CompareHist ----------- `id=0.536142610032 Comments from the Wiki `__ .. cfunction:: double cvCompareHist( const CvHistogram* hist1, const CvHistogram* hist2, int method ) 2つの密なヒストグラムを比較します. :param hist1: 1 番目の密なヒストグラム. :param hist2: 2 番目の密なヒストグラム. :param method: 比較手法.以下のうちの1つ: * **CV_COMP_CORREL** 相関 * **CV_COMP_CHISQR** カイ2乗 * **CV_COMP_INTERSECT** 交差 * **CV_COMP_BHATTACHARYYA** Bhattacharyya距離 この関数は,指定された手法を用いて2つの密なヒストグラムを比較します( :math:`H_1` は1番目のヒストグラムを, :math:`H_2` は2番目のヒストグラムを表します): * 相関 (method=CV\_COMP\_CORREL) .. math:: d(H_1,H_2) = \frac{\sum_I (H'_1(I) \cdot H'_2(I))}{\sqrt{\sum_I(H'_1(I)^2) \cdot \sum_I(H'_2(I)^2)}} ここで, .. math:: H'_k(I) = \frac{H_k(I) - 1}{N \cdot \sum_J H_k(J)} です.N はヒストグラムのビン数を表します. * カイ2乗 (method=CV\_COMP\_CHISQR) .. math:: d(H_1,H_2) = \sum _I \frac{(H_1(I)-H_2(I))^2}{H_1(I)+H_2(I)} * 交差 (method=CV\_COMP\_INTERSECT) .. math:: d(H_1,H_2) = \sum _I \min (H_1(I), H_2(I)) * Bhattacharyya距離 (method=CV\_COMP\_BHATTACHARYYA) .. math:: d(H_1,H_2) = \sqrt{1 - \sum_I \frac{\sqrt{H_1(I) \cdot H_2(I)}}{ \sqrt{ \sum_I H_1(I) \cdot \sum_I H_2(I) }}} この関数は, :math:`d(H_1, H_2)` を返します. 注意:手法 ``CV_COMP_BHATTACHARYYA`` は,正規化されたヒストグラムでのみ動作します. 疎なヒストグラム,あるいはより一般的な構造である重み付き点群などを比較するためには,関数 :ref:`CalcEMD2` の利用を検討してください. .. index:: CopyHist .. _CopyHist: CopyHist -------- `id=0.0776477181786 Comments from the Wiki `__ .. cfunction:: void cvCopyHist( const CvHistogram* src, CvHistogram** dst ) ヒストグラムをコピーします. :param src: コピー元ヒストグラムへのポインタ. :param dst: コピー先ヒストグラムへのダブルポインタ. この関数は,ヒストグラムのコピーを作成します.2番目のヒストグラムポインタ ``*dst`` がNULLならば, ``src`` と同じサイズのヒストグラムが新たに作成されます.NULLでない場合は,2つのヒストグラムは同じ型,同じサイズでなければいけません.この関数は,コピー元のヒストグラムのビンの値をコピー先のヒストグラムにコピーし,ビンの範囲も ``src`` と同じになるようにセットします. .. index:: CreateHist .. _CreateHist: CreateHist ---------- `id=0.000551799490096 Comments from the Wiki `__ .. cfunction:: CvHistogram* cvCreateHist( int dims, int* sizes, int type, float** ranges=NULL, int uniform=1 ) ヒストグラムを作成します. :param dims: ヒストグラムの次元数. :param sizes: ヒストグラムの各次元のサイズを示す配列. :param type: ヒストグラム表現フォーマット: ``CV_HIST_ARRAY`` は,ヒストグラムのデータが密な多次元配列 CvMatND で表現される事を意味します.また ``CV_HIST_SPARSE`` は,ヒストグラムのデータが疎な多次元配列 CvSparseMat で表される事を意味します. :param ranges: ヒストグラムのビンの範囲を示す配列.これの意味は,パラメータ ``uniform`` の値に依存します.これらの範囲は,ヒストグラムが計算される際や,どのヒストグラムのビンが入力画像中のどの値(あるいは,値のタプル)に対応するかを決定するバックプロジェクションの際に利用されます. :param uniform: 一様性を示すフラグ.これが0ではない場合,ヒストグラムは等間隔のビンをもち, ``ranges[i]`` :math:`0<=i`__ .. cfunction:: float cvGetHistValue_1D(hist, idx0) .. cfunction:: float cvGetHistValue_2D(hist, idx0, idx1) .. cfunction:: float cvGetHistValue_3D(hist, idx0, idx1, idx2) .. cfunction:: float cvGetHistValue_nD(hist, idx) ヒストグラムのビンへのポインタを返します. :param hist: ヒストグラム. :param idx0, idx1, idx2, idx3: ビンのインデックス. :param idx: インデックスの配列. .. code-block:: c #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にセットします. .. index:: GetMinMaxHistValue .. _GetMinMaxHistValue: GetMinMaxHistValue ------------------ `id=0.0755067596163 Comments from the Wiki `__ .. cfunction:: void cvGetMinMaxHistValue( const CvHistogram* hist, float* min_value, float* max_value, int* min_idx=NULL, int* max_idx=NULL ) 最小値を持つビン,および最大値を持つビンを求めます. :param hist: ヒストグラムへのポインタ. :param min_value: ヒストグラムの最小値へのポインタ. :param max_value: ヒストグラムの最大値へのポインタ. :param min_idx: 最小値に対する座標値の配列. :param min_idx: 最大値に対する座標値の配列. この関数は,最小値を持つビン,および最大値を持つビンとそれぞれの位置を求めます.出力に利用されるすべての引数は,オプションです.最小値や最大値が同値で複数存在する場合,(辞書順に並べた場合の)最小のインデックスを持つものが返されます. .. index:: MakeHistHeaderForArray .. _MakeHistHeaderForArray: MakeHistHeaderForArray ---------------------- `id=0.72620145396 Comments from the Wiki `__ .. cfunction:: CvHistogram* cvMakeHistHeaderForArray( int dims, int* sizes, CvHistogram* hist, float* data, float** ranges=NULL, int uniform=1 ) 配列からヒストグラムを作成します. :param dims: ヒストグラムの次元数. :param sizes: ヒストグラムの各次元のサイズを表す配列. :param hist: この関数によって初期化される,ヒストグラムのヘッダ. :param data: ヒストグラムのビンを保存するための配列. :param ranges: ヒストグラムのビンの範囲, :ref:`CreateHist` を参照してください. :param uniform: 一様性フラグ, :ref:`CreateHist` を参照してください. この関数は,ヒストグラムを初期化します.そのヘッダとビンはユーザによって確保されるものです.後で :ref:`ReleaseHist` を呼ぶ必要はありません.また,この方法で初期化できるのは,密なヒストグラムだけです.この関数は, ``hist`` を返します. .. index:: NormalizeHist .. _NormalizeHist: NormalizeHist ------------- `id=0.223913607686 Comments from the Wiki `__ .. cfunction:: void cvNormalizeHist( CvHistogram* hist, double factor ) ヒストグラムを正規化します. :param hist: ヒストグラムへのポインタ. :param factor: 正規化ファクタ. この関数は,ビンの値の合計が ``factor`` と等しくなるようにスケーリングを行うことで,ヒストグラムのビンの正規化を行います. .. index:: QueryHistValue*D .. _QueryHistValue*D: QueryHistValue*D ---------------- `id=0.253112491697 Comments from the Wiki `__ .. cfunction:: float QueryHistValue_1D(CvHistogram hist, int idx0) ヒストグラムのビンの値を取得します. :param hist: ヒストグラム. :param idx0, idx1, idx2, idx3: ビンのインデックス. :param idx: インデックスの配列. .. code-block:: c #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が返されます. .. index:: ReleaseHist .. _ReleaseHist: ReleaseHist ----------- `id=0.769048499837 Comments from the Wiki `__ .. cfunction:: void cvReleaseHist( CvHistogram** hist ) ヒストグラムを解放します. :param hist: 解放されるヒストグラムへのダブルポインタ. この関数は,ヒストグラム(ヘッダとデータ)を解放します.この関数により,ヒストグラムへのポインタもクリアされます.ポインタ ``*hist`` が既に ``NULL`` の場合は,この関数は何もしません. .. index:: SetHistBinRanges .. _SetHistBinRanges: SetHistBinRanges ---------------- `id=0.782081034203 Comments from the Wiki `__ .. cfunction:: void cvSetHistBinRanges( CvHistogram* hist, float** ranges, int uniform=1 ) ヒストグラムのビンの上下限値をセットします. :param hist: ヒストグラムへのポインタ. :param ranges: ビン範囲の配列, :ref:`CreateHist` を参照してください. :param uniform: 一様性フラグ :ref:`CreateHist` を参照してください. この関数は,ヒストグラムのビンの範囲をセットするための,単独で動作する関数です.パラメータ ``ranges`` と ``uniform`` のより詳しい説明は,同じように範囲を初期化できる関数 :ref:`CreateHist` を参照してください.ヒストグラムのビンの範囲は,ヒストグラムやヒストグラムのバックプロジェクションが計算されるよりも前にセットされていなければいけません. .. index:: ThreshHist .. _ThreshHist: ThreshHist ---------- `id=0.1948414278 Comments from the Wiki `__ .. cfunction:: void cvThreshHist( CvHistogram* hist, double threshold ) ヒストグラムの閾値処理を行います. :param hist: ヒストグラムへのポインタ. :param threshold: 閾値レベル. この関数は,指定した閾値以下のビンをクリアします.