2013-03-29 18 views
6

Ho difficoltà a fare l'inverso di una matrice complessa. Per quanto ne so, la matrice complessa è semplicemente una matrice a due canali (CV_32FC2/CV_64FC2).Come eseguire l'inverso su una matrice complessa in OpenCV?

Diciamo che ho una matrice 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); 

Dopo eseguo la funzione invertito, continuo a ricevere questo errore:

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

La funzione di inversione funziona bene con un'immagine in scala di grigi caricato (1 canale), ma ho difficoltà a fare inversione su una matrice complessa che contiene parti reali e immaginarie.

Qualcuno può dirmi come risolvere il problema inverso di una matrice complessa? Preferibilmente utilizzando il metodo DECOMP_SVD, poiché non riesco a ottenere il risultato desiderato utilizzando il metodo DECOMP_LU o DECOMP_CHOLESKY quando ho provato con un'immagine a canale singolo, probabilmente a causa della questione della matrice singolare. Grazie.

risposta

6

OpenCV non supporta l'inversione di matrici complesse. Devi manipolare la matrice complessa in un modo per formare una matrice reale contenente le parti reali e immaginarie della matrice complessa. This page spiega il processo.

Ecco il codice per eseguire inversa di una matrice complessa utilizzando il processo di cui sopra:

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

Grazie amico, hai fatto la mia giornata. Funziona per la matrice sopra. Ho provato il programma con l'immagine e funziona anche con successo. Avrò bisogno di analizzare ulteriormente l'immagine e ora posso procedere con il mio prossimo passo di elaborazione. Grazie ancora! – user2223228

Problemi correlati