Ask Your Question
0

How to do inverse on complex matrix in OpenCV?

asked 2013-03-29 01:51:18 -0600

New user gravatar image

updated 2013-04-01 04:44:55 -0600

I have trouble in doing inverse of a complex matrix. As far as I know, complex matrix is simply a two-channel matrix (CV_32FC2 / CV_64FC2).

(Written in C++) Let's say I have a matrix C:

Mat C(2, 2, CV_64FC2);

C.at<vec2d>(0,0)[0] = 1; C.at<vec2d>(0,0)[1] = 1; C.at<vec2d>(0,1)[0] = 3; C.at<vec2d>(0,1)[1] = 4; C.at<vec2d>(1,0)[0] = 2; C.at<vec2d>(1,0)[1] = -1; C.at<vec2d>(1,1)[0] = 5; C.at<vec2d>(1,1)[1] = 2;

Mat InverseMat; invert(C, InverseMat, DECOMP_SVD);

After I perform the invert function, I keep getting this error:

OpenCV Error: Assertion failed (type == CV_32F || type == CV_64F) in invert

The invert function works well with a grayscale loaded image (1 channel), but I have hard time to do inverse on complex matrix which contains real and imaginary part.

Can someone please tell me how to solve the inverse problem of a complex matrix? Preferably using DECOMP_SVD method, as I can't get desired result using DECOMP_LU or DECOMP_CHOLESKY method when I tried with a single channel image, probably because of the matter of singular matrix. Thanks.

From the solution I received, it's something like this:

void invComplex(const cv::Mat& m, cv::Mat& inverse)

{ cv::Mat twiceM = cv::Mat(m.rows * 2, m.cols * 2,CV_64FC1);

std::vector<cv::Mat> comp;
cv::split(m,comp);

cv::Mat real = comp[0];
cv::Mat imag = comp[1];

for(int i=0; i<m.rows; i++)
{
    for(int j=0; j<m.cols; j++)
    {
        twiceM.at<double>(i,j) = real.at<double>(i,j);
        twiceM.at<double>(i,j + m.cols) = imag.at<double>(i,j);
        twiceM.at<double>(i + m.rows,j) = -imag.at<double>(i,j);
        twiceM.at<double>(i + m.rows,j + m.cols) = real.at<double>(i,j);
    }
}

cv::Mat twiceInv;
cv::invert(twiceM,twiceInv);

inverse = cv::Mat(m.cols,m.rows,m.type());

for(int i=0; i<inverse.rows; i++)
{
    for(int j=0; j<inverse.cols; j++)
    {
        double re = twiceInv.at<double>(i,j);
        double im = twiceInv.at<double>(i,j + inverse.cols);

        cv::Vec2d val(re,im);

        inverse.at<cv::Vec2d>(i,j) = val;
    }
}

}

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
1

answered 2013-03-29 04:28:58 -0600

Can you resolve the problem by

  1. grabbing the real channel,
  2. calculating the inverse,
  3. then grabbing the complex channel,
  4. calculating again the inverse,
  5. combine the previous inverse channels in new two channel matrix?

No idea if this would do the trick, it is just a suggestion.

edit flag offensive delete link more

Comments

1

Your suggestion is a bit similar to my trial before, but that time I grabbed the complex channel first and do inverse together with real channel. Somehow, I couldn't get correct result, maybe due to errors in my program. However, I received a solution and I solved my problem now. I have to manipulate the complex matrix in a way to form a real matrix (1 channel) containing the real and imaginary parts of the complex matrix, as explained in http://home.earthlink.net/~w6rmk/math/matinv.htm Do the invert function, then arrange the real and imaginary results back to a 2-channel matrix again. Thanks a lot for your response anyway, as I am still fresh with OpenCV and programming. I am grateful with all the receiving responses.

New user gravatar imageNew user ( 2013-03-29 05:23:25 -0600 )edit

Basically you just aligned both channels into a single channel, which is a correct solution indeed.

StevenPuttemans gravatar imageStevenPuttemans ( 2013-03-29 05:50:17 -0600 )edit

Are you sure the result still has the mathematical properties of an inverse martix?

sammy gravatar imagesammy ( 2013-03-29 14:48:00 -0600 )edit
1

It works correctly with the simple matrix I posted above. Not sure if I apply it on image, but at least the program can run when I input an image & seems fine to me. I was unable to post the code at the moment, seems that new user in this website is only allowed to answer own question after 2 days of registration. Insufficient characters space to post in comment.

New user gravatar imageNew user ( 2013-03-30 23:25:50 -0600 )edit
1

@new-user You should post code in the question (edit it), not as an answer.

sammy gravatar imagesammy ( 2013-03-31 06:38:19 -0600 )edit
1

Appended the code in the question. Please have a look & feel free to give comments.

New user gravatar imageNew user ( 2013-04-01 04:47:16 -0600 )edit

Question Tools

Stats

Asked: 2013-03-29 01:51:18 -0600

Seen: 6,046 times

Last updated: Apr 01 '13