5

複素数行列の逆行列を行うのに問題があります。私の知る限り、複雑なマトリックスは単純に 2 チャンネルのマトリックス (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_LU または DECOMP_CHOLESKY メソッドを使用して単一チャネルの画像を試したときに目的の結果が得られないため、DECOMP_SVD メソッドを使用することをお勧めします。これは、おそらく特異行列の問題が原因です。ありがとう。

4

1 に答える 1

6

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;
}
于 2013-03-29T07:08:57.550 に答える