BeJay
BeJay

Reputation: 425

Cv::Mat CvType changes when return

I've used OpenCv to transform euler angles to a rotationmatrix

cv::Mat transformEulerToRotation(const cv::Mat &euler) {
  float rot[9]
  //transforming things
  //...
  cv::Mat resMat = cv::Mat(3, 3, CV_32F, rot);
  //here can I check the result
  std::cout << "resMat " << resMat << std::endl;
  return resMat;
}

void otherFunction() {
  //...
  std::cout << "rotMat function " << transformEulerToRotation(euler) << std::endl;
  cv::Mat rotMat = transformEulerToRotation(euler).clone;
  std::cout << "rotMat variable " << rotMat << std::endl;
}

As a result I get e.g.:

resMat [0.99965221, -0.024546526, -0.009639469;
-0.017124595, 0.99955207, 0.024376612;
0.010061417, 0.017124617, 0.99980277]

rotMat function [6.4592681e-31, 0, 2.6510468e-36;
0, 4.291036e-38, 0;
6.4569209e-31, 0, 0.21559119]

rotMat variable [0.99965221, -0.024546526, 1.5537966e-32;
-3.7597382e+19, 0.99955207, 0.024376612;
9.3246211e-39, 0, 0.21557593]

I don't know what is changing when I just return the cv::Mat. What can I do to get back the Matrix with the same values.

Upvotes: 0

Views: 485

Answers (2)

cxyzs7
cxyzs7

Reputation: 1227

I am sure the clone() approach works, but if you do care about performance, you should try to avoid the copy. The idea is to create the cv::Mat first, and operate directly on its data. In your case

cv::Mat transformEulerToRotation(const cv::Mat &euler)
{
  cv::Mat rotMat(3, 3, CV_32F);
  float* rot = rotMat.ptr<float>();
  // You can operate on rot now
  // transforming things
  // ...
  // Check the result
  std::cout << "rotMat" << rotMat<< std::endl;
  return rotMat;
}

Upvotes: 2

Miki
Miki

Reputation: 41765

Once you exit the function, the buffer rot will contain garbage values. You need to clone() the matrix to create a deep copy of the internal data, since simple copy will just create another Mat header pointing to the same internal data (which will get corrupted).

So you can:

return resMat.clone();

or avoid to create an intermediate matrix:

return cv::Mat(3, 3, CV_32F, rot).clone();

Upvotes: 0

Related Questions