美文网首页
PCL点云格式转换成tiff格式

PCL点云格式转换成tiff格式

作者: book_02 | 来源:发表于2020-07-15 12:10 被阅读0次

    近期,需要把PCL的点云格式转换成tiff格式的图片,然后在halcon中处理。
    总结转换过程如下

    1. 转换函数(C++代码)

    主要思路:

    1. 使用了libtiff库,来写tiff格式
    2. 把点云的x,y,z通道转换成tiff格式图片的三通道。
    3. 所以后续读取tiff格式图片转换成点云时,注意三通道代表x,y,z的顺序
    4. 写tiff格式的时候就是设置文件头,然后把数据一个字节一个字节的写进去

    函数说明:

    1. pointcloud2tiff()是主要的转换函数,把PCL的点云数据cloud,写到filename文件中去
    2. main()写了调用示例,读取"test_tif.ply"点云文件,转换成tiff格式,写到"test.tif"文件中去
    #include <iostream>
    #include <pcl/io/ply_io.h>
    #include <pcl/point_cloud.h>
    #include <pcl/point_types.h> 
    #include <string>
    #include "tiffio.h"
    
    using namespace std;
    
    void pointcloud2tiff(const pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud, const std::string filename)
    {
        TIFF *out = TIFFOpen(filename.c_str(), "w");
        int sampleperpixel = 3; // x, y, z
        int bitspersample = 32; //float
        int width = cloud->width;
        int height = cloud->height;
        float *image = new float[width*height*sampleperpixel];
        int linesamples = sampleperpixel * width;
        int linebytes = linesamples * sizeof(float);
        for (int r = 0; r < height; ++r) {
            for (int c = 0; c < width; ++c) {
                image[r*(linesamples)+3 * c + 0] = (*cloud)(c, r).x;
                image[r*(linesamples)+3 * c + 1] = (*cloud)(c, r).y;
                image[r*(linesamples)+3 * c + 2] = (*cloud)(c, r).z;
            }
        }
        // set header
        TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width);                   // set the width of the image
        TIFFSetField(out, TIFFTAG_IMAGELENGTH, height);                 // set the height of the image
        TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, sampleperpixel);     // set number of channels per pixel
        TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, bitspersample);        // set the size of the channels
        TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);    // set the origin of the image.
                                                                        // Some other essential fields to set that you do not have to understand for now.
        TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
        TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
        TIFFSetField(out, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
    
        unsigned char  *buf = NULL;
        if (TIFFScanlineSize(out)) {
            buf = (unsigned char *)_TIFFmalloc(linebytes);
        }
        else {
            buf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(out));
        }
    
        // We set the strip size of the file to be size of one row of pixels
        TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(out, width*sampleperpixel));
    
        //Now writing image to the file one strip at a time
        for (int row = 0; row < height; row++) {
            //memcpy(buf, &image[(height - row - 1)*linebytes], linebytes * sizeof(float));
            memcpy(buf, &image[row*linesamples], linebytes);
            if (TIFFWriteScanline(out, buf, row, 0) < 0) {
                fprintf(stderr, "scanline %d: Write error.\n", row);
                break;
            }
        }
    
        TIFFClose(out);
        if (buf) {
            _TIFFfree(buf);
        }
        if (image) {
            delete[]image;
        }
    }
    
    int main()
    {
        pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
    
        pcl::io::loadPLYFile<pcl::PointXYZRGB>("test_tif.ply", *cloud);
    
        pointcloud2tiff(cloud, "test.tif");    
    
        return 0;
    }
    

    2. 其他说明

    2.1 libtiff库

    libtiff库的安装使用,可参考官网 http://www.libtiff.org/

    按照说明,编译安装即可。

    使用的时候建议用cmake来配置

    2.2 扩展说明

    1. 上面的代码是把x,y,z通道保存到tif中去,如果需要把r,g,b等其他信息也保存进去,注意sampleperpixel和tiff文件头的设置
    2. 根据上面的代码,可以不限于PCL的点云格式,只要把相应的x,y,z信息填进去即可转换成tiff

    相关文章

      网友评论

          本文标题:PCL点云格式转换成tiff格式

          本文链接:https://www.haomeiwen.com/subject/zzydhktx.html