OpenCVにおける特徴検出器は,同一の問題を解く異なるアルゴリズム間を容易にスイッチできる共通のインタフェースによってラップされています. キーポイント検出器を実装するオブジェクトはすべて, FeatureDetector() から派生します.
特徴検出器のためのデータ構造.
class KeyPoint
{
public:
// デフォルトコンストラクタ
KeyPoint() : pt(0,0), size(0), angle(-1), response(0), octave(0),
class_id(-1) {}
// フルコンストラクタ
KeyPoint(Point2f _pt, float _size, float _angle=-1,
float _response=0, int _octave=0, int _class_id=-1)
: pt(_pt), size(_size), angle(_angle), response(_response),
octave(_octave), class_id(_class_id) {}
// フルコンストラクタの別の形式
KeyPoint(float x, float y, float _size, float _angle=-1,
float _response=0, int _octave=0, int _class_id=-1)
: pt(x, y), size(_size), angle(_angle), response(_response),
octave(_octave), class_id(_class_id) {}
// キーポイントの vector を 2次元点の vector に変換します
static void convert(const std::vector<KeyPoint>& keypoints,
std::vector<Point2f>& points2f,
const std::vector<int>& keypointIndexes=std::vector<int>());
// 2次元点の vector を キーポイントの vector に変換します.ここで,
// 各キーポイントは同じサイズ,同じ方向になります.
static void convert(const std::vector<Point2f>& points2f,
std::vector<KeyPoint>& keypoints,
float size=1, float response=1, int octave=0,
int class_id=-1);
// キーポイントの組のオーバラップを計算します.
// オーバラップはキーポイント領域が重なり合う面積と
// キーポイント領域の結合面積との比率です(現在は,キーポイント領域は円形です)
static float overlap(const KeyPoint& kp1, const KeyPoint& kp2);
Point2f pt; // キーポイントの座標
float size; // キーポイント周辺の重要領域の直径
float angle; // 計算されたキーポイントの方向(計算できない場合は -1 )
float response; // 最も強いキーポイントが選択されたときの応答.
// ソーティングやサブサンプリングに利用できます
int octave; // キーポイントが抽出されるオクターブ(ピラミッドの階層)
int class_id; // オブジェクトクラス(キーポイントを,それが属するオブジェクトによって
// クラスタリングする必要がある場合)
};
// キーポイントの vector をファイルストレージに書き込みます
void write(FileStorage& fs, const string& name, const vector<KeyPoint>& keypoints);
// キーポイントの vector を指定したファイルストレージノードから読み込みます
void read(const FileNode& node, CV_OUT vector<KeyPoint>& keypoints);
2次元画像特徴検出器のための抽象基底クラス.
class CV_EXPORTS FeatureDetector
{
public:
virtual ~FeatureDetector();
void detect( const Mat& image, vector<KeyPoint>& keypoints,
const Mat& mask=Mat() ) const;
void detect( const vector<Mat>& images,
vector<vector<KeyPoint> >& keypoints,
const vector<Mat>& masks=vector<Mat>() ) const;
virtual void read(const FileNode&);
virtual void write(FileStorage&) const;
static Ptr<FeatureDetector> create( const string& detectorType );
protected:
...
};
画像(第1のバージョン),または画像集合(第2のバージョン)からキーポイントを検出します.
パラメタ: |
|
---|
特徴検出器オブジェクトをファイルストレージに書き込みます.
パラメタ: |
|
---|
FAST() メソッドを使った特徴検出器のラッパークラス.
class FastFeatureDetector : public FeatureDetector
{
public:
FastFeatureDetector( int threshold=1, bool nonmaxSuppression=true );
virtual void read( const FileNode& fn );
virtual void write( FileStorage& fs ) const;
protected:
...
};
goodFeaturesToTrack() 関数を使った特徴検出器のラッパークラス.
class GoodFeaturesToTrackDetector : public FeatureDetector
{
public:
class Params
{
public:
Params( int maxCorners=1000, double qualityLevel=0.01,
double minDistance=1., int blockSize=3,
bool useHarrisDetector=false, double k=0.04 );
void read( const FileNode& fn );
void write( FileStorage& fs ) const;
int maxCorners;
double qualityLevel;
double minDistance;
int blockSize;
bool useHarrisDetector;
double k;
};
GoodFeaturesToTrackDetector( const GoodFeaturesToTrackDetector::Params& params=
GoodFeaturesToTrackDetector::Params() );
GoodFeaturesToTrackDetector( int maxCorners, double qualityLevel,
double minDistance, int blockSize=3,
bool useHarrisDetector=false, double k=0.04 );
virtual void read( const FileNode& fn );
virtual void write( FileStorage& fs ) const;
protected:
...
};
MSER() クラスを使った特徴検出器のラッパークラス.
class MserFeatureDetector : public FeatureDetector
{
public:
MserFeatureDetector( CvMSERParams params=cvMSERParams() );
MserFeatureDetector( int delta, int minArea, int maxArea,
double maxVariation, double minDiversity,
int maxEvolution, double areaThreshold,
double minMargin, int edgeBlurSize );
virtual void read( const FileNode& fn );
virtual void write( FileStorage& fs ) const;
protected:
...
};
StarDetector() クラスを使った特徴検出器のラッパークラス.
class StarFeatureDetector : public FeatureDetector
{
public:
StarFeatureDetector( int maxSize=16, int responseThreshold=30,
int lineThresholdProjected = 10,
int lineThresholdBinarized=8, int suppressNonmaxSize=5 );
virtual void read( const FileNode& fn );
virtual void write( FileStorage& fs ) const;
protected:
...
};
SIFT() クラスを使った特徴検出器のラッパークラス.
class SiftFeatureDetector : public FeatureDetector
{
public:
SiftFeatureDetector(
const SIFT::DetectorParams& detectorParams=SIFT::DetectorParams(),
const SIFT::CommonParams& commonParams=SIFT::CommonParams() );
SiftFeatureDetector( double threshold, double edgeThreshold,
int nOctaves=SIFT::CommonParams::DEFAULT_NOCTAVES,
int nOctaveLayers=SIFT::CommonParams::DEFAULT_NOCTAVE_LAYERS,
int firstOctave=SIFT::CommonParams::DEFAULT_FIRST_OCTAVE,
int angleMode=SIFT::CommonParams::FIRST_ANGLE );
virtual void read( const FileNode& fn );
virtual void write( FileStorage& fs ) const;
protected:
...
};
SURF() クラスを使った特徴検出器のラッパークラス.
class SurfFeatureDetector : public FeatureDetector
{
public:
SurfFeatureDetector( double hessianThreshold = 400., int octaves = 3,
int octaveLayers = 4 );
virtual void read( const FileNode& fn );
virtual void write( FileStorage& fs ) const;
protected:
...
};
グリッド状に分割された入力画像の各セルでポイントを検出するように,検出器を適応させます.
class GridAdaptedFeatureDetector : public FeatureDetector
{
public:
/*
* detector 適応される検出器.
* maxTotalKeypoints 画像から検出されるキーポイントの最大数.
* 強いキーポイント飲みが保存されます.
* gridRows グリッドの行数.
* gridCols グリッドの列数.
*/
GridAdaptedFeatureDetector( const Ptr<FeatureDetector>& detector,
int maxTotalKeypoints, int gridRows=4,
int gridCols=4 );
virtual void read( const FileNode& fn );
virtual void write( FileStorage& fs ) const;
protected:
...
};
ガウシアンピラミッドの複数レベルから検出するように,検出器を適応させます. 元々スケーリングできない検出器で利用すると便利です.
class PyramidAdaptedFeatureDetector : public FeatureDetector
{
public:
PyramidAdaptedFeatureDetector( const Ptr<FeatureDetector>& detector,
int levels=2 );
virtual void read( const FileNode& fn );
virtual void write( FileStorage& fs ) const;
protected:
...
};
指定した個数の特徴が見つかるまで繰り返し検出するように,適応調整された検出器.
この検出器が持続的なものであれば,最後の検出で利用されたパラメータを「覚えている」 ことになります.この理由により,ビデオストリームやパノラマ画像列などの空間的に連続する 画像集合から,常に一貫した個数のキーポイントを検出するために,この検出器が利用されることがあります.
DynamicAdaptedFeatureDetector は,FAST や SURF などの別の検出器を利用することで実際の処理を行いますが, ここで AdjusterAdapter の機能が活用されます. 特徴検出後,検出された特徴数が条件を満たさなかった場合,より多い(あるいは少ない)数の特徴が次回に検出されるように, AdjusterAdapter が検出パラメータを調整します これは,目的とする個数の特徴が見つかるか,パラメータの値が限界に達するまで繰り返されます.
AdjusterAdapter インタフェースを介して, 任意の検出器に対するアダプタを簡単に実装することができます.
これはスレッドセーフではないことに注意してください. パラメータを調整することで,検出ルーチンにおける定数が変更されるからです.
ここで,DynamicAdaptedFeatureDetector の作成方法を例に示します.
// 利用方法のサンプル:
// 100 - 110 個の FAST キーポイントを
// 見つけようとする検出器を作成し,
// その個数のキーポイントが見つかるまで,
// FAST特徴検出を最大で10回繰り返します.
Ptr<FeatureDetector> detector(new DynamicAdaptedFeatureDetector (100, 110, 10,
new FastAdjuster(20,true)));
class DynamicAdaptedFeatureDetector: public FeatureDetector
{
public:
DynamicAdaptedFeatureDetector( const Ptr<AdjusterAdapter>& adjaster,
int min_features=400, int max_features=500, int max_iters=5 );
...
};
DynamicAdaptedFeatureDetector コンストラクタ.
パラメタ: |
|
---|
特徴検出器パラメータの調整インタフェース.これは DynamicAdaptedFeatureDetector() によって利用されるもので, 検出後にパラメータを調整可能な FeatureDetector() のラッパーです.
具体的な実装に関しては FastAdjuster() , StarAdjuster() , SurfAdjuster() を参照してください.
class AdjusterAdapter: public FeatureDetector
{
public:
virtual ~AdjusterAdapter() {}
virtual void tooFew(int min, int n_detected) = 0;
virtual void tooMany(int max, int n_detected) = 0;
virtual bool good() const = 0;
};
検出された特徴が少なすぎる場合,それに応じて検出器のパラメータが調整され, 次回検出時により多くの特徴が検出できるようにします.
param min: 目的とする特徴数の最小値. param n_detected: 最後の実行時に,実際に検出された特徴数.
この実装例は,以下のようになります.
void FastAdjuster::tooFew(int min, int n_detected)
{
thresh_--;
}
検出された特徴が多すぎる場合,それに応じて検出器のパラメータが調整され,
次回検出時により少ない特徴しか検出されないようにします.
param max: 目的とする特徴数の最大値. param n_detected: 最後の実行時に,実際に検出された特徴数.
この実装例は,以下のようになります.
void FastAdjuster::tooMany(int min, int n_detected)
{
thresh_++;
}
パラメータが限界に達したか?あるいは,まだ有効か?パラメータをこれ以上調整できない場合には,false を返します.
この実装例は,以下のようになります.
bool FastAdjuster::good() const
{
return (thresh_ > 1) && (thresh_ < 200);
}
FastFeatureDetector() に対する AdjusterAdapter() .これは,通常,閾値を1づつ増加(または減少)させます.
class FastAdjuster FastAdjuster: public AdjusterAdapter
{
public:
FastAdjuster(int init_thresh = 20, bool nonmax = true);
...
};
StarFeatureDetector() に対する AdjusterAdapter() . これは,StarFeatureDetector の responseThreshold を調整します.
class StarAdjuster: public AdjusterAdapter
{
StarAdjuster(double initial_thresh = 30.0);
...
};