深度相机同时保存深度图和彩色图及合成点云

空格键保存深度图和彩色图,办公室环境三维重建

/home/yake/catkin_ws/src/pcl_in_ros/src/16_02rgb_depth_saver.cpp

rosrun pcl_in_ros rgb_depth_saver

#include <ros/ros.h>
#include <sensor_msgs/PointCloud2.h>

#include <boost/foreach.hpp>

#include <sensor_msgs/Image.h>
#include <sensor_msgs/image_encodings.h>

#include <image_transport/image_transport.h>
#include <image_geometry/pinhole_camera_model.h>

#include <cv_bridge/cv_bridge.h>

// OpenCV2
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

// PCL
#include <pcl/point_cloud.h>
#include <pcl_conversions/pcl_conversions.h>
#include <pcl/io/pcd_io.h>

#include <pcl/visualization/cloud_viewer.h>
#include <pcl/point_types.h>


#include <message_filters/subscriber.h>
#include <message_filters/synchronizer.h>
#include <message_filters/sync_policies/approximate_time.h>

using std::cout;
using std::endl;
using std::stringstream;
using std::string;

using namespace cv;
using namespace std;
using namespace sensor_msgs;
using namespace message_filters;
using namespace pcl;

unsigned int filesNum = 1;
bool saveCloud = false;

void
keyboardEventOccured(const visualization::KeyboardEvent& event, void* nothing)
{
    if(event.getKeySym() == "space"&& event.keyDown())
        saveCloud = true;

}

boost::shared_ptr<visualization::CloudViewer>
createViewer()
{
    boost::shared_ptr<visualization::CloudViewer> v(new visualization::CloudViewer("OpenNI viewer"));
    v->registerKeyboardCallback(keyboardEventOccured);

    return(v);
}

void callback(const ImageConstPtr& image_color_msg, const ImageConstPtr& image_depth_msg)
{
    cv::Mat image_color = cv_bridge::toCvCopy(image_color_msg)->image; // BGR8
    //    cv::Mat image_depth = cv_bridge::toCvCopy(image_depth_msg)->image;
    //    cv_bridge::CvImagePtr image_depth = cv_bridge::toCvCopy(image_depth_msg , sensor_msgs::image_encodings::TYPE_32FC1);
    //    cv::normalize(image_depth->image, image_depth->image, 1, 0, cv::NORM_MINMAX);

//    cv_bridge::CvImagePtr image_depth = cv_bridge::toCvCopy(image_depth_msg , sensor_msgs::image_encodings::TYPE_16UC1);
    cv_bridge::CvImagePtr image_depth = cv_bridge::toCvCopy(image_depth_msg);

    cv::imshow("color", image_color);
    cv::imshow("depth", image_depth->image);

    if(saveCloud)
    {

        vector<int>compression_param;
        compression_param.push_back(CV_IMWRITE_JPEG_QUALITY);
        compression_param.push_back(100);//  Highest quality

        vector<int>d_compression_param;
        d_compression_param.push_back(CV_IMWRITE_PNG_COMPRESSION);
        d_compression_param.push_back(0);// png Highest quality

        stringstream stream;
        stream  <<"/home/yake/pcl_gaoxiang/rgbd-slam-tutorial-gx-master/yake_potatochip_kinect/rgb_jpgfile/"<< "rgb"<< filesNum<< ".jpg";
        string filename = stream.str();

        stringstream stream2;
        stream2 <<"/home/yake/pcl_gaoxiang/rgbd-slam-tutorial-gx-master/yake_potatochip_kinect/depth_pngfile/"<< "depth"<< filesNum<< ".png";
        string filename2 = stream2.str();


        imwrite (filename.c_str (), image_color,compression_param);
        //        imwrite (filename2.c_str (), image_depth);

        imwrite(filename2.c_str (), image_depth->image, d_compression_param);

        cout << filename<<" Saved."<<endl;
        cout << filename2<<" Saved."<<endl;

        filesNum++;
        saveCloud = false;

    }

    cv::waitKey(3);
}



int main(int argc, char** argv)
{
    ros::init(argc, argv, "vision_node");

    ros::NodeHandle nh;

    cout<< "Press space to save rgb_raw and depth_raw to a file."<<endl;

    boost::shared_ptr<visualization::CloudViewer> viewer;
    viewer = createViewer();

//    message_filters::Subscriber<Image> image_color_sub(nh,"/camera/rgb/image_raw", 1); // bayer_grbg8
    message_filters::Subscriber<Image> image_color_sub(nh,"/camera/rgb/image_color", 1);// bgr8

//     Use the rqt_reconfigure close registration. Otherwise the depth image has no data.(freenect driver)
    message_filters::Subscriber<Image> image_depth_sub(nh,"/camera/depth/image_raw", 1);// 16UC1
//        message_filters::Subscriber<Image> image_depth_sub(nh,"/camera/depth/image", 1);// 32FC1

//     Open the depth registratioin.
//        message_filters::Subscriber<Image> image_depth_sub(nh,"/camera/depth_registered/image_raw", 1); // 16UC1
//    message_filters::Subscriber<Image> image_depth_sub(nh,"/camera/depth_registered/image", 1); // 32FC1

    typedef sync_policies::ApproximateTime<Image, Image> MySyncPolicy;
    Synchronizer<MySyncPolicy> sync(MySyncPolicy(5), image_color_sub, image_depth_sub);

    sync.registerCallback(boost::bind(&callback, _1, _2));

    ros::Rate rate(30.0);

    while (ros::ok() && ! viewer->wasStopped())
    {
        ros::spinOnce();
        rate.sleep();
    }


    return 0;
}

===============利用彩色图和深度图合成点云================= 

https://blog.csdn.net/u012700322/article/details/51821249

// 遍历深度图
    for (int m = 0; m < depth.rows; m++)
{
        for (int n=0; n < depth.cols; n++)
        {
            // 获取深度图中(m,n)处的值
            ushort d = depth.ptr<ushort>(m)[n];
            // d 可能没有值,若如此,跳过此点
            if (d == 0)
                continue;
            // d 存在值,则向点云增加一个点
            PointT p;
 
            // 计算这个点的空间坐标
            p.z = double(d) / camera_factor;
            p.x = (n - camera_cx) * p.z / camera_fx;
            p.y = (m - camera_cy) * p.z / camera_fy;
            
            // 从rgb图像中获取它的颜色
            // rgb是三通道的BGR格式图,所以按下面的顺序获取颜色
            p.b = rgb.ptr<uchar>(m)[n*3];
            p.g = rgb.ptr<uchar>(m)[n*3+1];
            p.r = rgb.ptr<uchar>(m)[n*3+2];
 
            // 把p加入到点云中
            cloud->points.push_back( p );
        }
}

高翔一起做RGBD-SLAM 

https://www.cnblogs.com/gaoxiang12/tag/%E4%B8%80%E8%B5%B7%E5%81%9ARGB-D%20SLAM/

 

 

  • 4
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 生成点云的方法通常涉及三维重建技术,可以使用彩色图和深度图进行点云生成。 首先,使用相机捕捉到场景的彩色图像深度图像。深度图像记录了场景中每个像素到相机的距离,因此可以用于计算场景中物体的三维形状。 接下来,可以使用计算机视觉库(例如OpenCV)中的函数将彩色图像深度图像转换为点云数据。具体来说,可以使用以下步骤: 1. 根据相机的内部参数和深度图像中的像素值,计算每个像素对应的三维坐标。这可以通过相机标定和深度图像的反投影来实现。 2. 将计算出的三维坐标与彩色图像中的像素值进行匹配,从而将每个点的颜色信息与其三维坐标关联起来。 3. 将匹配后的点云数据保存为常见的三维点云格式,例如PLY或OBJ。 值得注意的是,点云的生成质量受到深度图像的质量和精度的限制。因此,在进行点云生成之前,需要对深度图像进行校准和滤波,以消除深度图像中的噪声和失真。 ### 回答2: 彩色图和深度图如何生成点云,需要通过相机获取彩色图和深度图的数据,并将其转化为点云表示。 首先,彩色图是由相机捕捉到的每个像素点的颜色信息组成的图像。我们可以通过相机的光学传感器来获取每个像素点的颜色值,并将其转化为RGB格式的数据。 其次,深度图是由相机测量到的每个像素点距离相机的距离信息组成的图像。我们可以通过相机的深度传感器来获取每个像素点到相机的距离,并将其转化为深度值或者相对距离值。 生成点云的过程可以分为以下几个步骤: 1. 根据相机的内参矩阵和外参矩阵,将彩色图和深度图中的每个像素点的坐标变换到世界坐标下。 2. 对于每个像素点,根据深度值和相机的投影模型,计算出其对应的三维坐标。 3. 将每个像素点的三维坐标和对应的彩色信息组成一个点(Point)。 4. 将所有生成的点组成一个点云(PointCloud),可以使用相应的数据结构进行存储和操作。 需要注意的是,生成点云的质量和精度会受到相机的质量、深度传感器的性能以及相机标定的准确度等因素的影响。在实际操作中,还可以采用点云滤波、点云配准等技术对生成的点云进行进一步处理和优化。 ### 回答3: 彩色图和深度图是通过不同的传感器获得的。彩色图是由RGB相机等传感器捕捉到的,它能够感知物体的颜色和纹理。而深度图则是由深度相机或者ToF(Time of Flight)相机获得的,它能够感知物体与相机之间的距离。 生成点云需要将这两种图像信息结合起来。首先,我们需要提取彩色图中的RGB信息和深度图中的深度信息。然后,将深度信息转化为三维坐标,即将每个像素的深度值映射到相应的空间位置上。 通常,由于深度图像素与RGB图像像素在空间上的对应关系是已知的,我们可以根据它们的像素索引进行匹配。通过将深度值与相应的图像坐标配对,我们可以将每个像素的深度信息转化为点的三维坐标。 在生成点云时,我们可以用每个点的坐标来表示物体在三维空间中的位置。此外,我们还可以将对应点在彩色图中的RGB值赋给该点的颜色属性,从而给点云赋予颜色信息。 总结来说,生成点云需要利用彩色图和深度图提取RGB信息和深度信息,并将深度信息转化为三维坐标。然后,通过将像素索引匹配并将颜色属性关联,可以得到带有颜色和三维位置信息的点云。这样的点云可以用于许多应用领域,如三维重建、虚拟现实和机器人视觉等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

yaked19

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

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

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

打赏作者

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

抵扣说明:

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

余额充值