【问题标题】:Inverse Matrix OpenCV. Matrix.inv() not working properly逆矩阵 OpenCV。 Matrix.inv() 无法正常工作
【发布时间】:2012-06-13 12:45:44
【问题描述】:

我有一个问题我找不到任何解决方案。

我必须用一个已知矩阵的逆进行一些计算。

Matrix homography=

1.1688, 0.23, 62.2,

-0.013,1.225, -6.29,

0, 0, 1, 

然后:

Mat homoInv=homography.inv();

矩阵的内容是:

1.81381e-29, 15.1628, -7.57361e+17, 

0, -0, 0, 

5.4561e-33, -2.40123e+34, -1.38198e-05

这当然是错误的,因为我已经在 Matlab 中检查了结果。两个矩阵都显示和读取为浮点数,它们的深度是64FC1

有人知道可以做什么吗?

谢谢大家

更多代码:

int main(int argc, char ** argv )
{ 
  Mat homogra(3,3,CV_64FC1);
  Mat coord(3,1,CV_64FC1);
  Mat result(target.size(),CV_8UC1);
  homogra.at<float>(0,0)=1.1688;
  homogra.at<float>(0,1)=0.23;
  homogra.at<float>(0,2)=(-62.20);
  homogra.at<float>(1,0)=(-0.013);
  homogra.at<float>(1,1)=1.225;
  homogra.at<float>(1,2)=-6.29;
  homogra.at<float>(2,0)=0;
  homogra.at<float>(2,1)=0;
  homogra.at<float>(2,2)=1;
  printMatrix(homogra);

  Mat inverse=homogra.inv();
  printMatrix(inverse);
}

函数打印矩阵:

void printMatrix(Mat M){
cout<<"Tipo de matriz:"<<M.type()<<endl;
 // dont print empty matrices
  if (M.empty()){
    cout << "---" << endl;
    return;
  }
  // loop through columns and rows of the matrix
  for(int i=0; i < M.rows; i++){
      for(int j=0; j < M.cols ; j++){
      cout << M.at<float>(i,j) << ", "<<endl;
      }
    cout<<"Change\n"<<endl;
}
  }

但错误不在printMatrix 中,因为如果我分别打印元素,我会在逆数中得到相同的奇怪结果。

【问题讨论】:

  • 您的代码中某处存在错误。如果您需要更多帮助,则必须发布更多代码。
  • 你确定这个矩阵是可逆的吗?如果不是,则 matlab 可能正在计算伪逆。
  • 它可能会迟到而且没用,但如果你这样做 std::cout &lt;&lt; your_cv_mat &lt;&lt; std::endl; 它会打印矩阵。你不需要像“printMatrix”这样的功能:)

标签: c++ opencv matrix-inverse


【解决方案1】:

正如彼得指出的那样,问题出在我的代码中。我仍然不明白原因,但它是这样的:

我将数据CV_64F 视为浮点数,这是一个错误,它需要被视为双精度,用于写入和读取值。(&lt;double&gt;)

但是CV_32F 可以被视为浮动,访问将使用&lt;float&gt;

【讨论】:

  • 这将有助于理解原因。我确定 Opencv 使用该类型来获取内存中的位置。对于二维数组中的索引 (i,j)(假设具有连续性的主行),内存中的位置通常位于数据开头位置的索引 (i * number_of_columns + j)*(sizeof_variable_type) 处。默认 C++ 指针索引使用指针类型来了解要跳过的字节数。因此,如果类型不符合预期,您最终会像您的问题一样将值分配给错误的内存空间。最重要的是,您的逆向计算不是基于您预期的数据
  • CV_ 类型中的数字是位数。您必须检查floatdouble 在您的系统中有多少位。您可以使用sizeof 执行此操作,它将返回字节数。顺便说一句,对于已知大小的小矩阵,您应该使用cv::Matx。很方便,这个问题本来可以避免,因为你说 cv::Matx&lt;double, 3, 3&gt; homography 并使用 homography(0, 0) = 1.1688; 轻松访问元素