2016-06-19 213 views
3

我嘗試構建一個包含OpenCV PCA的DLL,以使其在Labview中可用。將cv :: Mat傳遞給labview

我所定義的功能:

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

而且這樣寫:

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  
} 

在Labview的身邊,我被編譯的DLL訪問功能:

但我無法弄清楚,如何從0123中傳遞值cv::Mat添加到1D浮點輸出數組。

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

任何人都可以給出提示嗎?

+0

看一看[這裏](http://docs.opencv.org/3.1.0/d1/dee/tutorial_introduction_to_pca.html#gsc.tab = 0)知道如何正確訪問特徵向量。它們只是'n_of_principal_components x dimension'(而不是'input_rows x input_cols'),它們是'double' – Miki

回答

0

我學會了如何從pageMiki給出的PCA。

這是我的代碼來做類似的事情。

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

結果:

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]