Ask Your Question
0

Weird numbers with cv::Mat

asked 2017-04-23 11:27:08 -0600

lovaj gravatar image

updated 2017-04-23 11:50:42 -0600

I have this struct:

struct Result{
    Result(const cv::Mat1f &descriptor, const Keypoint &keypoint) :
        descriptor(descriptor), keypoint(keypoint){
      std::cout<<"constructor="<<std::endl<<descriptor<<std::endl;
    }
    const cv::Mat1f descriptor;
    const Keypoint keypoint;
};

Where Keypoint I think is irrelevant for this question (but I'll post it if you ask about it).

I have this function:

void foo(...,vector<Result> &res){
...
std::vector<float> vec;
//fill vec
cv::Mat1f desc(1,128,vec.data());
std::cout<<"desc="<<std::endl<<desc<<std::endl;
res.push_back(Result(desc, Keypoint(...)));
}

Which is called like this:

std::vector<Result> res;
for(int i=0; i<N; i++){
   foo(..., res);
   std::cout<<"res="<<std::endl<<res.back().descriptor<<std::endl;
}

Sometimes, the three std::cout print the same value. But in some cases, the last print (the one inside after calling foo) gives different results:

desc=
[2, 10, 54, 3, 2, 2, 5, 6, 7, 27, 111, 5, 3, 17, 11, 12, 8, 31, 113, 6, 3, 6, 10, 27, 2, 8, 63, 9, 13, 17, 2, 1, 54, 10, 16, 5, 13, 22, 18, 85, 37, 18, 17, 3, 99, 113, 29, 41, 113, 7, 21, 5, 28, 40, 34, 113, 12, 6, 14, 10, 93, 113, 8, 23, 54, 21, 50, 31, 20, 20, 7, 78, 18, 69, 82, 29, 86, 108, 9, 20, 77, 44, 98, 54, 17, 20, 15, 113, 27, 44, 29, 14, 53, 74, 10, 31, 8, 16, 36, 45, 39, 8, 4, 1, 35, 105, 45, 16, 11, 5, 4, 3, 6, 28, 53, 92, 32, 5, 5, 2, 27, 61, 23, 14, 9, 4, 6, 4]
constrcutor=
[2, 10, 54, 3, 2, 2, 5, 6, 7, 27, 111, 5, 3, 17, 11, 12, 8, 31, 113, 6, 3, 6, 10, 27, 2, 8, 63, 9, 13, 17, 2, 1, 54, 10, 16, 5, 13, 22, 18, 85, 37, 18, 17, 3, 99, 113, 29, 41, 113, 7, 21, 5, 28, 40, 34, 113, 12, 6, 14, 10, 93, 113, 8, 23, 54, 21, 50, 31, 20, 20, 7, 78, 18, 69, 82, 29, 86, 108, 9, 20, 77, 44, 98, 54, 17, 20, 15, 113, 27, 44, 29, 14, 53, 74, 10, 31, 8, 16, 36, 45, 39, 8, 4, 1, 35, 105, 45, 16, 11, 5, 4, 3, 6, 28, 53, 92, 32, 5, 5, 2, 27, 61, 23, 14, 9, 4, 6, 4]
res=
[1.1986551e+10, 0, 8.6976665e+23, 0, 0.00012219016, 1.0372148e-08, 6.3080874e-10, 0, 7, 27, 111, 5, 127.62504, 0, 0, 0, 8.6650199e-38, 0, 8.6650199e-38, 0, 8.6653068e-38, 0, 8.6653068e-38, 0, 0, 0, 0, 0, 8.6650512e-38, 0, 8.6650916e-38, 0, 0, 0, 0, 0, 0, 22.000002, 0, 0, 0, 0, 8.6651656e-38, 0, 0, 0, 8.6652015e-38, 0, 0, 0, 0, 5, 1.6213893e+09, 0, 0, 0, 12, 6, 0, 0, 144173.88, 0, 8.6651544e-38, 0, 0, 21.000174, 50, 31, 20, 20, 7, 78, 18, 69, 0, 0, 144173.88, 0 ...
(more)
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
2

answered 2017-04-23 11:48:02 -0600

berak gravatar image

updated 2017-04-23 11:50:10 -0600

if you use a Mat constructor with a data pointer, like you do here:

cv::Mat1f desc(1,128,vec.data());

this will copy only the pointer ,NOT the pixels (or whatever it holds).

once you leave that function, your local vector goes out of scope, and your Mat has a "dangling pointer", pointing to nowwhere.

remedy: make sure to copy the actual data (deep copy), like:

res.push_back(Result(desc.clone(), Keypoint(...)));

or:

cv::Mat1f desc(vec, true); // also a deep copy
edit flag offensive delete link more

Comments

@berak is it correct to say that this is going to be very inefficient in terms of performance because of the deep copy? This is for an HPC application, I need to do this efficiently as possible

lovaj gravatar imagelovaj ( 2017-04-23 11:52:12 -0600 )edit
1

yea, i already knew , you would say that .., but you simply can't have a cake and eat it.

only way to avoid it, imho is: stick with either vector or Mat as long as you can.

maybe you can get rid of the vector, preallocate the Mat, and use float *data = mat.ptr<float>()in your calculation ?

berak gravatar imageberak ( 2017-04-23 12:12:07 -0600 )edit
2

@berak that was what I was thinking about!

lovaj gravatar imagelovaj ( 2017-04-23 12:40:12 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2017-04-23 11:27:08 -0600

Seen: 203 times

Last updated: Apr 23 '17