【问题标题】:PCL Release Build crashes with Failed to AllocatePCL Release Build 崩溃并分配失败
【发布时间】:2018-03-13 19:54:02
【问题描述】:

我对 PCL 和 C++ 比较陌生。我有这段代码在点云中分割平面。该代码在调试模式下工作正常。然而,发布配置不断崩溃,[initCompute] Failed to allocate 34263047 indices。每次尝试中索引的数量都在不断变化。

不确定需要做什么,我认为 PCL 使用智能指针,这意味着我不必显式释放引用。

关于如何绕过它的任何想法?我在下面附上我的代码以供参考。

原始云大小 13698107 过滤后的云大小 44196 [initCompute] 34263047 个索引分配失败。

环境: PCL 1.8.0 VS 2015 社区 视窗 10

感谢您的宝贵时间。

#include <iostream>
#include <vector>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/search/search.h>
#include <pcl/search/kdtree.h>
#include <pcl/features/normal_3d.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/filters/passthrough.h>
#include <pcl/segmentation/region_growing.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/filters/extract_indices.h>

#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/sample_consensus/ransac.h>
#include <pcl/sample_consensus/sac_model_plane.h>

#include <pcl/octree/octree.h>

#include <boost/filesystem.hpp>

typedef pcl::PointXYZ PointT;

std::vector<double> split_axis_vectors(std::string input, char delimiter) {
    std::vector<double> result;
    std::stringstream ss(input); // Turn the string into a stream.
    std::string tok;
    std::string::size_type sz;

    while (getline(ss, tok, delimiter)) {
        result.push_back(std::stod(tok));
    }

    return result;
}

std::vector<std::string> split_axis(std::string input, char delimiter) {
    std::vector<std::string> result;
    std::stringstream ss(input); // Turn the string into a stream.
    std::string tok;
    std::string::size_type sz;

    while (getline(ss, tok, delimiter)) {
        result.push_back(tok);
    }

    return result;
}

bool segment_planes(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,
    pcl::PointCloud<pcl::Normal>::Ptr normal,
    Eigen::Vector3f axis,
    int modelType,
    double epsAngle) {
    int nr_points = (int)cloud->points.size();
    //pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_plane(new pcl::PointCloud<pcl::PointXYZ >);
    //pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_p(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients());

    pcl::PointIndices::Ptr inliers(new pcl::PointIndices());

    pcl::SACSegmentationFromNormals<PointT, pcl::Normal> seg;
    //pcl::ExtractIndices<pcl::PointXYZ> extract;
    //pcl::ExtractIndices<pcl::Normal> extract_normals;

    // Temporary Objects for swapping
    //pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_tmp(new pcl::PointCloud<pcl::PointXYZ>);
    //pcl::PointCloud<pcl::Normal>::Ptr cloud_normals_tmp(new pcl::PointCloud<pcl::Normal>);

    // Segment Planes Vertical
    seg.setOptimizeCoefficients(true);
    seg.setModelType(modelType);
    seg.setNormalDistanceWeight(0.1);
    seg.setMethodType(pcl::SAC_RANSAC);
    seg.setMaxIterations(100);
    seg.setDistanceThreshold(0.2);
    seg.setAxis(axis);
    seg.setEpsAngle(epsAngle);
    seg.setInputNormals(normal);
    seg.setInputCloud(cloud);
    seg.segment(*inliers, *coefficients);

    if (inliers->indices.size() > 0 && 
        inliers->indices.size() >= nr_points * 0.5) {
        return true;
    }
    else {
        return false;
    }
}
int
main (int argc, char** argv)
{
    pcl::PointCloud<pcl::PointXYZ>::Ptr full_cloud(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PCLPointCloud2::Ptr cloud_blob(new pcl::PCLPointCloud2), cloud_filtered_blob(new pcl::PCLPointCloud2);

    std::vector<std::string> axises = split_axis(argv[3], ';');     // Get individual axis seperated by ;
    std::string out_dir = argv[2];

    // Fill in the cloud data
    pcl::PCDReader reader;
    reader.read(argv[1], *cloud_blob);
    pcl::fromPCLPointCloud2(*cloud_blob, *full_cloud);

    // Create SAC Model plane to test fitting of downsized cloud
    pcl::SampleConsensusModelPlane<pcl::PointXYZ>::Ptr model_p(new pcl::SampleConsensusModelPlane<pcl::PointXYZ>(full_cloud));

    std::cout << "Original Cloud Size " << cloud_blob->width * cloud_blob->height << std::endl;

    pcl::search::Search<pcl::PointXYZ>::Ptr tree = boost::shared_ptr<pcl::search::Search<pcl::PointXYZ> > (new pcl::search::KdTree<pcl::PointXYZ>);
    pcl::PointCloud <pcl::Normal>::Ptr normals (new pcl::PointCloud <pcl::Normal>);

    float leaf_size = 0.5f;

    // Create the filtering object: downsample the dataset using a leaf size of 1cm
    pcl::VoxelGrid<pcl::PCLPointCloud2> sor;
    sor.setInputCloud(cloud_blob);
    sor.setLeafSize(leaf_size, leaf_size, leaf_size);
    sor.filter(*cloud_filtered_blob);

    // Convert to the templated PointCloud
    pcl::fromPCLPointCloud2(*cloud_filtered_blob, *cloud);

    std::cout << "Filtered Cloud Size " << cloud->points.size() << std::endl;

    pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> normal_estimator;
    normal_estimator.setSearchMethod (tree);
    normal_estimator.setInputCloud (cloud);
    normal_estimator.setKSearch (25);
    normal_estimator.compute (*normals);

    pcl::RegionGrowing<pcl::PointXYZ, pcl::Normal> reg;
    reg.setMinClusterSize (100);
    reg.setMaxClusterSize (1000000);
    reg.setSearchMethod (tree);
    reg.setNumberOfNeighbours (15);
    reg.setInputCloud (cloud);
    reg.setInputNormals (normals);
    reg.setSmoothnessThreshold (5.0 / 180.0 * M_PI);
    reg.setCurvatureThreshold (1.0);

    std::vector <pcl::PointIndices> clusters;
    reg.extract (clusters);

    int no_clusters = clusters.size();
    std::cout << "Number of clusters is equal to " << no_clusters << std::endl;

    pcl::PointIndices::Ptr all_perp_indices(new pcl::PointIndices());
    all_perp_indices->indices.clear();
    pcl::PointIndices::Ptr all_parallel_indices(new pcl::PointIndices());
    all_parallel_indices->indices.clear();

    std::vector<Eigen::VectorXf> parallel_model_coffs;
    std::vector<Eigen::VectorXf> perpendicular_model_coffs;

    std::vector<int> perp_planes_indices;
    std::vector<int> parallel_planes_indices;

    pcl::octree::OctreePointCloudSearch<pcl::PointXYZ> octree(leaf_size);
    octree.setInputCloud(full_cloud);
    octree.addPointsFromInputCloud();

    for (int idx = 0; idx < no_clusters; idx = idx + 1) {
        std::cout << "Number of points in "<< idx << " is equal to " << clusters[idx].indices.size() << std::endl;
        //region_indices.insert(region_indices.end(), clusters[idx].indices.begin(), clusters[idx].indices.end());
        pcl::ExtractIndices<pcl::PointXYZ> extract;
        pcl::ExtractIndices<pcl::Normal> extract_normals;

        pcl::PointCloud<pcl::PointXYZ>::Ptr cluster_cloud(new pcl::PointCloud<pcl::PointXYZ>);
        pcl::PointCloud<pcl::Normal>::Ptr cluster_normals(new pcl::PointCloud<pcl::Normal>);

        pcl::PointIndices::Ptr cluster_inliers(new pcl::PointIndices());
        cluster_inliers->indices.clear();
        cluster_inliers->header = clusters[idx].header;
        cluster_inliers->indices = clusters[idx].indices;

        all_perp_indices->header = clusters[idx].header;
        all_parallel_indices->header = clusters[idx].header;

        // Extract the point cloud inliers in cluster
        extract.setInputCloud(cloud);
        extract.setIndices(cluster_inliers);
        extract.setNegative(false);
        extract.filter(*cluster_cloud);                     // Get Points in plane

        // Extact the point normal inliers in cluster
        extract_normals.setNegative(false);
        extract_normals.setInputCloud(normals);
        extract_normals.setIndices(cluster_inliers);
        extract_normals.filter(*cluster_normals);

        // Test perpendicular and parallel for all axis combinations
        for (int aIdx = 0; aIdx < axises.size(); aIdx = aIdx + 1) {
            std::vector<double> axis = split_axis_vectors(axises[aIdx], ',');

            // Segment Parallel Planes
            bool perp_plane_cloud = segment_planes(cluster_cloud,
                cluster_normals,
                Eigen::Vector3f(axis[0], axis[1], axis[2]),
                pcl::SACMODEL_PERPENDICULAR_PLANE,
                20.0f * 0.0174533f);

            if (perp_plane_cloud) {
                int n_perp_plane_point = cluster_cloud->points.size();

                for (int pp_Idx = 0; pp_Idx < n_perp_plane_point; pp_Idx = pp_Idx + 1) {
                    pcl::PointXYZ searchPoint = cluster_cloud->points[pp_Idx];
                    std::vector<int> perp_inliers;

                    if (octree.voxelSearch(searchPoint, perp_inliers)) {
                        all_perp_indices->indices.insert(all_perp_indices->indices.end(), perp_inliers.begin(), perp_inliers.end());
                    }
                }
            }

            // Segment Parallel Planes
            bool parallel_plane_cloud = segment_planes(cluster_cloud,
                cluster_normals,
                Eigen::Vector3f(axis[1] * -1, axis[0], axis[2]),
                pcl::SACMODEL_PERPENDICULAR_PLANE,
                20.0f * 0.0174533f);

            if (parallel_plane_cloud) {
                int n_parallel_plane_point = cluster_cloud->points.size();

                for (int pl_Idx = 0; pl_Idx < n_parallel_plane_point; pl_Idx = pl_Idx + 1) {
                    pcl::PointXYZ searchPoint = cluster_cloud->points[pl_Idx];
                    std::vector<int> parallel_inliers;

                    if (octree.voxelSearch(searchPoint, parallel_inliers)) {
                        all_parallel_indices->indices.insert(all_parallel_indices->indices.end(), parallel_inliers.begin(), parallel_inliers.end());
                    }
                }
            }
        }
    }

    // Extract Perpendicular Planes
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_perp(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::ExtractIndices<pcl::PointXYZ> extract_perp;
    extract_perp.setInputCloud(full_cloud);
    extract_perp.setIndices(all_perp_indices);
    extract_perp.setNegative(false);
    extract_perp.filter(*cloud_perp);

    if (cloud_perp->points.size() > 0) {
        pcl::io::savePCDFileBinaryCompressed(out_dir + "\\reg_segment_perp.pcd", *cloud_perp);
    }

    // Extract Parallel Planes
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_parallel(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::ExtractIndices<pcl::PointXYZ> extract_parallel;
    extract_parallel.setInputCloud(full_cloud);
    extract_parallel.setIndices(all_parallel_indices);
    extract_parallel.setNegative(false);
    extract_parallel.filter(*cloud_parallel);

    if (cloud_parallel->points.size() > 0) {
        pcl::io::savePCDFileBinaryCompressed(out_dir + "\\reg_segment_parallel.pcd", *cloud_parallel);
    }

    return (0);
}

里亚斯

【问题讨论】:

    标签: c++ point-cloud-library


    【解决方案1】:

    安装 pcl 很困难,因为与 pcl 软件一起使用的依赖项有很多。但是使用 vcpkg,安装就像一个单行命令一样。

    使用 Microsoft vcpkg 自动为您的项目构建静态库。 boost、tiff、openssl、flann、szip 等所有依赖项都将自行下载和安装。安装 vcpkg 后,在 Powershell 上键入以下内容。

    .\vcpkg install pcl:x64-windows-static
    

    【讨论】:

      【解决方案2】:

      我认为您使用了错误的 fla 库。尝试在发布模式下重建 flann 并仅使用 flann dll。希望对您有所帮助。

      【讨论】:

      • 感谢您的输入。这是有道理的,实际上它在正常估计时会崩溃。我正在使用这里的安装程序unanancyowen.com/en/pcl18。您能否指出 PCL 1.8 的 flann 兼容版本是什么,找不到有关兼容版本的任何文档?我将从源代码构建它,然后重试。
      • 理想情况下,我会使用最新的 flann 版本。我没有发现最新版本的问题。但我会自己使用 VS Compiler 从源代码编译库,而不是使用预编译的二进制文件。
      猜你喜欢
      • 2012-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-04
      相关资源
      最近更新 更多