1

OpenCV のSIFT 記述子の実装を使用しているときに、少し混乱する状況があります。

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

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

しかし、実際には、ディスクリプタ計算後のキー ポイントの数が増加します。それは明らかにそうであり、私はそれが起こるのを止めようとしているわけではありません.理由についての説明を望んでいます.

コードを持たない実際の OpenCV の周りにラッパーのレイヤーを何層も重ねています (いくつかのローカルの非 OpenCV フラグを設定するだけです)。

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

記述子の計算の直前と直後の最初の 10 個のキー ポイントを出力したので、例としていくつかの具体的な数値を示します。

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[1]feat[7]がそれぞれ 2 つの新しいキー ポイントにまたがっていることがわかりますが、それを行うcompute方法についての論理的な説明は見当たりません :(

ここに示したプリントアウトは、キーポイントの検出にMSERを使用してからSIFT記述子を計算しようとしたものですが、検出されたSTARSURF、およびSIFT (つまり DoG) キーポイントでも同じサイズの増加が発生します。SIFT記述子を別のものに変更しようとはしませんでしたが、質問に関連していると誰かが考えた場合は、それを試して質問で編集します。

4

3 に答える 3

5

まず第一に、ドキュメント でわかるように、 in 引数 which in をcv::DescriptorExtractor::compute取ります。これは、このベクトルを で変更できることを意味します。実際には、and (2 つの関数) がベクトルに適用され、記述子を計算できないキーポイントが削除されます。キーポイントの再抽出は行われません。さらに診断するために、使用している数行のコードを投稿する必要があります。 std::vector<cv::Keypoints>non constcv::DescriptorExtractor::computeKeyPointsFilter::runByImageBorderKeyPointsFilter::runByKeypointSizenon-const

--

さて、私は最終的に問題が発生する場所を見つけました:フィーチャの向きを (再) 計算し、いくつかの支配的な向きでポイントを複製するcv::SiftDescriptorExtractor::computeメソッド呼び出しです。解決策は、falseSIFT::operator()に変更することです。descriptorParams.recalculateAngles

于 2012-03-21T14:04:56.603 に答える
2

それは、Rob Hess の SIFT 実装を使用する OpenCV が原因のようです。

OpenCV で報告されたバグを調べてみると、問題はここで報告されました。

これはバグではありません。動作は新しいバージョンでは修正されていませんが、代わりに文書化されています。私は現在使用している OpenCV バージョン (v2.1) を使用する義務があるため、古いドキュメントで説明されている動作は私にとって意味があったため、追加の動作について新しいドキュメントを確認することは思いつきませでした

于 2012-03-21T16:32:10.710 に答える
0

これはバグではなく、設計によるものです。

SIFT は、単一の優勢な方向が明確に存在しない場合、異なる方向を持つ同じ場所にある複数の関心点を返します。通常、最大 3 つの方向 (実際の画像パッチによって異なります) が推定されます。

于 2013-03-02T15:44:57.420 に答える