2013-03-29 32 views
6

Mam problem z odwróceniem złożonej macierzy. O ile mi wiadomo, złożona macierz jest po prostu macierzą dwukanałową (CV_32FC2/CV_64FC2).Jak wykonać odwrotność na złożonej macierzy w OpenCV?

Powiedzmy mam macierzy 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); 

Po pełnić funkcję inwertowany, wciąż otrzymuję ten błąd:

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

Funkcja inwertowanego działa dobrze z szarości załadowaniu obrazu (1 kanał), ale trudno mi zrobić odwrotność na złożonej macierzy, która zawiera część rzeczywistą i urojoną.

Czy ktoś może mi powiedzieć, jak rozwiązać odwrotny problem złożonej macierzy? Najlepiej przy użyciu metody DECOMP_SVD, ponieważ nie mogę uzyskać pożądanego wyniku przy użyciu metody DECOMP_LU lub DECOMP_CHOLESKY, gdy próbowałem z obrazem pojedynczego kanału, prawdopodobnie z powodu materii pojedynczej macierzy. Dzięki.

Odpowiedz

6

OpenCV nie obsługuje inwersji złożonych macierzy. Musisz manipulować złożoną macierzą w taki sposób, aby utworzyć prawdziwą macierz zawierającą rzeczywiste i urojone części złożonej macierzy. This page wyjaśnia proces.

Oto kod, aby wykonać odwrotność macierzy złożonej z wykorzystaniem wyżej wymienionego procesu:

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

Thanks kolego, to składa się mój dzień. Działa dla powyższej macierzy. Wypróbowałem program z obrazem i działa on z powodzeniem. Będę potrzebował dalszej analizy obrazu i mogę teraz przejść do następnego etapu przetwarzania. Dzięki jeszcze raz! – user2223228