2016-06-19 10 views
3

ich versuche, eine DLL mit dem OpenCV PCA enthalten, um es unter Labview nutzbar zu machen.Pass cv :: Mat zu labview

Ich habe die Funktion definiert:

extern "C" __declspec(dllexport) int __cdecl doPCA(float *input,int32_t input_rows,int32_t input_cols,double maxComponents,float *output); 

und schrieb es mag:

int __cdecl doPCA(float *input,int32_t input_rows, int32_t input_cols,double maxComponents,float *output) 

{ 

    Mat pcaset = Mat(input_rows,input_cols, CV_32FC1, &input); //CV_32FC1 is for float valued pixel 

    PCA pca(pcaset,    // pass the data 
      Mat(),    // we do not have a pre-computed mean vector, // so let the PCA engine to compute it    
      CV_PCA_DATA_AS_ROW, // indicate that the vectors// are stored as matrix rows// (use PCA::DATA_AS_COL if the vectors are // the matrix columns)     
      2     // specify, how many principal components to retain 
      ); 

    int i, j; 
    for(i = 0; i < input_rows; i++) 
    { 
    for(j = 0; j < input_cols; j++) 
    { 
     output[(i * input_cols) + j] = pca.eigenvectors.data[(i * input_cols) + j];  // Write Values to 1D output array         
    } 
    } 

    if(pca.eigenvectors.empty()){return 0;}  // is empty 
    if(!pca.eigenvectors.empty()){return 1;} // is not empty  
} 

Auf Labview Seite greife ich auf die Funktion, die durch die kompilierte DLL:

Aber ich kann es nicht herausfinden, wie man den Wert vonübergibtcv::Mat an das 1D-Float-Ausgangsarray.

int i, j; 
    for(i = 0; i < input_rows; i++) 
    { 
    for(j = 0; j < input_cols; j++) 
    { 
     output[(i * input_cols) + j] = pca.eigenvectors.data[(i * input_cols) + j];  // Write Values to 1D output array         
    } 
    } 

Kann jemand einen Hinweis geben?

+0

Werfen Sie einen Blick [hier] (http://docs.opencv.org/3.1.0/d1/dee/tutorial_introduction_to_pca.html#gsc.tab = 0) um zu wissen, wie man richtig auf die Eigenvektoren zugreift. Sie sind nur "n_of_principal_components x dimension" (und nicht "input_rows x input_cols"), und sie sind "double" – Miki

Antwort

0

Ich lerne, wie man PCA von der page, die Miki gibt, macht.

Dies ist mein Code, um die ähnliche Sache zu tun.

///! Convert pointer to cv::Mat, do PCA, and convert back. 
///! 2017.10.05 10:28:25 CST 

int doPCA(float* data, int rows, int cols, int maxC, float* eigenvecs) { 
    // convert pointer to Mat, CV_32FC1 is for float valued pixel. 
    Mat pcaset = Mat(rows,cols, CV_32FC1, data); 
    // let opencv compute the eigenvectors, and treat data as row, extract the first 2 principle components. 
    // pca.means : eigenvalues as row matrix 
    // pca.eigenvectors: eigenvectors as row matrix 

    maxC = (maxC >0 && maxC <= rows)?maxC:rows; 
    PCA pca(pcaset, Mat(), CV_PCA_DATA_AS_ROW,maxC); 
    cout << "Eigen values:\n"<< pca.mean <<endl; 
    cout << "Eigen vectors:\n"<<pca.eigenvectors<<endl; 

    if(pca.eigenvectors.empty()) { 
     return 0; // is empty 
    } 

    float *pvec = eigenvecs; 
    // get eigenvector in revered order 
    for(int i=maxC-1; i>=0; --i){ 
     for(int j=0; j<cols; ++j){ 
      *pvec++ = pca.eigenvectors.at<float>(i,j); 
     } 
    } 
    return 1; 
} 

int testPCA(){ 
    // row first 
    float data[4] = {1.0,2.0,2.0,5.0}; 
    int cols = 2; 
    int rows = 2; 

    // alloc two eigenvectors length: 2x2=4 
    float eigenvecs[4]={0}; 
    // max components nums 
    int maxC = 2; 
    int res = doPCA(data, rows, cols, maxC, eigenvecs); 
    Mat eigenvalues(Size(cols, rows), CV_32FC1, eigenvecs); 

    cout << "Flag:\n" << res << endl; 
    cout << "Principle Components:\n"<< eigenvalues<<endl; 
    return 0; 
} 

Ergebnis:

Eigen values: 
[1.5, 3.5] 
Eigen vectors: 
[0.31622776, 0.94868332; 
0.94868332, -0.31622776] 
Flag: 
1 
Principle Components: 
[0.94868332, -0.31622776; 
0.31622776, 0.94868332]