c#封装最新版本点云库pcl———— 自定义pcl算法封装

3 篇文章 0 订阅
2 篇文章 0 订阅

一、配置好pcl 的c++环境,添加cpp文件,添加如下函数:

#include "..\export.h"

#include "pcl\pcl_base.h"
#include "pcl\point_types.h"
#include <pcl/point_cloud.h>
#include <pcl/filters/approximate_voxel_grid.h>
#ifdef __cplusplus  
extern "C" {  // only need to export C interface if  
			  // used by C++ source code  
#endif  
//对点云进行近似体素下采样
EXPORT(void)   approximateVoxelDownSample(pcl::PointCloud<pcl::PointXYZ> * in_pc, double leaf_size,
                                                    pcl::PointCloud<pcl::PointXYZ> * out_pc)
{
    pcl::ApproximateVoxelGrid<pcl::PointXYZ> avoxel;
    avoxel.setInputCloud(in_pc->makeShared());
    avoxel.setLeafSize(leaf_size, leaf_size, leaf_size);
    avoxel.filter(*out_pc);
}

#ifdef __cplusplus  
}
#endif  

该示例为一个简单的近似体素滤波的封装函数,输入输出为点云数据类pcl::PointCloud<pcl::PointXYZ>的指针形式。

编译该代码生成相应的c++动态链接库

二、在c#中以DLLimport方式调用c++封装函数

[DllImport("xxxx.dll", CallingConvention= CallingConvention.Cdecl)]
private static extern void approximateVoxelDownSample(IntPtr input, double leaf_size, IntPtr out_cloud);

这里dll填入你自己的dll名称,函数名approximateVoxelDownSample不能输错,input,out_cloud为Inptr类型,对应c++函数中的点云指针

以下为c#调用代码:

PclSharp.PointCloudOfXYZ pointCloudOfXYZ = new PclSharp.PointCloudOfXYZ();
using (var reader = new PclSharp.IO.PCDReader())
{
    reader.Read("./rabbit.pcd", pointCloudOfXYZ);
}
var pc = new PclSharp.PointCloudOfXYZ();
approximateVoxelDownSample(pointCloudOfXYZ.Ptr, 0.005, pc.Ptr);
PclSharp.Vis.Visualizer visualizer = new PclSharp.Vis.Visualizer("cloud");
int v1 = visualizer.CreateViewPort(0, 0, 0.5, 1);
//visualizer.SetBackgroundColor(0, 0, 1, v1);
int v2 = visualizer.CreateViewPort(0.5, 0, 1, 1);
// visualizer.SetBackgroundColor(0,1,0, v2);

visualizer.AddPointCloud(pointCloudOfXYZ,"c1",255,0,0,v1);
visualizer.AddPointCloud(pc, "c2",0,255,0, v2);
visualizer.SpinOnce();

运行效果:

这里就完成了c#调用c++pcl算法调用

三、封装原理

这个例子中我们只使用pclsharp封装库的PointCloudOfXYZ数据接口,这个类自动帮我们完成了c++点云数据的内存管理,无需我们进行资源的释放。查看PointCloudOfXYZ源码:

基类为UnmanagedObject:

public abstract class UnmanagedObject : DisposableObject
{
    protected IntPtr _ptr;

    public IntPtr Ptr => _ptr;

    public static implicit operator IntPtr(UnmanagedObject obj)
    {
        return obj?._ptr ?? IntPtr.Zero;
    }
}

其中_ptr成员为非托管资源指针,本库中为c++点云数据指针

该类实现IDisposable接口用于管理非托管资源。

查看 PointCloudOfXYZ的默认构造函数:

 

public PointCloudOfXYZ()
        : this(Invoke.pointcloud_xyz_ctor())
    {
    }

pointcloud_xyz_ctor函数具体为

[DllImport("PclSharp.Extern.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr pointcloud_xyz_ctor();

对应c++实现为:

EXPORT(PointCloud<PointXYZ>*) pointcloud_xyz_ctor()
{
    return new PointCloud<PointXYZ>();
}

用于创建点云对象,返回点云指针

而 PointCloudOfXYZ的DisposeObject函数负责资源的释放

 

 protected override void DisposeObject()
    {
        if (!_suppressDispose)
        {
            Invoke.pointcloud_xyz_delete(ref _ptr);
        }
    }

其中pointcloud_xyz_delete的c++版本为:

EXPORT(void) pointcloud_xyz_delete(PointCloud<PointXYZ>** ptr)
{
    delete *ptr;
    *ptr = NULL;
}

其他类基本也是按这个形式封装,一般分为三步:pcl算法类的构造,调用,和释放。

注意pclsharp并没有封装pcl的所有算法,不过根据以上介绍的原理,不难实现其他算法的封装。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值