使用深度学习进行点云匹配(四)

承接上一篇文章《使用深度学习进行点云匹配(三)》。因为之前提到过因为硬件原因我自己无法去训练3Dmatch描述子,因此接下来我的任务是尝试应用这个模型。我更换了原来的点云数据,新数据来自于斯坦福大学的3D扫描数据库,网址为;http://graphics.stanford.edu/data/3Dscanrep/,我使用了其中赫赫有名的兔子模型。

点击蓝字进行下载,解压后会发现里面有很多ply文件,文件名中的数字代表角度,比如045就是45°拍摄的。我们使用000和045两个点云文件,替换掉之前的single-depth-1.ply和single-depth-2.ply,然后直接按照之前的步骤编译运行就好了。当然是不可能的,事情没有这么简单!!!

之前的single-depth-1.ply和single-depth-2.ply的点云文件是按照二进制方式存储的,可以用notepad++打开如下:

其中第二行的format binary_little_endian 1.0指明了点云的文件格式,常用的有三种,大家可以自己百度,这一种看前缀就知道是二进制的存储。可以看到下面的都是乱码。再打开我们的兔子点云文件:

可以看到这里的格式是format ascii 1.0,是使用ascii进行编码的,没错,如果你仔细阅读斯坦福数据集的介绍,他们就说明了:For convenience, we have represented most of these PLY files in their ASCII formats. Choosing ASCII makes it possible for someone unfamiliar with it to get a feel for the file format, and it avoids the problem of using the correct big-endian vs. little-endian byte orders. 意思就是我们大部分都是用ASCII编码,因为二进制编码有两种格式,避免你读取的时候造成错误。

那么这就要求我们去修改demo.cu文件。我们打开文件,找到main函数,需要修改以下两个部分:

int num_pts = 0;
  for (int line_idx = 0; line_idx < 7; ++line_idx) {
    std::string line_str;
    std::getline(pointcloud_file, line_str);
    if (line_idx == 2) {
      std::istringstream tmp_line(line_str);                 //istringstream 是从字符串读   https://blog.csdn.net/sinat_30071459/article/details/50755710
      std::string tmp_line_prefix;                            //输出前面的两部分 
      tmp_line >> tmp_line_prefix;                            //输出element              
      tmp_line >> tmp_line_prefix;                            //输出vertex
      tmp_line >> num_pts;                                  //点云的数目(对于点云1是257179)
    }

在这里要将7改为24,将下面的line_idx=2中的2改为7,为什么要做这个修改呢,首先要明白这部分代码的作用是什么。这部分是读ply文件的头部,也就是header,如果你百度ply文件格式的话就会知道,header的作用就是介绍ply文件的一些配置。因为我们是从文件中读取,因此这部分先读出来我们才能读下面的数据。而中间部分的代码其实是为了读出点云中的点的数目,如果你往前翻看两个文件的截图,就会明白一个在第三行(下标是2)的第三个,是252179,而第二个是第18行(下标是17)的第三个,是40256。这就是以上修改的原因。

 float * pts = new float[num_pts * 3]; // Nx3 matrix saved as float array (row-major order)   Nx3矩阵保存为float数组(行主顺序)
  pointcloud_file.read((char*)pts, sizeof(float) * num_pts * 3);
  pointcloud_file.close();
//pointcloud_file.read((char*)pts, sizeof(float) * num_pts * 3);
    for(int i=0;i<num_pts*3; i++)
    {
        float a;
        pointcloud_file>>pts[i];
        //std::cout<<pts[i]<<std::endl;

    }

我们将其中的读文件那一行改为下面的读取方式,可以看出上面的读取方式是使用了read函数,这里其实就是c++中的ifstream函数,这个读取文件流可以读取二进制也可以读取文本文件,read函数就是用来读取二进制文件,而下面的直接使用>>是用来读取文本文件的,这就是改写的原因。

以上这两点是我通过将代码改成标准c++后实验出来的,最后的确可以训练出描述子,完成匹配。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值