0

I have detected a number of points from 2 images. I am trying to find a transformation matrix between these 2 images. So I need to do an inverse of the matrix coordinates of one matrix and then multiply it to the coordinates of the other Mat matrix. I used very simple opencv methods but I get this error https://i.stack.imgur.com/Rqp7v.jpg. I do not understand why. Here is my code http://pastebin.com/Tef42E2Q. Can anybody guide me here please?

Steph
  • 609
  • 3
  • 13
  • 32

1 Answers1

3

You should make sure at least two things before Mat inverse.

  1. The Matrix should be square.

  2. The Matrix should be non-singular, that is determinant should be non-zero.

Eg:

    Mat A(3,3,CV_32FC1);
    A=(Mat_<float>(3,3)<< 0,2,3,\
                          4,5,6,\
                          7,8,9);
    cout<<A <<endl;

    if(determinant(A)!=0){
    Mat B=A.inv();
    cout<<B <<endl;
    }

Also see the answer Mat.inv() yielding all zeroes in opencv

Edit:-

Here is some bug I found in your code

The piece of code

    Mat matrix_f(2,3,CV_32F);
    matrix_f=Mat(coordinates_f);

should changed to

    Mat matrix_f(2,3,CV_32F);
    matrix_f=Mat(coordinates_f);
    matrix_f=matrix_f.reshape(1,2);

because later you are going to multiply with a 3X3 Mat, So we will make it's rows to 3

And next is change the lines

    Mat new_left(3,3,CV_32F);
    new_left=Mat(coordinates_l_new);

to

      Mat new_left(3,3,CV_32F);
      new_left=Mat(coordinates_l_new);
      new_left=new_left.reshape(1,3);

as you are going to find the inverse of new_left, it should be square matrix.

And finally make sure the Mat is non-singular by finding determinant

 if(determinant(new_left)!=0) {
        Mat T(3,3,CV_32F);
        T=matrix_f * (new_left.inv());
  } 
Community
  • 1
  • 1
Haris
  • 13,645
  • 12
  • 90
  • 121
  • your piece of code works perfectly if I manually input the elements of matrix A. But my problem is when I take a matrix found earlier in the code,I am not able to find its inverse and nor am I able to perform a multiplication with it, giving me the error above – Steph Feb 04 '14 at 06:30
  • Can you show your full code?...In the link you provided with your question you may use the code `Mat T=matrix_f * (new_left.inv());` see if it working. – Haris Feb 04 '14 at 06:38
  • If you post your image it will help me debug your code – Haris Feb 04 '14 at 07:14
  • okayy thanks!one more thing..when I apply this transformation matrix to the original left image and when I try to display it,it shows a yellow image with the detected green pixels. I added this part inside the if statement: Mat left_transformed=Mat::zeros(left.size(),left.type()); left_transformed=left.mul(T); imshow("left_trans",left_transformed);Why does it not display the transformed left image correctly? – Steph Feb 04 '14 at 18:26
  • For Mat::mul both Mat should be same type and size [See OpenCV Doc](http://docs.opencv.org/modules/core/doc/basic_structures.html#mat-mul) – Haris Feb 05 '14 at 07:11
  • okayy!!I was trying to apply the transformation matrix to the whole image so that it becomes like that http://i.imgur.com/DXxKu5V.jpg. But after looking at opencv doc,this is not possible. Do you have any suggestions?because I tried affineTransform as well,it did not work :s – Steph Feb 05 '14 at 07:35
  • You can apply affinTransfor with your own Mat like `Mat warp_dst = Mat::zeros( front.rows, front.cols, front.type() ); warpAffine( front, warp_dst, T, warp_dst.size() ); imshow("warp_dst",warp_dst);` – Haris Feb 05 '14 at 07:56
  • that's exactly what I did but I get this error message http://i.imgur.com/DXxKu5V.jpg – Steph Feb 05 '14 at 08:00
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/46816/discussion-between-haris-and-steph) – Haris Feb 05 '14 at 08:02