8

opencv記述子エクストラクタの「compute」メソッドを使用して取得した記述子行列の値を出力するのに問題があります。機能の記述子を1つずつファイルに出力したいのですが、記述子マトリックスのある要素に「at」でアクセスすると、その要素に対して異なる値を受け取ります。以下は、「at」を使用するときに記述子行列の出力値をテストするために使用した「for」ループです。

for(int i=0; i<nF; i++){

    if(lpx != keypoints[i].pt.x && lpy != keypoints[i].pt.y){
        usedFeatures++;
        cerr << descriptors.row(i) << endl << endl; // printing row of descriptor matrix
        fileS << keypoints[i].pt.y << " " << keypoints[i].pt.x << " ";
        fileS << keypoints[i].size << " " << keypoints[i].angle << endl;

        if(i == nF - 2){
            //printing subvector of descriptor matrix made of the element at row i and col 0
            cerr << "get row i, col 0 " << descriptors.row(i).col(0) << endl;

            //same as before just inverting the order of access
            cerr << "get col 0, row i: " << descriptors.col(0).row(i) << endl;


            //printing the value of the element with 'at'
            cerr << (int)descriptors.at<uchar>(i, 0);

            //creating a new int and giving it the value of element (i, 0) of descriptor matrix. Should be the same
            //value shown on the subvector before
            int test = descriptors.at<uchar>(i, 0);

            //printing value of element
            cerr << "i, 0: " << test << endl;
        }

2番目の「if」はテストです。「if」記述子の要素にアクセスするときに出力される値を確認しました。今、によって印刷されます

cerr << descriptors.row(i) << endl << endl;

nF-2の反復で、次の結果が得られます。

[20, 11, 0, 18, 51, 3, 0, 3, 133, 50, 0, 0, 0, 0, 0, 11, 133, 18, 0, 0, 0, 0, 0, 3,
119, 2, 0, 0, 0, 0, 0, 2, 19, 5, 0, 4, 55, 27, 1, 1, 133, 25, 0, 1, 4, 1, 0, 22, 133,
18, 0, 0, 0, 0, 0, 14, 131, 13, 1, 0, 0, 0, 0, 1, 12, 1, 0, 1, 56, 133, 25, 13, 133,
14, 0, 0, 3, 8, 20, 80, 133, 38, 0, 0, 0, 0, 0, 51, 106, 11, 1, 0, 0, 0, 0, 23, 0, 0,
0, 0, 19, 126, 70, 11, 23, 0, 0, 0, 0, 9, 83, 133, 53, 1, 0, 0, 0, 0, 2, 133, 26, 
3, 2, 0, 0, 0, 0, 28]

そして予想通り、最初の2つは2番目の'if'の中に印刷されます。

cerr << "get row i, col 0 " << descriptors.row(i).col(0) << endl;

cerr << "get col 0, row i: " << descriptors.col(0).row(i) << endl;

ください[20]

しかし、他の2つのプリント

cerr << (int)descriptors.at<uchar>(i, 0);

int test = descriptors.at<uchar>(i, 0);
cerr << "i, 0: " << test << endl;

20ではなく0を指定してください。前に示したnF-2行で、「at」を使用して要素にアクセスして出力したときの完全な結果は次のとおりです。

 0 0 160 65 0 0 48 65 0 0 0 0 0 0 144 65 0 0 76 66
 0 0 64 64 0 0 0 0 0 0 64 64 0 0 5 67 0 0 72 66
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 48 65 0 0 5 67 0 0 144 65 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 64 64 0 0 238 66
 0 0 0 64 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 64

これは私が期待していたものとは完全に異なります。私はすでに多くのことを試しました。intだけでなくfloat、double、unsigned intを使用してキャストし、それらの型の変数にも割り当てます。印刷する前にマトリックスを変換し、マトリックスをコピーしてから変換し、異なるタイプの記述子マトリックスを作成します...しかし、それらはどれも機能しませんでした。記述子マトリックスのタイプと関係があると思いますが、ucharタイプであるとほぼ確信しています(elemSizeで確認しました)

よろしくお願いします。私の英語と質問のサイズについて申し訳ありません。

4

2 に答える 2

7

答えが見つかりました。それは確かにタイプの問題でした。によって返される記述子行列のタイプは、私が思ったようにucharではなく、実際にはfloatです。で値を取得する

(float)descriptors.at<float>(i, 0);

私に正しい価値を与えてくれます。おかしなことに、以前にフロートで試してみたのですが、うまくいきませんでした。int、double、unsignedintに対してのみ試してみたに違いありません。

于 2012-05-03T16:17:02.247 に答える
1

これはあなたの問題が起こる理由に答えませんが、私の記述子値にアクセスしようとしたときに同様の問題があったことを覚えています。

cv::DescriptorExtractorOpenCVには複数のが実装されているため、どの記述子でも機能するコードを書き込もうとしていました。問題は、いつか自分の記述子インターフェイスで動作する独自のOpenCV独立ライブラリを作成できるようにしたいので、std::vector<vector<double> >構造内のすべての記述子が必要だったということです。

cv::Mat descOldこれがに変換する私のコードですstd::vector< std::vector <double> > desc

cv::DescriptorExtractor *descCalc;

// initialize descCalc

descCalc->compute(*image, feats, descOld);

// conversion to std::vector<std::vector <double> > :

const double *temp;
desc.clear();
desc.reserve(descOld.cols);
for (int i=0, szi = this->desc.rows; i < szi; ++i){
    temp = descOld.ptr<double>(i);
    desc.push_back(std::vector<double>(temp, temp+descOld.cols));
}

assert(desc.size() == descOld.rows);
assert(desc[0].size() == descOld.cols);

それがいくつかの助けになることを願っています。

于 2012-05-03T07:41:07.967 に答える