charlesq34 / pointnet2

PointNet++: Deep Hierarchical Feature Learning on Point Sets in a Metric Space
Other
3.13k stars 900 forks source link

Normalize the point sets #95

Open wusuoweima opened 5 years ago

wusuoweima commented 5 years ago

How do you normalize the point sets to be zero mean and within a unit ball? I use the following method, but it seems to be wrong. ` void normalized() { ifstream inputfile; string filename; string obj_root_path = "./DataSet/ModelNet40_obj"; string ply_root_path = "./DataSet/ModelNet40_Ply_Normalized"; string filename2 = "filenames.txt";

inputfile.open(filename2);
while (inputfile.fail())
{
    cout << "Fail to open the filenames_final.txt " << endl;
    system("Pause");
    exit(1);
}
while (!inputfile.eof())
{
    inputfile >> filename;
    //if (filename != "\\piano\\test/piano_0326") continue;

    PolygonMesh pcl_mesh;
    PointCloud<pcl::PointXYZ> cloud;
    PointCloud<pcl::Normal>::Ptr cloud_normals(new PointCloud<pcl::Normal>);
    string input_path = obj_root_path + filename + ".obj";

    if (!pcl::io::loadPolygonFile("F:/ModelNet40/ModelNet40_obj/cup/train/cup_0067.obj", pcl_mesh))
    {
        cout << "error: pcl can not read the input file " << input_path << endl;
        system("Pause");
        exit(-1);
    }
    MatrixXd coors_Mat(pcl_mesh.cloud.width, 3);
    coors_Mat.setZero();

    PCLPointCloud2ToMatrix(pcl_mesh.cloud, coors_Mat);
    // normalize the  point sets or mesh model  
    VectorXd norms;
    auto center = coors_Mat.colwise().mean();
    norms = coors_Mat.rowwise().norm();

    coors_Mat = coors_Mat.rowwise() - center;
    coors_Mat = coors_Mat / norms.maxCoeff();

    MatrixToPCLPointCloud2(coors_Mat, pcl_mesh.cloud);
    string save_path = ply_root_path + filename + ".ply";

    if (!pcl::io::savePolygonFile(save_path, pcl_mesh, false))
    {
        cout << "error: fail write: " << save_path << endl;
        system("Pause");
        exit(1);
    }
    else
    {
        cout << "normalized success: " << save_path << endl;

    }
    //pcl::visualization::PCLVisualizer viewer("PCL viewer");
    ////viewer.setBackgroundColor(0.0, 0.0, 0.0);
    ////viewer.addPointCloud<Normal>(cloud_normals);
    //viewer.addPolygonMesh(pcl_mesh, "normalized mesh");

    ////viewer.addPointCloudNormals<pcl::PointXYZ, pcl::Normal>(cloud, cloud_normals);
    //while (!viewer.wasStopped())
    //{
    //  viewer.spinOnce();
    //}

}

}

void PCLPointCloud2ToMatrix(const PCLPointCloud2 &cloud, MatrixXd &points) {

PointCloud<pcl::PointXYZ> pointCloud;
pcl::fromPCLPointCloud2(cloud, pointCloud);
for (unsigned i = 0; i < pointCloud.size(); i++)
{
    pcl::PointXYZ &p = pointCloud.at(i);
    if (!pcl_isnan(p.x) && !pcl_isnan(p.y) && !pcl_isnan(p.z))
    {
        points(i, 0) = p.x;
        points(i, 1) = p.y;
        points(i, 2) = p.z;
    }
}

} void MatrixToPCLPointCloud2(const MatrixXd &coors_Mat,PCLPointCloud2 &cloud ) {

PointCloud<pcl::PointXYZ> pointCloud;
PointXYZ point;
for (unsigned i = 0; i < coors_Mat.rows(); i++)
{
    if (!pcl_isnan(coors_Mat(i, 0)) && !pcl_isnan(coors_Mat(i, 0)) && !pcl_isnan(coors_Mat(i, 0)))
    {
        point.x = coors_Mat(i, 0);
        point.y = coors_Mat(i, 1);
        point.z = coors_Mat(i, 2);
    }
    else
    {
        cout << "error:matrix to points cloud" << endl;
        system("Pause");
        exit( -1);
    }
    pointCloud.push_back(point);
}
pcl::toPCLPointCloud2(pointCloud, cloud);

}` Questions: (1) The center of mesh model or point cloud is not at the origin。such as cup_0072 image

(2) some models' radius will be very samll ,such as cup_0002 image

1543067435 1

The following maybe normal image

wusuoweima commented 5 years ago

I open these models with meshlab

ting9059 commented 5 years ago

@wusuoweima ,hello,I met the same problem,did you resolve it?

ShiQiu0419 commented 5 years ago

@wusuoweima ,hello,I met the same problem,did you resolve it?

there are codes for such preprocessings in the project (python implementation), it is very intuitive:

  1. compute mean coordinates (x',y',z'): (x',y',z') = mean(coords(poincloud))
  2. subtract (x',y',z') from all points: coords(translated_pointcloud) = coords(pointcloud) - (x',y',z') ---that is to move the point cloud to the origin
  3. calculate distances between all points and the origin (0,0,0), and find the maximum: dist_max
  4. coordinates of all points divided by dist_max: coords(final_poincloud) = coords(translated_pointcloud)/dist_max

You can follow above steps to implement in C++, hope it helps

CodeLHY commented 4 years ago

intuitive

I'm sorry to bother you, do you know how the ModelNet40 is preprocessed? It seems that the author just provided the link to the preprocessed data. I'm eager to know the way the preprocess the data.

ShiQiu0419 commented 4 years ago
  1. Using a certain sampling algorithm (Uniform sampling here) to collect points from the surface of 3d model (CAD model here).
  2. Preprocessings: moving the centroid of each model to the origin, then scaling the point cloud to fit in a unit sphere.

------------------ Original ------------------ From: 李弘洋 <notifications@github.com> Date: Sat,Apr 4,2020 6:11 PM To: charlesq34/pointnet2 <pointnet2@noreply.github.com> Cc: ShiQiu0419 <philqiu@foxmail.com>, Comment <comment@noreply.github.com> Subject: Re: [charlesq34/pointnet2] Normalize the point sets (#95)

intuitive

I'm sorry to bother you, do you know how the ModelNet40 is preprocessed? It seems that the author just provided the link to the preprocessed data. I'm eager to know the way the preprocess the data.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.

CodeLHY commented 4 years ago
  1. Using a certain sampling algorithm (Uniform sampling here) to collect points from the surface of 3d model (CAD model here). 2. Preprocessings: moving the centroid of each model to the origin, then scaling the point cloud to fit in a unit sphere. ------------------ Original ------------------ From: 李弘洋 <notifications@github.com> Date: Sat,Apr 4,2020 6:11 PM To: charlesq34/pointnet2 <pointnet2@noreply.github.com> Cc: ShiQiu0419 <philqiu@foxmail.com>, Comment <comment@noreply.github.com> Subject: Re: [charlesq34/pointnet2] Normalize the point sets (#95) intuitive I'm sorry to bother you, do you know how the ModelNet40 is preprocessed? It seems that the author just provided the link to the preprocessed data. I'm eager to know the way the preprocess the data. — You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.

Thank you for your timely reply. In fact, I was confused by the modelnet40 data set applied by "https:/ /shapenet .cs.stanford。edu/media/modelnet40 normal resampled.zip ". This is a processed data set, where every resampled point is preprocessed to be a 6 dim vector. I did not know the way of implementation of the process. And now I have found the answer, the author not only normalized the coordinates but also add the surface normal(decomposed to x y z ). Anyway, thank you for your help!

ShiQiu0419 commented 4 years ago

Original modelnet40 is CAD-generated, thus the face normals are known. The samples are collected from certain faces whose normals are known, therefore correponding normals can be attached as additional feature of sampled points.

I think the author has clarified these issues, you may have a look at this github project or paper for details.

------------------ Original ------------------ From: 李弘洋 <notifications@github.com> Date: Sun,Apr 5,2020 0:28 AM To: charlesq34/pointnet2 <pointnet2@noreply.github.com> Cc: ShiQiu0419 <philqiu@foxmail.com>, Comment <comment@noreply.github.com> Subject: Re: [charlesq34/pointnet2] Normalize the point sets (#95)

CodeLHY commented 4 years ago

Original modelnet40 is CAD-generated, thus the face normals are known. The samples are collected from certain faces whose normals are known, therefore correponding normals can be attached as additional feature of sampled points. I think the author has clarified these issues, you may have a look at this github project or paper for details. ------------------ Original ------------------ From: 李弘洋 <notifications@github.com> Date: Sun,Apr 5,2020 0:28 AM To: charlesq34/pointnet2 <pointnet2@noreply.github.com> Cc: ShiQiu0419 <philqiu@foxmail.com>, Comment <comment@noreply.github.com> Subject: Re: [charlesq34/pointnet2] Normalize the point sets (#95)

It's so kind of you.

I reviewed the paper of PointNet and PointNet++ but could found nothing about it. T.T