# How to do inverse on complex matrix in OpenCV?

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 close merge delete

Sort by ยป oldest newest most voted

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.

more

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.

( 2013-03-29 05:23:25 -0500 )edit

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

( 2013-03-29 05:50:17 -0500 )edit

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

( 2013-03-29 14:48:00 -0500 )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.

( 2013-03-30 23:25:50 -0500 )edit
1

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

( 2013-03-31 06:38:19 -0500 )edit
1

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

( 2013-04-01 04:47:16 -0500 )edit

Official site

GitHub

Wiki

Documentation