6

I have one problem for which I could not find any solution.

I have to make some calculations with the inverse of one known matrix.

Matrix homography=

1.1688, 0.23, 62.2,

-0.013,1.225, -6.29,

0, 0, 1, 

and then:

Mat homoInv=homography.inv();

The content of the matrix would be:

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

0, -0, 0, 

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

That of course is wrong as I already checked the result in Matlab. Both matrix are displayed and read as floats, and their depth is a 64FC1.

Does anyone have any idea of what could be done?

Thanks All

More code:

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

function printMatrix:

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

But the error is not in printMatrix, as If i print the elements separately I obtain the same strange result in the numbers of inverse.

Angie Quijano
  • 4,167
  • 3
  • 25
  • 30
Ivánovick
  • 267
  • 1
  • 5
  • 17
  • You have a bug in your code somewhere. If you want more help, you'll have to post more code. – Peter Jun 13 '12 at 13:20
  • Are you sure that this matrix is invertible? If not, it's possible that matlab is calculating the pseudo-inverse instead. – Ian Medeiros Jun 13 '12 at 17:33
  • 1
    It may be late and useless, but if you do `std::cout << your_cv_mat << std::endl;` it will print the matrix. you don't need any function like "printMatrix" :) – Bastienm Nov 21 '17 at 13:16

1 Answers1

12

The problem was, as Peter pointed out, in my code. I still don't understand the reason deeply but it is like:

I was treating the data CV_64F as float, it is a mistake, it needs to be treated as double, for writing values and reading them.(<double>)

However CV_32F can be treated as float, the access would be with <float>.

user513951
  • 12,445
  • 7
  • 65
  • 82
Ivánovick
  • 267
  • 1
  • 5
  • 17
  • 3
    This will help understand why. I am certain Opencv uses the type to get the position in the memory. For index (i,j) in a 2D array(assuming row major with continuity), the position in the memory will usually be at index ( i * number_of_columns + j)*(sizeof_variable_type) from the position the beginning of the data. Default C++ pointer indexing uses the pointer type to know the number of bytes to skip.Thus if the type is not as expected, you end up assigning values to wrong memory space as with your question. Bottom line, your inverse calculation was not on the data you expected – I L Aug 25 '16 at 00:16
  • The number in the `CV_` types is the number of bits. You'd have to check how many bits a `float` and `double` is in your system. You can do this with [sizeof](https://en.cppreference.com/w/cpp/language/sizeof), which will return the number of bytes. By the way, for small matrices of known size, you should use `cv::Matx`. Conveniently this issue would have been avoided, because then you say `cv::Matx homography` and access the elements easily with `homography(0, 0) = 1.1688;` – darda Dec 03 '20 at 20:25