将cv :: Mat传递给labview

时间:2016-06-19 14:48:35

标签: c++ opencv dll labview

我尝试使用OpenCV PCA构建一个DLL,使其在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访问该函数:

但我无法弄明白,如何将值从pca.eigenvectors 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                                  
    }
  }

有人可以提示吗?

1 个答案:

答案 0 :(得分:0)

我从page给出的Miki了解如何进行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]