点云数据常用处理:C++实现

python版本实现见:点云数据常用处理:python实现

数据集增强

仿射变换

平移变换

#include <iostream>
#include <fstream>
#include <time.h>

int main(int argc, char* argv[])
{
	std::ifstream infile;
	infile.open("rabbit.txt");
	std::fstream outfile;
	outfile.open("rabbit_change.txt", 'w');

	float x, y, z, r, g, b;
	srand((int)time(0));
	float delta_x = rand() * 20.0 / RAND_MAX - 10.0;
	float delta_y = rand() * 20.0 / RAND_MAX - 10.0;
	float delta_z = rand() * 20.0 / RAND_MAX - 10.0;
	while (infile >> x >> y >> z >> r >> g >> b)
	{
		outfile << x + delta_x << " " << y + delta_y << " " << z + delta_z << " "
			<< r << " " <<g << " " <<b << std::endl;
	}
	infile.close();
	outfile.close();

	return EXIT_SUCCESS;
}

旋转变换

#include <iostream>
#include <fstream>
#include <time.h>

#define M_PI 3.1415926

int main(int argc, char* argv[])
{
	std::ifstream infile;
	infile.open("rabbit.txt");
	std::fstream outfile;
	outfile.open("rabbit_change.txt", 'w');

	float x, y, z, r, g, b, temp_x, temp_y, temp_z;
	srand((int)time(0));
	float rot_x = rand() / 5.0 * M_PI / RAND_MAX - M_PI / 10.0;
	float rot_y = rand() / 5.0 * M_PI / RAND_MAX - M_PI / 10.0;
	float rot_z = rand() / 5.0 * M_PI / RAND_MAX - M_PI / 10.0;
	while (infile >> x >> y >> z >> r >> g >> b)
	{
		temp_x = x;
		temp_y = cos(rot_x)*y - sin(rot_x)*z;
		temp_z = sin(rot_x)*y + cos(rot_x)*z;

		x = cos(rot_y)*temp_x - sin(rot_y)*temp_z;
		y = temp_y;
		z = sin(rot_y)*temp_x + cos(rot_y)*temp_z;

		temp_x = cos(rot_z)*x - sin(rot_z)*y;
		temp_y = sin(rot_z)*x + cos(rot_z)*y;
		temp_z = z;

		outfile << temp_x << " " << temp_y << " " << temp_z << " " << r << " " << g << " " << b << std::endl;
	}
	infile.close();
	outfile.close();

	return EXIT_SUCCESS;
}

尺度变换

#include <iostream>
#include <fstream>
#include <time.h>

int main(int argc, char* argv[])
{
	std::ifstream infile;
	infile.open("rabbit.txt");
	std::fstream outfile;
	outfile.open("rabbit_change.txt", 'w');

	float x, y, z, r, g, b;
	srand((int)time(0));
	float scale = rand() * 2.0 / RAND_MAX;
	while (infile >> x >> y >> z >> r >> g >> b)
	{
		outfile << x * scale << " " << y * scale << " " << z * scale << " " << r << " " << g << " " << b << std::endl;
	}
	infile.close();
	outfile.close();

	return EXIT_SUCCESS;
}

仿射变换

上面三种变换综合可以写成:

#include <iostream>
#include <fstream>
#include <time.h>
#include <Eigen/Dense>

Eigen::Matrix4f random_transformation()
{
	srand((int)time(0));

	float x = rand() * 20.0 / RAND_MAX - 10.0;
	float y = rand() * 20.0 / RAND_MAX - 10.0;
	float z = rand() * 20.0 / RAND_MAX - 10.0;

	float rot_x = rand() / 5.0 * M_PI / RAND_MAX - M_PI / 10.0;
	float rot_y = rand() / 5.0 * M_PI / RAND_MAX - M_PI / 10.0;
	float rot_z = rand() / 5.0 * M_PI / RAND_MAX - M_PI / 10.0;

	float scale = rand() * 2.0 / RAND_MAX;

	Eigen::Vector3f ea(rot_x, rot_y, rot_z);
	Eigen::Matrix3f R;
	R = Eigen::AngleAxisf(ea[0], Eigen::Vector3f::UnitZ())*
		Eigen::AngleAxisf(ea[1], Eigen::Vector3f::UnitY()) *
		Eigen::AngleAxisf(ea[2], Eigen::Vector3f::UnitX());

	R(0, 0) *= scale;
	R(1, 1) *= scale;
	R(2, 2) *= scale;

	Eigen::Vector3f T(x, y, z);
	Eigen::Matrix4f H;
	H << R, T, 0, 0, 0, 1;
	return H;
}

int main(int argc, char* argv[])
{
	std::ifstream infile;
	infile.open("rabbit.txt");
	std::fstream outfile;
	outfile.open("rabbit_change.txt", 'w');

	float x, y, z, r, g, b, temp_x, temp_y, temp_z;
	Eigen::Matrix4f H = random_transformation();
	while (infile >> x >> y >> z >> r >> g >> b)
	{
		temp_x = H(0, 0)*x + H(0, 1)*y + H(0, 2)*z + H(0, 3);
		temp_y = H(1, 0)*x + H(1, 1)*y + H(1, 2)*z + H(1, 3);
		temp_z = H(2, 0)*x + H(2, 1)*y + H(2, 2)*z + H(2, 3);

		outfile << temp_x << " " << temp_y << " " << temp_z << " " << r << " " << g << " " << b << std::endl;
	}
	infile.close();
	outfile.close();

	return EXIT_SUCCESS;
}

仿射变换:
PCL 仿射变换,实现点云平移旋转

添加噪声

高斯噪声

#include <iostream>
#include <fstream>
#include <time.h>
#include <boost/random.hpp>

int main(int argc, char* argv[])
{
	std::ifstream infile;
	infile.open("rabbit.txt");
	std::fstream outfile;
	outfile.open("rabbit_change.txt", 'w');

	//添加高斯噪声
	boost::mt19937 rng;
	rng.seed(static_cast<unsigned int>(time(0)));
	boost::normal_distribution<> nd(0, 0.1);
	boost::variate_generator<boost::mt19937&, boost::normal_distribution<>> var_nor(rng, nd);

	float x, y, z, r, g, b;
	while (infile >> x >> y >> z >> r >> g >> b)
	{
		x += static_cast<float> (var_nor());
		y += static_cast<float> (var_nor());
		z += static_cast<float> (var_nor());
		outfile << x << " " << y << " " << z << " " << r << " " << g << " " << b << std::endl;
	}
	infile.close();
	outfile.close();

	return EXIT_SUCCESS;
}

随机噪声

#include <iostream>
#include <fstream>
#include <time.h>

int main(int argc, char* argv[])
{
	std::ifstream infile;
	infile.open("rabbit.txt");
	std::fstream outfile;
	outfile.open("rabbit_change.txt", 'w');

	float x, y, z, r, g, b;
	srand((int)time(0));
	while (infile >> x >> y >> z >> r >> g >> b)
	{
		float delta_x = rand() * 2.0 / RAND_MAX - 1.0;
		float delta_y = rand() * 2.0 / RAND_MAX - 1.0;
		float delta_z = rand() * 2.0 / RAND_MAX - 1.0;
		outfile << x + delta_x << " " << y + delta_y << " " << z + delta_z << " "
			<< r << " " << g << " " << b << std::endl;
	}
	infile.close();
	outfile.close();

	return EXIT_SUCCESS;
}

下采样

指定体素

体素滤波具体C++实现见:voxelgrid体素滤波实现
下面是pcl的api调用代码:

#include <iostream>
#include <fstream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/voxel_grid.h>

int main(int argc, char* argv[])
{
	std::ifstream infile;
	infile.open("rabbit.txt");
	std::fstream outfile;
	outfile.open("rabbit_change.txt", 'w');

	float x, y, z, r, g, b;
	pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
	pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZRGB>);
	while (infile >> x >> y >> z >> r >> g >> b)
	{
		pcl::PointXYZRGB p;
		p.x = x;
		p.y = y;
		p.z = z;
		p.r = r;
		p.g = g;
		p.b = b;
		cloud->push_back(p);
	}
	infile.close();

	pcl::VoxelGrid<pcl::PointXYZRGB> vg; //创建滤波器对象
	vg.setInputCloud(cloud);
	vg.setLeafSize(1, 1, 1);
	vg.filter(*cloud_filtered);

	for (size_t i = 0; i < cloud_filtered->size(); i++)
	{
		outfile << cloud_filtered->points[i].x << " " << cloud_filtered->points[i].y << " " << cloud_filtered->points[i].z << " "
			<< cloud_filtered->points[i].r << " " << cloud_filtered->points[i].g << " " << cloud_filtered->points[i].b << std::endl;
	}
	outfile.close();

	return EXIT_SUCCESS;
}

指定点数

#include <iostream>
#include <fstream>
#include <vector>
#include <time.h>

int main(int argc, char* argv[])
{
	std::ifstream infile;
	infile.open("rabbit.txt");
	std::fstream outfile;
	outfile.open("rabbit_change.txt", 'w');

	float x, y, z, r, g, b;
	srand((int)time(0));
	std::vector<std::vector<float>> points;
	while (infile >> x >> y >> z >> r >> g >> b)
	{
		points.push_back({ x, y, z, r, g, b });
	}

	std::vector<int> labels(points.size(), 0);
	std::vector<int> indexs;

	int down_size = 2048;
	if (points.size() < down_size)
		return -1;

	for (size_t i = 0; i < down_size; i++)
	{
		int rand_num = rand() % points.size();

		/*不重复采样应取消以下代码块的注释*/
		//while (true)
		//{
		//	if (labels[rand_num] == 0)
		//	{
		//		labels[i] = 1;
		//		break;
		//	}
		//	rand_num = rand() % points.size();
		//}

		outfile << points[rand_num][0] << " " << points[rand_num][1] << " " << points[rand_num][2] << " "
			<< points[rand_num][3] << " " << points[rand_num][4] << " " << points[rand_num][5] << std::endl;
	}

	return EXIT_SUCCESS;
}

调用pcl库api实现:

#include <iostream>
#include <fstream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/random_sample.h>

int main(int argc, char* argv[])
{
	std::ifstream infile;
	infile.open("rabbit.txt");
	std::fstream outfile;
	outfile.open("rabbit_change.txt", 'w');

	float x, y, z, r, g, b;
	pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
	pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZRGB>);
	while (infile >> x >> y >> z >> r >> g >> b)
	{
		pcl::PointXYZRGB p;
		p.x = x;
		p.y = y;
		p.z = z;
		p.r = r;
		p.g = g;
		p.b = b;
		cloud->push_back(p);
	}
	infile.close();

	pcl::RandomSample<pcl::PointXYZRGB> ran;     //创建滤波器对象
	ran.setInputCloud(cloud);   //设置待滤波点云
	ran.setSample(2048);     //设置下采样点云的点数
	ran.setSeed(1);      //设置随机函数种子点
	ran.filter(*cloud_filtered);   //执行随机下采样滤波

	for (size_t i = 0; i < cloud_filtered->size(); i++)
	{
		outfile << cloud_filtered->points[i].x << " " << cloud_filtered->points[i].y << " " << cloud_filtered->points[i].z << " "
			<< cloud_filtered->points[i].r << " " << cloud_filtered->points[i].g << " " << cloud_filtered->points[i].b << std::endl;
	}
	outfile.close();

	return EXIT_SUCCESS;
}

数据标准化

#include <iostream>
#include <fstream>
#include <vector>

int main(int argc, char* argv[])
{
	std::ifstream infile;
	infile.open("rabbit.txt");
	std::fstream outfile;
	outfile.open("rabbit_change.txt", 'w');

	float x, y, z, r, g, b;
	std::vector<std::vector<float>> points;
	while (infile >> x >> y >> z >> r >> g >> b)
	{
		points.push_back({ x, y, z, r, g, b });
	}
	infile.close();

	//去中心化
	float mean_x = 0, mean_y = 0, mean_z = 0;
	for (size_t i = 0; i < points.size(); ++i)
	{
		mean_x += points[i][0];
		mean_y += points[i][1];
		mean_z += points[i][2];
	}
	mean_x /=points.size();
	mean_y /=points.size();
	mean_z /=points.size();

	for (size_t i = 0; i < points.size(); ++i)
	{
		points[i][0] -= mean_x;
		points[i][1] -= mean_y;
		points[i][2] -= mean_z;
	}

	//尺度归一化
	float m = 0;
	for (size_t i = 0; i < points.size(); ++i)
	{
		if (sqrt(pow(points[i][0], 2) + pow(points[i][1], 2) + pow(points[i][2], 2)) > m)
			m = sqrt(pow(points[i][0], 2) + pow(points[i][1], 2) + pow(points[i][2], 2));
	}

	for (size_t i = 0; i < points.size(); ++i)
	{
		points[i][0] /= m;
		points[i][1] /= m;
		points[i][2] /= m;
		outfile << points[i][0] << " " << points[i][1] << " " << points[i][2] << " " << points[i][3] << " " << points[i][4] << " " << points[i][5] << std::endl;
	}
	outfile.close();

	return EXIT_SUCCESS;
}
  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

给算法爸爸上香

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值