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.
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.
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::DescriptorExtractor
s 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With