Cv::Mat CvType在返回时发生更改

Cv::Mat CvType changes when return

本文关键字:返回 Mat CvType Cv      更新时间:2023-10-16

我使用OpenCv将欧拉角转换为旋转矩阵

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

结果我得到了例如:

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]

我不知道当我刚返回简历时发生了什么变化::Mat。我能做些什么来取回具有相同值的矩阵。

我确信clone()方法有效,但如果您确实关心性能,则应尽量避免复制。其思想是首先创建cv::Mat,并直接对其数据进行操作。在您的情况下

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

一旦退出函数,缓冲区rot将包含垃圾值。您需要clone()矩阵来创建内部数据的深层副本,因为简单的副本只会创建另一个指向相同内部数据的Mat标头(它会被损坏)。

所以你可以:

return resMat.clone();

或者避免创建一个中间矩阵:

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