【问题标题】:How to do inverse on complex matrix in OpenCV?如何对 OpenCV 中的复矩阵求逆?
【发布时间】:2013-03-29 05:06:09
【问题描述】:

我在做复数矩阵的逆时遇到了麻烦。据我所知,复矩阵只是一个两通道矩阵(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 错误:反转中的断言失败(类型 == CV_32F || 类型 == CV_64F)

反转功能适用于灰度加载图像(1 通道),但我很难对包含实部和虚部的复杂矩阵进行反转。

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

【问题讨论】:

    标签: c++ opencv complex-numbers matrix-inverse


    【解决方案1】:

    OpenCV 不支持复杂矩阵的求逆。您必须以某种方式操作复矩阵以形成包含复矩阵的实部和虚部的实矩阵。 This page 解释了这个过程。

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

    //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;
    }
    

    【讨论】:

    • 谢谢哥们,你弥补了我的一天。它适用于上面的矩阵。我尝试了带有图像的程序,它也成功运行。我需要进一步分析图像,现在我可以继续下一步的处理了。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-05
    相关资源
    最近更新 更多