2012-03-21 10 views
0

OpenCVのSIFT記述子の実装を使用すると、少し混乱することがあります。SIFT記述子を使用するOpenCV(C++)は、検出された機能の数を増やしますか?

私はさまざまな検出器の方法と記述子の間で簡単に変更できるように、cv::FeatureDetectorcv::DescriptorExtractorのインターフェイスの組み合わせを使用しています。

(単一画像のバリアント)cv::DescriptorExtractor::compute(...)を呼び出す場合、ドキュメントは彼らの記述子を計算することは不可能であるならば、それは減少にアルゴリズムに与えられたキーポイントの数のために可能であることを述べている、と私はどのように理解してそしてなぜそれが行われたのか。

しかし、私には、実際にディスクリプタ計算後のキーポイントの数がになると、が増えます。それは明らかにそうであり、私は起こることからそれを止めようとはしていない、私はちょうどなぜ(ただの直感的な記述がクールであろうと、それについて何かに感謝している)についての説明を望んでいる。

コードを持たない実際のOpenCV(いくつかのローカル非OpenCVフラグを設定しています)の周りにラッパーのレイヤーがあります。そのため、ここにはOpenCVコードがあります:私はちょうど前の最初の10個のキーポイントをプリントアウトしてきたとの記述子の計算の後、ので、ここでは一例として、いくつかの具体的な数値である

cv::Ptr<cv::FeatureDetector> dect = cv::FeatureDetector::create("MSER"); 
cv::Mat input = cv::imread("someImg.ppm", 0); 
std::vector<cv::KeyPoint> keypoints; 
dect->detect(input, keypoints); 

cv::Ptr<cv::DescriptorExtractor>deEx=cv::DescriptorCalculator::create("SIFT"); 

std::cout << "before computing, feats size " << keypoints.size() << std::endl; 
// code to print out 10 features 

cv::Mat desc; 
deEx->compute(input, keypoints, desc); 

std::cout << "after computing, feats size " << keypoints.size() << std::endl; 
// code to print out 10 features 

before computing, feats size 379 
feat[0]: 10.7584 39.9262 176.526 0 12.5396 
feat[1]: 48.2209 207.904 275.091 0 11.1319 
feat[2]: 160.894 313.781 170.278 0 9.63786 
feat[3]: 166.061 239.115 158.33 0 19.5027 
feat[4]: 150.043 233.088 171.887 0 11.9569 
feat[5]: 262.323 322.173 188.103 0 8.65429 
feat[6]: 189.501 183.462 177.396 0 12.3069 
feat[7]: 218.135 253.027 171.763 0 123.069 
feat[8]: 234.508 353.236 173.281 0 11.8375 
feat[9]: 234.404 394.079 176.23 0 8.99652 
after computing, feats size 463 
feat[0]: 10.7584 39.9262 13.1313 0 12.5396 
feat[1]: 48.2209 207.904 69.0472 0 11.1319 
feat[2]: 48.2209 207.904 107.438 0 11.1319 
feat[3]: 160.894 313.781 9.57937 0 9.63786 
feat[4]: 166.061 239.115 166.144 0 19.5027 
feat[5]: 150.043 233.088 78.8696 0 11.9569 
feat[6]: 262.323 322.173 167.259 0 8.65429 
feat[7]: 189.501 183.462 -1.49394 0 12.3069 
feat[8]: 218.135 253.027 -117.067 3 123.069 
feat[9]: 218.135 253.027 7.44055 3 123.069 

が、私はこの例から見ることができ、その元の​​とfeat[7]は、2つの新しいキーポイントごとにスパンしているが、compute方法が行うために、私は、任意の論理的な説明が表示されない

私はここに与えられたキーポイントの検出のためのMSERを使用してからでてきた印刷物、及び:(そのその後、SIFT記述子を計算しようとしているが、サイズが同じ増加STARSURFで起こり、そしてSIFT(すなわちDoG)キーポイントが検出されました。私はSIFT記述子を他のものに変更しようとはしませんでしたが、誰かがその質問に関連していると思えば、私はそれを試して、私の質問で編集します。

+0

使用するコードの一部を追加できますか?パラメータを知ることは有用です。 – Alex

+0

ええと...私はOpenCVコードのラッパーの周りに実際にラッパーを作っていますが、その下にあるすべての作業をしている実際の5行のコードを掘り下げて編集しようとしています。 – penelope

答えて

2

Rob HessのSIFT実装を使用してOpenCVを使用しているように見えますが、これは複数の支配的な方向を持つキーポイントを複製することがあります。

OpenCVの報告したバグを見てみると、この問題はhereと報告されました。

これはバグではなく、新しいバージョンで修正されたものではなく、単に文書化されたものです。私はOpenCVのバージョンに義務付けられているので、old oneで説明されている動作が意味をなさないので、追加動作としてnewer documentationを見ても私には当てはまりませんでした(v2.1)。明らかに、単一の支配的な方向が存在しない場合

SIFTは異なる方位と同じ場所に複数の関心点を返します。

5

まず、documentationcv::DescriptorExtractor::computeで見ることができるように、non constではstd::vector<cv::Keypoints>を引数にとります。これは、このベクターをcv::DescriptorExtractor::computeによって修飾することができることを意味する。 実際にはKeyPointsFilter::runByImageBorderKeyPointsFilter::runByKeypointSize(2つのnon-const関数)がベクトルに適用され、記述子を計算できないキーポイントが削除されます。キーポイントの再抽出は行われません。 さらに診断するために使用している数行のコードを投稿する必要があります。

-

問題が発生した場所まあ、私はついに見つけ:cv::SiftDescriptorExtractor::compute方法は、(再)機能の向きを計算し、また、いくつかの支配的な方向でポイントを複製SIFT::operator()を呼び出します。 解決策はdescriptorParams.recalculateAnglesをfalseに変更することです。

+0

私は知っています':: compute'関数が' std :: vector 'を変更することが許されている理由と' non const'が意味するものです。彼らがドキュメンテーションに与える理由は(そして私は引用しています) "キーポイント。記述子が計算できないキーポイントは削除されます。"そして、削除は大丈夫です。しかし、私のキーポイントがプロセスを終えると、*より*少ない*であり、それは私が理解できないものです。私は、印刷物が何であるかをより良く理解するために、実際のコードを掲載しました。 – penelope

+0

私はあなたの問題を完全に理解するためにそれについて明確にしたいと思っていました。コードなしでは、診断することは困難です。私はあなたが編集したコードを試しました。私は他のタイプのDesciptorExtractorに変更しました。問題はSift記述子でのみ発生するようです。 – Eric

+0

はい、古い文書と新しい文書へのリンクと、問題が報告されたページを回答しました。最初にコードを投稿しなかったのはなぜですか*なぜ*これが起こっているのか(SIFT記述子を抽出するとキーポイントの数が増えたことはどのように意味があるのでしょうか) – penelope

0

これはバグではなく、設計によるものです。通常、(実際の画像パッチに応じて)3つまでの向きが推定される。