点云pcl转图像opencv;图像转点云

#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;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值