C++ 创建一个模板以读取不同类型的点云
我创建了一个模板函数来读取PointXYZ和PointXYZI云。通过进一步添加,我还可以读取PointXYZRGB cloud。然而,这样的话,我想代码将更长,以适应其他类型。你能提出一个更好的解决办法吗 代码如下C++ 创建一个模板以读取不同类型的点云,c++,boost,point-cloud-library,point-clouds,C++,Boost,Point Cloud Library,Point Clouds,我创建了一个模板函数来读取PointXYZ和PointXYZI云。通过进一步添加,我还可以读取PointXYZRGB cloud。然而,这样的话,我想代码将更长,以适应其他类型。你能提出一个更好的解决办法吗 代码如下 template <typename T> typename T::Ptr readGeneralPointCloud( const std::string & filename , std::function<typename T::PointType
template <typename T>
typename T::Ptr readGeneralPointCloud( const std::string & filename , std::function<typename T::PointType( const std::string & )> storage_function )
{
std::ifstream input;
input.open( filename );
if( ! input.fail() )
{
typename T::Ptr pointCloud( new T);
std::string content;
while( std::getline( input , content ) )
{
pointCloud->points.push_back( storage_function( content ) );
}
return pointCloud;
}
else
{
throw std::exception( "Error occured : The file cannot be opened and the returned cloud is an empty cloud " );
return typename T::Ptr( new typename T() );
}
}
template <typename T>
T readPointCloud( const std::string &filename ){}
// Explicit template instantiation
template <>
pcl::PointCloud<pcl::PointXYZI>::Ptr readPointCloud( const std::string & filename )
{
return readGeneralPointCloud<pcl::PointCloud<pcl::PointXYZI>>
(
filename ,
[] ( const std::string & someStr ) -> pcl::PointXYZI
{
std::istringstream s( someStr );
std::vector<std::string> separated_tokens{ std::istream_iterator < std::string > {s} , std::istream_iterator < std::string > {} };
if( separated_tokens.size() != 4 )
{
throw std::exception( "Exception occured: The data of PointXYZI cloud should be 4" );
}
auto tmp = separated_tokens.cbegin();
pcl::PointXYZI xyzi_points;
try
{
xyzi_points.x = boost::lexical_cast< double >( *tmp++ );
xyzi_points.y = boost::lexical_cast< double >( *tmp++ );
xyzi_points.z = boost::lexical_cast< double >( *tmp++ );
xyzi_points.intensity = boost::lexical_cast< double >( *tmp++ );
return xyzi_points;
}
catch( const boost::bad_lexical_cast e )
{
throw std::exception( "Error Occured: The data couldn't be converted to double, possibly bad format of data" );
}
}
);
}
template <>
pcl::PointCloud<pcl::PointXYZ>::Ptr readPointCloud( const std::string & filename )
{
return readGeneralPointCloud<pcl::PointCloud<pcl::PointXYZ>>
(
filename ,
[] ( const std::string & someStr ) -> pcl::PointXYZ
{
std::istringstream s( someStr );
std::vector<std::string> separated_tokens{ std::istream_iterator < std::string > {s} , std::istream_iterator < std::string > {} };
if( separated_tokens.size() != 3 )
{
throw std::exception( "Exception occured: The number of data of PointXYZ cloud should be 3" );
}
auto tmp = separated_tokens.cbegin();
pcl::PointXYZ xyz_points;
try
{
xyz_points.x = boost::lexical_cast< double >( *tmp++ );
xyz_points.y = boost::lexical_cast< double >( *tmp++ );
xyz_points.z = boost::lexical_cast< double >( *tmp++ );
return xyz_points;
}
catch( const boost::bad_lexical_cast e )
{
throw std::exception( "Error Occured: The data couldn't be converted to double, possibly bad format of data" );
}
}
);
}
模板
typename T::Ptr readGeneralPointCloud(常量std::字符串和文件名,std::函数存储\函数)
{
std::ifstream输入;
打开(文件名);
如果(!input.fail())
{
类型名T::Ptr点云(新T);
std::字符串内容;
while(std::getline(输入,内容))
{
点云->点。向后推(存储功能(内容));
}
返回点云;
}
其他的
{
抛出std::exception(“发生错误:文件无法打开,返回的云是空云”);
返回typename T::Ptr(新的typename T());
}
}
模板
T readPointCloud(const std::string和filename){}
//显式模板实例化
模板
pcl::PointCloud::Ptr readPointCloud(常量std::字符串和文件名)
{
返回readGeneralPointCloud
(
文件名,
[](const std::string和someStr)->pcl::PointXYZI
{
std::istringstreams(someStr);
std::向量分隔的_标记{std::istream_迭代器{s},std::istream_迭代器{};
if(分隔的\u令牌.size()!=4)
{
抛出std::exception(“发生异常:PointXYZI云的数据应该是4”);
}
auto tmp=分离的令牌.cbegin();
pcl::点xyzi xyzi_点;
尝试
{
xyzi_points.x=boost::lexical_cast(*tmp++);
xyzi_points.y=boost::lexical_cast(*tmp++);
xyzi_points.z=boost::lexical_cast(*tmp++);
xyzi_points.intensity=boost::lexical_cast(*tmp++);
返回xyzi_点;
}
捕获(const boost::bad_词法_cast e)
{
抛出std::exception(“发生错误:数据无法转换为双精度,可能是数据格式错误”);
}
}
);
}
模板
pcl::PointCloud::Ptr readPointCloud(常量std::字符串和文件名)
{
返回readGeneralPointCloud
(
文件名,
[](常量std::string和someStr)->pcl::PointXYZ
{
std::istringstreams(someStr);
std::向量分隔的_标记{std::istream_迭代器{s},std::istream_迭代器{};
如果(分隔的\u令牌.size()!=3)
{
抛出std::exception(“发生异常:PointXYZ云的数据数应该是3”);
}
auto tmp=分离的令牌.cbegin();
pcl::点xyz xyz_点;
尝试
{
xyz_points.x=boost::词法转换(*tmp++);
xyz_points.y=boost::词法转换(*tmp++);
xyz_points.z=boost::词法转换(*tmp++);
返回xyz_点;
}
捕获(const boost::bad_词法_cast e)
{
抛出std::exception(“发生错误:数据无法转换为双精度,可能是数据格式错误”);
}
}
);
}
您能谈谈不使用pcl::io::loadPCDFile的动机吗?( ). 请注意,您可以将任何云加载到PointCloud2对象中。()@D.J.Duff有数百个点云fomat数据转换为.txt或其他格式文件。我必须创建一个应用程序来读取这些文件。该程序应允许用户读取这些数据。我不允许将数据更改为pcd格式。所以,我不得不保持现状。