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. 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());