利用stringstream缓存加速PCD文件读取

利用stringstream缓存加速PCD文件读取

在用pcl读取点云文件的时候有时需要处理几十万点云数据,对于1-5万的点云直接用

pcl::io::loadPCDFile(“pointcloud.pcd”, cloud)

来读取确实很方便,但是大于点数大于20万时读取时间会额外加长,尤其debug模式下,所以自己写了一个读pcd格式的点云文件。如果用io流逐行读取,文件读取的时间会急剧增长,而一次性将数据会部读入内存之后再处理,达到减少IO次数的目的。
头文件:

#pragma once
#include "stdafx.h"
#include<iostream>
#include <fstream>
#include <regex>
#include <string>
#include <omp.h>
#include <pcl/io/pcd_io.h>
#include <Boost/smart_ptr/make_shared.hpp>
#include <pcl/point_cloud.h>
#include<pcl/visualization/cloud_viewer.h>
class parafile
{
public:
    parafile();
    ~parafile();
    pcl::PointCloud<pcl::PointXYZ> cloud;
    const int MIN_ITERATOR_NUM=4;//最小并行要求
    int tn;tn表示要设置的线程数量
    void readtxt(std::string name);
///读取pcd文件
    void setThreadNum(int ITERATOR_NUM);
//多线程方案
};

cpp文件:

#include "parafile.h"
parafile::parafile()
{
    cloud.clear();
}
parafile::~parafile()
{
}
void parafile::readtxt(std::string name)
{
    std::ifstream file1;
    file1.open(name);
    if (!file1)
    {
        std::cout << "Open file failed!" << std::endl;
        exit(1);
    }
    while (!file1.eof())//检测前缀
//利用正则表达式匹配信息,这里只找了数据头和数据量,其余可以自己添加
    {
        std::regex reg1("[\u4E00-\u9FA5A-Za-z_]+"); //匹配大小字母数字和下划线
        std::regex reg2("#+");
        std::regex reg3("WIDTH");
        std::string s1;
        getline(file1, s1);
        std::smatch r1;
        if (regex_search(s1, r1, reg3))
        {
            std::stringstream strstr3;
            int cloudwidth = 0; std::string part2;
            strstr3.str(s1);
            strstr3 >> part2;
            strstr3 >> cloudwidth;
            cloud.resize(cloudwidth);

        }
        if (!(regex_search(s1, r1, reg1) || regex_search(s1, r1, reg2)))
//跳出前缀信息检测,开始读取数据
        {
            pcl::PointXYZ point;
            std::stringstream strstr2;
            strstr2.str(s1);
            float part;
            strstr2>>part;
            point.x = part;
            strstr2 >> part;
            point.y= part;
            strstr2 >> part;
            point.z = part;
            cloud[0]=point;
            break;
        }
    }
    std::string buffer;//写入字符串流
    buffer.assign(std::istreambuf_iterator<char>(file1), std::istreambuf_iterator<char>());
    std::stringstream strstr;
    strstr.str(buffer);
    std::string linestr;

    setThreadNum(cloud.size());
#pragma omp parallel for if( tn > 1) num_threads(tn)
//openmp并行计算
    for (int i = 1; i < cloud.size(); i++)
    {
        pcl::PointXYZ point;
        float part;
        strstr >> part;
        point.x = part;
        strstr >> part;
        point.y = part;
        strstr >> part;
        point.z = part;
        cloud[i] = point;
    }
    file1.close();
}
void parafile::setThreadNum(int ITERATOR_NUM)
{
    int ncore = omp_get_num_procs(); //获取执行核的数量
    int max_tn = ITERATOR_NUM / MIN_ITERATOR_NUM;
    tn = max_tn > 2 * ncore ? ncore : max_tn;
    std::cout << "启用线程数量:" << tn << std::endl;
}

debugx64结果:

这里写图片描述

这里写图片描述
releasex64结果:
这里写图片描述
这里写图片描述

第一个时间是自己写的函数,第二个时间是pcl库函数,在debug模式下效率提升的还是很高的,release下也提高了快一倍

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值