OpenCV Q&A Forum - RSS feedhttp://answers.opencv.org/questions/OpenCV answersenCopyright <a href="http://www.opencv.org">OpenCV foundation</a>, 2012-2018.Fri, 29 Mar 2013 01:51:18 -0500How to do inverse on complex matrix in OpenCV?http://answers.opencv.org/question/10328/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;
}
}
}New userFri, 29 Mar 2013 01:51:18 -0500http://answers.opencv.org/question/10328/