Как я могу вычислить нормаль для каждой точки в облаке

Моя проблема заключается в следующем: у меня есть облако 3D-точек. Я хочу приписать каждую нормаль к каждой точке. Из учебника PCL:

// Create the normal estimation class, and pass the input dataset to it
pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
ne.setInputCloud (cloud.makeShared());

// Create an empty kdtree representation, and pass it to the normal estimation object.
// Its content will be filled inside the object, based on the given input dataset (as no other search surface is given).
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ> ());
ne.setSearchMethod (tree);

// Output datasets
pcl::PointCloud<pcl::Normal>::Ptr cloud_normals (new pcl::PointCloud<pcl::Normal>);

// Use all neighbors in a sphere of radius 3cm
ne.setRadiusSearch (0.03);

// Compute the features
ne.compute (*cloud_normals);

Я могу найти только все облачные нормали, я хотел бы назначить для каждой точки, учитывая ее точную нормаль.

2 ответа

Решение

Я предполагаю, что у вас есть облако точек типа сказать pcl::PointCloud<pcl::PointXYZRGB> и вы хотите назначить свои оценочные нормали поверхности каждой точке вашего облака точек.

Поверхностные нормали оцениваются для каждой точки вашего входного облака точек. Таким образом, размер поверхностного нормального облака точек равен размеру входного облака точек.

Вы можете создать другое облако точек типа pcl::PointCloud<pcl::PointXYZRGBNormal> который может содержать информацию для соответствующих нормалей вместе с местоположением и цветом точки. Тогда напишите for цикл для назначения.

Ниже приведен фрагмент кода для этого:

pcl::PointCloud<pcl::PointXYZRGB>& src; // Already generated
pcl::PointCloud<pcl::PointXYZRGBNormal> dst; // To be created

// Initialization part
dst.width = src.width;
dst.height = src.height;
dst.is_dense = true;
dst.points.resize(dst.width * dst.height);

// Assignment part
for (int i = 0; i < cloud_normals->points.size(); i++)
{
    dst.points[i].x = src.points[i].x;
    dst.points[i].y = src.points[i].y;
    dst.points[i].z = src.points[i].z;

    dst.points[i].r = src.points[i].r;
    dst.points[i].g = src.points[i].g;
    dst.points[i].b = src.points[i].b;

   // cloud_normals -> Which you have already have; generated using pcl example code 

    dst.points[i].curvature = cloud_normals->points[i].curvature;

    dst.points[i].normal_x = cloud_normals->points[i].normal_x;
    dst.points[i].normal_y = cloud_normals->points[i].normal_y;
    dst.points[i].normal_z = cloud_normals->points[i].normal_z;
}

Надеюсь, это поможет.

Вместо использования for цикл, вы можете использовать pcl::concatenateFields:

          pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals (new pcl::PointCloud<pcl::PointNormal>); 
    pcl::PointCloud<pcl::Normal>::Ptr normals (new pcl::PointCloud<pcl::Normal>);
    // Use all neighbors in a sphere of radius 3cm
    ne.setRadiusSearch (0.03);
    // Compute the features
    ne.compute (*normals);
    pcl::concatenateFields(*cloud, *normals, *cloud_with_normals); 
Другие вопросы по тегам