Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

The results of cv::eigen() are different on Win10 and Ubuntu.

I use the eigenvectors of the local covariance matrix to compute the normals of a point cloud. But I found the results of the function cv::eigen() are different with the same code and data on different OS. The local covariance matrixes are always same, but the signs of the eigenvectors are opposite partially as the image below. image description image description The first picture is from ubuntu, and the code was compiled by g++. The second picture is from Win10 compiled by VS2017. I want to know why did this happen and how to fix it. Thanks in advance.

Here is my code.

  int computeNormalsPC3d(const Mat& PC, Mat& PCNormals, const int NumNeighbors, const bool FlipViewpoint, const Vec3f& viewpoint)
{
  int i;

  if (PC.cols!=3 && PC.cols!=6) // 3d data is expected
  {
    //return -1;
    CV_Error(cv::Error::BadImageSize, "PC should have 3 or 6 elements in its columns");
  }

  PCNormals.create(PC.rows, 6, CV_32F);
  Mat PCInput = PCNormals.colRange(0, 3);
  Mat Distances(PC.rows, NumNeighbors, CV_32F);
  Mat Indices(PC.rows, NumNeighbors, CV_32S);

  PC.rowRange(0, PC.rows).colRange(0, 3).copyTo(PCNormals.rowRange(0, PC.rows).colRange(0, 3));

  void* flannIndex = indexPCFlann(PCInput);

  queryPCFlann(flannIndex, PCInput, Indices, Distances, NumNeighbors);
  destroyFlann(flannIndex);
  flannIndex = 0;

#if defined _OPENMP
#pragma omp parallel for
#endif
  for (i=0; i<PC.rows; i++)
  {
    Matx33d C;
    Vec3d mu;
    const int* indLocal = Indices.ptr<int>(i);

    // compute covariance matrix
    meanCovLocalPCInd(PCNormals, indLocal, NumNeighbors, C, mu);
    std::cout << "C: "<< C << std::endl;
    // eigenvectors of covariance matrix
    Mat eigVect, eigVal;
    eigen(C, eigVal, eigVect);
    std::cout << "eigVect: " << eigVect << std::endl;
    eigVect.row(2).convertTo(PCNormals.row(i).colRange(3, 6), CV_32F);

    if (FlipViewpoint)
    {
      Vec3f nr(PCNormals.ptr<float>(i) + 3);
      Vec3f pci(PCNormals.ptr<float>(i));
      flipNormalViewpoint(pci, viewpoint, nr);
      Mat(nr).reshape(1, 1).copyTo(PCNormals.row(i).colRange(3, 6));
    }
  }

  return 1;
}

Here is the function cv::eigen in opencv2/core.hpp

CV_EXPORTS_W bool eigen(InputArray src, OutputArray eigenvalues,
                        OutputArray eigenvectors = noArray());