如何在OpenCV中做复矩阵的逆

How to do inverse on complex matrix in OpenCV?

本文关键字:OpenCV      更新时间:2023-10-16

我在做一个复矩阵的逆时遇到了麻烦。据我所知,复矩阵只是一个双通道矩阵(CV_32FC2/CV_64FC2)。

假设我有一个矩阵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);

执行逆函数后,我一直得到这个错误:

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

反函数在灰度加载图像(1通道)上工作得很好,但是我很难在包含实部和虚部的复矩阵上做反。

谁能告诉我如何解决一个复矩阵的逆问题?最好使用DECOMP_SVD方法,因为当我尝试使用单通道图像时,使用DECOMP_LU或DECOMP_CHOLESKY方法无法得到期望的结果,可能是因为奇异矩阵的问题。谢谢。

OpenCV不支持复矩阵的反转。你必须用一种方法来处理这个复矩阵来形成一个包含复矩阵的实部和虚部的实矩阵。本页解释了这个过程。

下面是使用上述过程执行复矩阵逆的代码:

//Perform inverse of complex matrix.
cv::Mat invComplex(const cv::Mat& m)
{
    //Create matrix with twice the dimensions of original
    cv::Mat twiceM(m.rows * 2, m.cols * 2, CV_MAKE_TYPE(m.type(), 1));
    //Separate real & imaginary parts
    std::vector<cv::Mat> components;
    cv::split(m, components);
    cv::Mat real = components[0], imag = components[1];
    //Copy values in quadrants of large matrix
    real.copyTo(twiceM({ 0, 0, m.cols, m.rows })); //top-left
    real.copyTo(twiceM({ m.cols, m.rows, m.cols, m.rows })); //bottom-right
    imag.copyTo(twiceM({ m.cols, 0, m.cols, m.rows })); //top-right
    cv::Mat(-imag).copyTo(twiceM({ 0, m.rows, m.cols, m.rows })); //bottom-left
    //Invert the large matrix
    cv::Mat twiceInverse = twiceM.inv();
    cv::Mat inverse(m.cols, m.rows, m.type());
    //Copy back real & imaginary parts
    twiceInverse({ 0, 0, inverse.cols, inverse.rows }).copyTo(real);
    twiceInverse({ inverse.cols, 0, inverse.cols, inverse.rows }).copyTo(imag);
    //Merge real & imaginary parts into complex inverse matrix
    cv::merge(components, inverse);
    return inverse;
}