物体検出 ============ .. highlight:: cpp .. index:: FeatureEvaluator .. _FeatureEvaluator: FeatureEvaluator ---------------- .. ctype:: FeatureEvaluator カスケード分類器で特徴量を求めるための基底クラス. :: class CV_EXPORTS FeatureEvaluator { public: enum { HAAR = 0, LBP = 1 }; // サポートされる特徴タイプ virtual ~FeatureEvaluator(); // デストラクタ virtual bool read(const FileNode& node); virtual Ptr clone() const; virtual int getFeatureType() const; virtual bool setImage(const Mat& img, Size origWinSize); virtual bool setWindow(Point p); virtual double calcOrd(int featureIdx) const; virtual int calcCat(int featureIdx) const; static Ptr create(int type); }; .. .. index:: FeatureEvaluator::read cv::FeatureEvaluator::read -------------------------- .. cfunction:: bool FeatureEvaluator::read(const FileNode\& node) FileStorage ノードから,特徴量パラメータを読み込みます. :param node: ファイルノード.ここから特徴量パラメータが読み出されます .. index:: FeatureEvaluator::clone cv::FeatureEvaluator::clone --------------------------- .. cfunction:: Ptr FeatureEvaluator::clone() const 特徴量評価器の完全なコピーを返します. .. index:: FeatureEvaluator::getFeatureType cv::FeatureEvaluator::getFeatureType ------------------------------------ .. cfunction:: int FeatureEvaluator::getFeatureType() const 特徴量タイプ(現在は HAAR か LBP)を返します. .. index:: FeatureEvaluator::setImage cv::FeatureEvaluator::setImage ------------------------------ .. cfunction:: bool FeatureEvaluator::setImage(const Mat\& img, Size origWinSize) 特徴量を求める対象となる画像をセットします. :param img: ``CV_8UC1`` 型の行列.ここにセットされた画像の特徴を求めます :param origWinSize: 学習画像のサイズ .. index:: FeatureEvaluator::setWindow cv::FeatureEvaluator::setWindow ------------------------------- :func:`CascadeClassifier::runAt` .. cfunction:: bool FeatureEvaluator::setWindow(Point p) 現在の画像上に,特徴量を計算する探索窓をセットします( によって呼び出されます) :param p: 探索窓の左上角の座標.この探索窓の中の特徴量が計算されます.探索窓のサイズは,学習画像と同じです .. index:: FeatureEvaluator::calcOrd cv::FeatureEvaluator::calcOrd ----------------------------- .. cfunction:: double FeatureEvaluator::calcOrd(int featureIdx) const 順序付き(数値)特徴量の値を求めます. :param featureIdx: 値を求める特徴量のインデックス 求められた順序付き特徴量の値を返します. .. index:: FeatureEvaluator::calcCat cv::FeatureEvaluator::calcCat ----------------------------- .. cfunction:: int FeatureEvaluator::calcCat(int featureIdx) const カテゴリ特徴量の値を求めます. :param featureIdx: 値を求める特徴量のインデックス 求められたカテゴリ特徴量,つまり [0,... (カテゴリ数 - 1)] の範囲内の値を返します. .. index:: FeatureEvaluator::create cv::FeatureEvaluator::create ---------------------------- .. cfunction:: static Ptr FeatureEvaluator::create(int type) 特徴量評価器を作成します. :param type: カスケードによって評価される特徴量の種類(現在は,HAAR または LBP のどちらか) .. index:: CascadeClassifier .. _CascadeClassifier: CascadeClassifier ----------------- .. ctype:: CascadeClassifier 物体検出のためのカスケード分類器クラス. :: class CascadeClassifier { public: // 木ノードを表す構造体 struct CV_EXPORTS DTreeNode { int featureIdx; // 分岐となる特徴量インデックス float threshold; // 順序付き特徴量に対する分岐の閾値 int left; // 木ノード配列において,左側にある子ノードのインデックス int right; // 木ノード配列において,右側にある子ノードのインデックス }; // 決定木を表す構造体 struct CV_EXPORTS DTree { int nodeCount; // ノード数 }; // カスケードステージ(現在のところ BOOST のみ)を表す構造体 struct CV_EXPORTS Stage { int first; // 木配列における,最初の木のインデックス int ntrees; // 木の数 float threshold; // ステージの閾値 }; enum { BOOST = 0 }; // サポートされるステージの種類 // 検出のモード(HaarDetectObjects 関数のパラメータ flags を参照してください) enum { DO_CANNY_PRUNING = CV_HAAR_DO_CANNY_PRUNING, SCALE_IMAGE = CV_HAAR_SCALE_IMAGE, FIND_BIGGEST_OBJECT = CV_HAAR_FIND_BIGGEST_OBJECT, DO_ROUGH_SEARCH = CV_HAAR_DO_ROUGH_SEARCH }; CascadeClassifier(); // デフォルトコンストラクタ CascadeClassifier(const string& filename); ~CascadeClassifier(); // デストラクタ bool empty() const; bool load(const string& filename); bool read(const FileNode& node); void detectMultiScale( const Mat& image, vector& objects, double scaleFactor=1.1, int minNeighbors=3, int flags=0, Size minSize=Size()); bool setImage( Ptr&, const Mat& ); int runAt( Ptr&, Point ); bool is_stump_based; // 木が stump の場合は true int stageType; // ステージの種類(現在は,BOOST のみ) int featureType; // 特徴量の種類(現在は,HAAR または LBP のどちらか) int ncategories; // カテゴリ数(カテゴリ特徴量の場合のみ) Size origWinSize; // 学習画像のサイズ vector stages; // ステージの vector (現在は,BOOST のみ) vector classifiers; // 決定木の vector vector nodes; // 木ノードの vector vector leaves; // 葉の値の vector vector subsets; // カテゴリ特徴量によって分けられた部分集合 Ptr feval; // 特徴評価器へのポインタ Ptr oldCascade; // pointer to old cascade }; .. .. index:: CascadeClassifier::CascadeClassifier cv::CascadeClassifier::CascadeClassifier ---------------------------------------- .. cfunction:: CascadeClassifier::CascadeClassifier(const string\& filename) ファイルから分類器を読み込む. :param filename: ファイル名.ここから分類器を読み込みます .. index:: CascadeClassifier::empty cv::CascadeClassifier::empty ---------------------------- .. cfunction:: bool CascadeClassifier::empty() const 分類器が読み込まれたか否かをチェックします. .. index:: CascadeClassifier::load cv::CascadeClassifier::load --------------------------- .. cfunction:: bool CascadeClassifier::load(const string\& filename) ファイルから分類器を読み込みます.以前の内容は破棄されます. :param filename: ファイル名.ここから分類器を読み込みます.ファイルには(haartraining アプリケーションによって学習された)古い haar 分類器,または(traincascade アプリケーションによって学習された)新しいカスケード分類器が保存されている場合があります .. index:: CascadeClassifier::read cv::CascadeClassifier::read --------------------------- .. cfunction:: bool CascadeClassifier::read(const FileNode\& node) ファイルストレージノードから分類器を読み込みます.ファイルには,(traincascade アプリケーションによって学習された)新しいカスケード分類器しか保存されていません. .. index:: CascadeClassifier::detectMultiScale cv::CascadeClassifier::detectMultiScale --------------------------------------- .. cfunction:: void CascadeClassifier::detectMultiScale( const Mat\& image, vector\& objects, double scaleFactor=1.1, int minNeighbors=3, int flags=0, Size minSize=Size()) 入力画像中から異なるサイズの物体を検出します.検出された物体は,矩形のリストとして返されます. :param image: ``CV_8U`` 型の行列.ここに格納されている画像中から物体が検出されます :param objects: 矩形を要素とするベクトル.それぞれの矩形は,検出した物体を含みます :param scaleFactor: 各画像スケールにおける縮小量を表します :param minNeighbors: 物体候補となる矩形は,最低でもこの数だけの近傍矩形を含む必要があります :param flags: このパラメータは,新しいカスケードでは利用されません.古いカスケードに対しては,cvHaarDetectObjects 関数の場合と同じ意味を持ちます :param minSize: 物体が取り得る最小サイズ.これよりも小さい物体は無視されます .. index:: CascadeClassifier::setImage cv::CascadeClassifier::setImage ------------------------------- .. cfunction:: bool CascadeClassifier::setImage( Ptr\& feval, const Mat\& image ) 画像をセットします(各レベルの画像において detectMultiScale から呼び出されます). :param feval: 特徴量を計算するために用いられる特徴評価器へのポインタ :param image: ``CV_8UC1`` 型の行列.ここに格納されている画像中の特徴量が求められます .. index:: CascadeClassifier::runAt cv::CascadeClassifier::runAt ---------------------------- .. cfunction:: int CascadeClassifier::runAt( Ptr\& feval, Point pt ) 画像の指定位置で検出器を実行します(検出器の動作対象となる画像は,setImage によってセットされている必要があります). :param feval: 特徴量を計算するために用いられる特徴評価器へのポインタ :param pt: 探索窓の左上角の座標.この探索窓の中の特徴量が計算されます.探索窓のサイズは,学習画像と同じです 以下を返します: 1 - カスケード分類器が,指定位置で物体を検出した場合. -si - それ以外の場合.si は,与えられた探索窓位置が背景画像であると最初に予測したステージのインデックスです. .. index:: groupRectangles cv::groupRectangles ------------------- .. cfunction:: void groupRectangles(vector\& rectList, int groupThreshold, double eps=0.2) 物体候補の矩形をグループ化します.. :param rectList: 矩形の入出力ベクトル.出力の場合,グループ化された矩形を格納します :param groupThreshold: 矩形グループにおいて,最低限保持すべき矩形の数 - 1 :param eps: 1つのグループにマージするための,矩形端同士の相対的差異 この関数は,汎用関数 :func:`partition` のラッパです.これは,矩形が同一と見なせるかどうかの基準を利用して,すべての入力矩形をクラスタリングします.つまり,同じようなサイズで同じような位置にある(この類似性は ``eps`` で定義されます)矩形を結合します. ``eps=0`` の場合,クラスタリングは全く行われません. :math:`\texttt{eps}\rightarrow +\inf` ならば,すべての矩形が1つのクラスタに入れられます. また, ``groupThreshold`` 個以下の矩形しか含まないような小さいクラスタは,棄却されます.それぞれのクラスタにおいて平均矩形が計算され,出力の矩形リストに書き出されます. .. index:: matchTemplate cv::matchTemplate ----------------- .. cfunction:: void matchTemplate( const Mat\& image, const Mat\& templ, Mat\& result, int method ) テンプレートと,それに重なった画像領域とを比較します. :param image: テンプレートの探索対象となる画像.8ビットまたは32ビットの浮動小数点型 :param templ: 探索されるテンプレート.探索対象となる画像以下のサイズで,同じデータ型でなければいけません :param result: 比較結果のマップ.シングルチャンネル,32ビット,浮動小数点型. ``image`` が :math:`W \times H` で, ``templ`` が :math:`w \times h` とすると ``result`` は :math:`(W-w+1) \times (H-h+1)` となります :param method: 比較手法の指定(以下の説明を参照してください) この関数は ``templ`` を ``image`` 全体に対してスライドさせ,それと重なる :math:`w \times h` の領域とを指定された方法で比較し,その結果を ``result`` に保存します.以下に,この関数で指定可能な比較手法を表す式を示します( :math:`I` は画像を, :math:`T` はテンプレートを, :math:`R` は結果をそれぞれ表します.総和計算は,以下のようにテンプレートと(または)画像領域に対して行われます: :math:`x' = 0...w-1, y' = 0...h-1` * method=CV\_TM\_SQDIFF .. math:: R(x,y)= \sum _{x',y'} (T(x',y')-I(x+x',y+y'))^2 * method=CV\_TM\_SQDIFF\_NORMED .. math:: R(x,y)= \frac{\sum_{x',y'} (T(x',y')-I(x+x',y+y'))^2}{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}} * method=CV\_TM\_CCORR .. math:: R(x,y)= \sum _{x',y'} (T(x',y') \cdot I(x+x',y+y')) * method=CV\_TM\_CCORR\_NORMED .. math:: R(x,y)= \frac{\sum_{x',y'} (T(x',y') \cdot I'(x+x',y+y'))}{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}} * method=CV\_TM\_CCOEFF .. math:: R(x,y)= \sum _{x',y'} (T'(x',y') \cdot I(x+x',y+y')) where .. math:: \begin{array}{l} T'(x',y')=T(x',y') - 1/(w \cdot h) \cdot \sum _{x'',y''} T(x'',y'') \\ I'(x+x',y+y')=I(x+x',y+y') - 1/(w \cdot h) \cdot \sum _{x'',y''} I(x+x'',y+y'') \end{array} * method=CV\_TM\_CCOEFF\_NORMED .. math:: R(x,y)= \frac{ \sum_{x',y'} (T'(x',y') \cdot I'(x+x',y+y')) }{ \sqrt{\sum_{x',y'}T'(x',y')^2 \cdot \sum_{x',y'} I'(x+x',y+y')^2} } この関数による比較の後,関数 :func:`minMaxLoc` を用いて,大域的最小値( ``CV_TM_SQDIFF`` の場合)あるいは大域的最大値( ``CV_TM_CCORR`` や ``CV_TM_CCOEFF`` の場合)を検出することでベストマッチを得ることができます.カラー画像の場合,分母・分子それぞれの総和計算は全てのチャンネルについて行われます(各チャンネルで用いる平均値はそれぞれ異なります).つまり,この関数はカラーテンプレートやカラー画像をとることができます.結果はシングルチャンネル画像のままで,簡単に分析できます.