【点云学习】pcl中PointCloud和PointCloud::Ptr的复制与函数传参

本文用于记录在使用PointCloud和PointCloud::Ptr时,等号复制、函数传参以及copyPointCloud复制,这几种方法复制后,旧的变量修改是否会影响所复制的变量。仅用于记录,不保证准确。【转载请注明出处】

1. 函数调用

测试了四种函数参数,分别是Ptr类型,PointCloud类型,PointCloud的引用,以及const引用:

void func_ptr(MyPointCloud::Ptr pc){
    pc->resize(0);
}
void func_pointcloud(MyPointCloud pc){
    pc.resize(0);
}
void func_ref(MyPointCloud& pc){
    pc.resize(10);
}
void func_pointcloud_ref(const MyPointCloud& pc){
    // pc.resize(0);  // Error! cannot change size.
}

测试方法和结果如下:

MyPointCloud::Ptr pc (new MyPointCloud()), pc2(new MyPointCloud());
MyPointCloud pc3, pc4;

cout<<"================  Function test ================" <<endl;
string filename = "mesh.pcd";
pcl::io::loadPCDFile<MyPoint>(filename, *pc);

cout << "------- Test 1. Using Ptr" << endl;
func_ptr(pc);
cout << "after: " << (*pc).size() << endl;			// 被修改了,为0

pcl::io::loadPCDFile<MyPoint>(filename, *pc);
cout << "------- Test 2.1 Using pointcloud but input *ptr" << endl;
func_pointcloud(*pc);
cout << "after: " << (*pc).size() << endl;			// 未被修改,依旧为12500

pcl::io::loadPCDFile<MyPoint>(filename, pc3);
cout << "------- Test 2.2 Using pointcloud but input pointcloud" << endl;
func_pointcloud(pc3);
cout << "after: " << pc3.size() << endl;			// 未被修改,依旧为12500

pcl::io::loadPCDFile<MyPoint>(filename, pc3);
pcl::io::loadPCDFile<MyPoint>(filename, *pc);
cout << "------- Test 3. Using ref pointcloud" << endl;
func_ref(*pc);
cout << "after: " << (*pc).size() << endl;			// 被修改了,为10
func_ref(pc3);
cout << "after: " << pc3.size() << endl;			// 被修改了,为10

结论:使用Ptr或引用&,函数内修改会改变实参;而直接PointCloud则不会改变实参。

2. 等号复制

cout << "================  Operator= test ================" << endl;
cout << "------- Test 1. Copy pointer to pointer" << endl;
pcl::io::loadPCDFile<MyPoint>(filename, *pc);
pc2 = pc;
pc->resize(0);
cout << "Pc2: " << pc2->size() << endl;			// 被修改了,为0

cout << "------- Test 2. Copy *pointer to *pointer" << endl;
pcl::io::loadPCDFile<MyPoint>(filename, *pc);
*pc2 = *pc;
pc->resize(0);
cout << "Pc2: " << pc2->size() << endl;			// 被修改了,为0

cout << "------- Test 3. Copy *pointer to value" << endl;
pcl::io::loadPCDFile<MyPoint>(filename, *pc);
pc3 = *pc;
pc->resize(0);
cout << "Pc3: " << pc3.size() << endl;			// 没有被修改


cout << "------- Test 4. Copy value to value" << endl;
pcl::io::loadPCDFile<MyPoint>(filename, pc3);
pc4 = pc3;
pc3.resize(0);
cout << "Pc4: " << pc3.size() << endl;			// 被修改了,为0

cout << "------- Test 5. Copy value to *pointer" << endl;
pcl::io::loadPCDFile<MyPoint>(filename, pc3);
*pc = pc3;
pc3.resize(0);
cout << "Pc: " << pc->size() << endl;			// 没有被修改

结论:指针和指针之间,无论是指针本身用等号,还是指针内容用等号,本质是同一块数据;PointCloud和PointCloud也是如此。但用指针数据赋给非指针,或反过来,则使用两块内存。

3. copyPointCloud函数

pcl提供了copyPointCloud函数用于点云复制,那么再测一下这个是不是“深度拷贝”

cout << "================  Copy Function test ================" << endl;
cout << "------- Test 1. Copy *pointer to *pointer" << endl;
pcl::io::loadPCDFile<MyPoint>(filename, *pc);
pcl::copyPointCloud(*pc, *pc2);
pc->resize(0);
cout << "pc2: " << pc2->size() << endl;			// 被修改了,为0

cout << "------- Test 2. Copy *pointer to value" << endl;
pcl::io::loadPCDFile<MyPoint>(filename, *pc);
pcl::copyPointCloud(*pc, pc3);
pc->resize(0);
cout << "pc3: " << pc3.size() << endl;			// 没有被修改

cout << "------- Test 3. Copy value to *pointer" << endl;
pcl::io::loadPCDFile<MyPoint>(filename, pc3);
pcl::copyPointCloud(pc3, *pc);
pc3.resize(0);
cout << "pc: " << pc->size() << endl;			// 没有被修改

cout << "------- Test 4. Copy value to value" << endl;
pcl::io::loadPCDFile<MyPoint>(filename, pc3);
pcl::copyPointCloud(pc3, pc4);
pc3.resize(0);
cout << "pc4: " << pc4.size() << endl;			// 没有被修改

结论:用指针的数据时,使用相同内存;其他情况,指针给变量,或变量给变量,变量给指针,都是两块不同的区域。

4. 小结

之前每次写函数调用和等号复制时,都要纠结到底是共用同一块内存,还是有深拷贝。如今算是测试明白了。
完整测试代码:https://github.com/LarryDong/csdn_codes/tree/main/pointcloud_copy

你可能感兴趣的:(PCL点云处理,点云处理)