#include <iostream>
#include <pcl/filters/passthrough.h>
#include "pcl/point_cloud.h"
//#include <pcl\range_image\range_image.h>
#include <vector>
#include <pcl/visualization/common/float_image_utils.h>
#include <pcl/io/png_io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_cloud.h>
#include <pcl/common/transforms.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/console/time.h>
#include <pcl/point_types.h>
#include "pcl/common/centroid.h"
#include "pcl/common/common.h"
#include <pcl/filters/conditional_removal.h> //条件滤波
#include <pcl/search/kdtree.h> //单独使用kd树的头文件(方法之一)
#include <pcl/segmentation/extract_clusters.h> // 欧式聚类
#include <opencv2/highgui.hpp>
#include <opencv2/core/types.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/opencv.hpp>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>
//#include "../include/my_Utility.h"
using namespace std;
using namespace cv;
typedef pcl::PointXYZI PointI;
typedef pcl::PointCloud<pcl::PointXYZI>::Ptr PCIPtr;
void pcd2img_img2pcl(const PCIPtr input_pc_,
int ingore_value_img_hw,
PCIPtr &output_pc_){
//获取点云最值
pcl::PointXYZI min_p_;//用于存放三个轴的最小值
pcl::PointXYZI max_p_;//用于存放三个轴的最大值
pcl::getMinMax3D(*input_pc_, min_p_, max_p_);
cout << "min_p_.x = " << min_p_.x << "\n" << endl;
cout << "max_p_.x = " << max_p_.x << "\n" << endl;
cout << "min_p_.y = " << min_p_.y << "\n" << endl;
cout << "max_p_.y = " << max_p_.y << "\n" << endl;
cout << "min_p_.z = " << min_p_.z << "\n" << endl;
cout << "max_p_.z = " << max_p_.z << "\n" << endl;
//定义图像的宽高
int image_rows = max_p_.x - min_p_.x +1;
int image_cols = max_p_.y - min_p_.y +1;
Mat image1 = Mat::zeros(image_rows, image_cols, CV_8UC1);//h行w列的全0矩阵
for (int i = 0; i < input_pc_->points.size(); i++)
{
int image_i = input_pc_->points[i].x - min_p_.x;
int image_j = input_pc_->points[i].y - min_p_.y;
if (input_pc_->points[i].z - min_p_.z < 255)
{
//根据点云高度,进行0-255转换
image1.at<uchar>(image_i, image_j) = static_cast<uchar>((input_pc_->points[i].z - min_p_.z) / (max_p_.z-min_p_.z)*255);
}else{
image1.at<uchar>(image_i, image_j) = static_cast<uchar>(255);
}
}
Mat image1_th;
cv::threshold(image1,image1_th,1,255,cv::THRESH_BINARY);
auto cloud_reuslt_src = std::make_shared<pcl::PointCloud<pcl::PointXYZI>>();
for (int i = 0 + ingore_value_img_hw; i < image1_th.rows - ingore_value_img_hw; i ++) {
for (int j = 0 + ingore_value_img_hw; j < image1_th.cols - ingore_value_img_hw; j++) {
int temp_ = static_cast<int>(image1_th.at<uchar>(i, j));
if(temp_ < 1) {
// cout << image1_th.at<uchar>(i, j) << " ";
pcl::PointXYZI point_1{0.0, 0.0, 0.0};
point_1.x = (i + min_p_.x) / 1.0f;
point_1.y = (j + min_p_.y) / 1.0f;
point_1.z = min_p_.z;
cloud_reuslt_src->emplace_back(point_1);
}
}
}
// auto ec_cloud_result_src = std::make_shared<pcl::PointCloud<pcl::PointXYZI>>();
// -------------------------------------------欧式聚类--------------------------------------------
typename pcl::search::KdTree<pcl::PointXYZI>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZI>);
tree->setInputCloud(cloud_reuslt_src);
vector<pcl::PointIndices> cluster_indices; // 聚类索引
pcl::EuclideanClusterExtraction<pcl::PointXYZI> ec;// 欧式聚类对象
ec.setClusterTolerance(2.0); // 设置近邻搜索的搜索半径(也即两个不同聚类团点之间的最小欧氏距离)
ec.setMinClusterSize(50); // 设置一个聚类需要的最少的点数目为100
ec.setMaxClusterSize(5000); // 设置一个聚类需要的最大点数目为25000
ec.setSearchMethod(tree); // 设置点云的搜索机制
ec.setInputCloud(cloud_reuslt_src); // 设置输入点云
ec.extract(cluster_indices); // 从点云中提取聚类,并将点云索引保存在cluster_indices中
//int size_th = cluster_indices[0].indices.size();
pcl::copyPointCloud(*cloud_reuslt_src,cluster_indices[0],*output_pc_);
if(cloud_reuslt_src->size() > 0)
pcl::io::savePCDFileBinary("/home/wzs/Rtzh/pcl_test/test_data/river/river_ec_cloud_result_src.pcd", *output_pc_);
};
int main(int argc, char** argv)
{
//pcl::PointCloud<pcl::PointXYZI> pointcloud;
auto pointcloud = std::make_shared<pcl::PointCloud<pcl::PointXYZI>>();
//读入点云
if (pcl::io::loadPCDFile("/home/wzs/Rtzh/pcl_test/test_data/river/water_ROI_2_sub_0.5.pcd", *pointcloud) < 0)
{
PCL_ERROR("目标文件不存在!\n");
return -1;
}
auto pointcloud_dst = std::make_shared<pcl::PointCloud<pcl::PointXYZI>>();
pcd2img_img2pcl(pointcloud,3,pointcloud_dst);
cout << pointcloud_dst->size() << endl;
cout << endl;
}
点云pcl转图像opencv;图像转点云
最新推荐文章于 2024-07-18 23:33:05 发布