2012-05-02 9 views
8

opencvディスクリプタエクストラクタの 'compute'メソッドを使用して取得したディスクリプタマトリックスの値を表示する際に問題があります。あるフィーチャのディスクリプタを1つずつファイルに出力したいのですが、ディスクリプタマトリックスの一部の要素に 'at'でアクセスすると、その要素の値が異なります。私は値が印刷された参照が行わ「が」テスト「であれば」キーポイントディスクリプタマトリクスの値を印刷するopencv

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; 
     } 

秒以下は「で」使用する場合、私が記述行列の出力値をテストするために使用されるループ「の」でありますディスクリプタの要素にアクセスするとき - 今、nFので

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

によって印刷された2 iteraction、私は次の結果を持っている:

[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枚のプリント

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]

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

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

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

私がラインNF-2のために持っていた0の代わりに、20の完全な結果を与える私は「で」との要素にアクセスし、それらをして印刷するときに、前に示した:

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 

これは私が期待していたものとまったく異なっています。私はすでにたくさんのことを試みました:float、double、unsigned intをintの代わりにキャストし、それらの型の変数にも割り当てます。マトリックスをコピーして変換し、異なるタイプの記述子マトリックスを作成します...しかし、それらのどれもは働かなかった。私は、それが記述子行列の型と関係があると思われますが、私はほとんどそれがuchar型を持っていると確信しています(elemSizeでチェックしました)

私の英語とサイズ質問。

答えて

7

答えを見つけました。それは確かにタイプの問題でした。私が思ったように、返される記述子行列の型はucharではなく、実際は浮動小数点型です。値を

で取得する
(float)descriptors.at<float>(i, 0); 

私に正しい値が与えられます。面白いことに、私はフロートの前にそれを試したことを誓うことができ、それは動作しませんでした。私はint型、double型、unsigned int型のみで試してみたに違いない。

1

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

私はOpenCVに複数のcv::DescriptorExtractorが実装されているため、どの記述子でも動作するコードを書くことを試みていました。問題は、いつか自分のディスクリプタインターフェイスで動作する独自のOpenCV独立ライブラリを作成できるようにするために、std::vector<vector<double> >構造のすべてのディスクリプタが欲しいということです。ここで

std::vector< std::vector <double> > desccv::Mat descOldに変換私のコードです:

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); 

それはいくつかのお役に立てば幸いです。

+0

ありがとうございます!それは私が今いる問題を解決しませんが、この変換は私にとっては将来的には役に立つかもしれないので、あなたの答えに感謝します! –

+0

@Alberto Aあなたの問題の「理由」には答えられませんが、記述子に 'double 'としてアクセスすることができますか?私の場合、 'temp'は行の先頭へのポインタですが、' temp'を使って行の最初の要素を取得するには、 'double val = * temp'にするだけです。多分それを試してみませんか?私は、ディスクリプタにアクセスするための適切なタイプを見つけるのに苦労したことも知っています。 – penelope