Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Printing values of keypoint descriptor matrix opencv

I'm having some trouble printing the values of the descriptor matrix obtained through the use of the 'compute' method of any opencv descriptor extractor. I want to print the descriptor of a feature to a file one by one, but always when I access some element of the descriptor matrix with 'at', I receive a different value for that element. The following is a 'for' loop I used to test the output value of the descriptor matrix when using 'at':

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

The second 'if' is a test 'if' I made to see the values printed when accessing the elements of the descriptors. Now, printed by the

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

at the nF - 2 iteraction, I have the following result:

[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]

And as expected, the first two prints inside the second '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;

give me [20]

But the other two prints

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

and

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

give me 0 instead of 20. The complete result I had for line nF-2 I showed before, when accessing the elements with 'at' and printing them was:

 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

Which is completely different from what I was expecting. I've tried a lot of things already: casting with float, double, unsigned int instead of only int, and assigning to variables of those types as well; converting the matrix before printing it, copying the matrix then converting, creating the descriptors matrix with a different type...but none of them worked. I suspect it has something to do with the type of the descriptors matrix, although I'm almost sure it has the uchar type (I checked with elemSize)

Thanks in advance, and sorry for my english and the size of the question.

like image 545
Alberto A Avatar asked May 02 '12 16:05

Alberto A


2 Answers

Found the answer. It was indeed a type problem. The type of descriptor matrix returned by isn't uchar like I thought, it is actually float. Getting the value with

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

gives me the right value. Funny thing is I could swear I tried it for float before, and it didn't work. I must've tried it only for int, double and unsigned int.

like image 111
Alberto A Avatar answered Sep 21 '22 22:09

Alberto A


This does not answer why your problem happens, but I remember having similar issues when trying to access my descriptor values.

I was trying to write a piece of code that would work with any descriptors, as OpenCV has multiple cv::DescriptorExtractors implemented. The thing is, since I want to someday be able to make my own, OpenCV independent libraries that work with my descriptor interfaces, I wanted all the descriptors in std::vector<vector<double> > structures.

Here is my code that converts cv::Mat descOld to 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);

Hope it helps some.

like image 21
penelope Avatar answered Sep 19 '22 22:09

penelope