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

asked 2019-08-12 09:12:59 -0600

thom gravatar image

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());
edit retag flag offensive close merge delete

Comments

It seems, using the knowledge of this SO issue that data collected from source on 2 OS systems could have slight differences. This is the case with JPEG images for example, and in general with lossy compression. How is your data collected before processing with the eigen functions?

StevenPuttemans gravatar imageStevenPuttemans ( 2019-08-20 08:39:12 -0600 )edit

My data are read from the same file. So the inputs of the function cv::eigen() are same.

thom gravatar imagethom ( 2019-08-28 01:56:55 -0600 )edit

Exactly my point, on 2 OS systems, even reading from the exact same source, could be given different values.

StevenPuttemans gravatar imageStevenPuttemans ( 2019-08-28 03:14:30 -0600 )edit

I understood what you mean. But my found the input covariance matrixes of cv::eigen() are same which means the file was dealed correctly. I think the problem is in the cv::eigen() instead of the way processing file.

thom gravatar imagethom ( 2019-08-28 06:37:07 -0600 )edit