【问题标题】:How to set the precision while writing binary file in c++?用c ++编写二进制文件时如何设置精度?
【发布时间】:2021-01-24 15:56:09
【问题描述】:

我需要将 .pcd 格式的数据转换成 .bin 格式(数据是激光雷达点云)。所以我试图以精确的行对齐顺序写入数据。但我完全可以设置精度。完成转换后,我读取了 .bin 文件。数据仍然不是预定义的精度格式。 代码如下:

#include <iostream>           
#include <pcl/io/pcd_io.h>      
#include <pcl/point_types.h>     
using namespace std;


int main(){
    std::string bin_path = "/home/dummy/data1/pcd_bin/bin/";
    std::string out_file = bin_path+"100.bin";
    pcl::PointCloud<pcl::PointXYZ> cloud;
    for (int v=0; v<1000; ++v)
    {
        pcl::PointXYZ newPoint;
        newPoint.x = (rand() * 100.0) / RAND_MAX;
        newPoint.y = (rand() * 100.0) / RAND_MAX;
        newPoint.z = (rand() * 100.0) / RAND_MAX;
        //newPoint.intensity = (rand() * 100.0) / RAND_MAX;
        cloud.points.push_back(newPoint);
    }
       //Create & write .bin file
      ofstream  bin_file(out_file.c_str(),ios::out|ios::binary|ios::app);
      if(!bin_file.good()) cout<<"Couldn't open "<<out_file<<endl;  


      for (size_t i = 0; i < cloud.points.size (); ++i)
      {
        bin_file<<std::setprecision(5);
        bin_file.write((char*)&cloud.points[i].x,3*sizeof(float)); 
       // bin_file.write((char*)&cloud.points[i].intensity,sizeof(float));
        //cout<<    cloud->points[i]<<endl;
      }
}

如您所见,将值写入 float32 中的二进制文件(假设,在阅读了一些 stackoverflow 问题之后)并在 python 代码中仅将它们作为 float32 读取。

二进制文件中的预期保存格式:

[84.0187 39.438 78.309]

[79.844 91.164 19.755]

[33.522 76.822 27.777]

[55.396 47.739 62.887]

[36.478 51.340 95.222]

但二进制文件中实际保存的格式与原始格式相同:

[84.01877 39.438293 78.30992]

[79.844 91.164734 19.755136]

[33.522274 76.82296 27.777472]

[55.396996 47.739704 62.887093]

[36.478447 51.34009 95.22297]

读取二进制文件的Python代码:

 raw_lidar_o_crop = np.fromfile(100.bin, dtype=np.float32).reshape((-1, 4))
    print("ouster new ")
    with open("ouster_new_intensity2.txt", "w") as text_file:
        for i in range(len(raw_lidar_o_crop)):
           print(f"ouster points cropped : {raw_lidar_o_crop[i]}", file=text_file)

PS:预期的格式值是虚拟的。我在 python 中读取了二进制文件并将值保存在 .txt 文件中以进行可视化。

PS1:需要 pcl 库来重现结果。

PS2:我还有其他用 C++ 精确编写的二进制文件,所以我正在使用 float32 类型的 python 读取这些文件。

提前致谢

【问题讨论】:

  • 在写入原始二进制数据时,您不需要(或实际上应该)设置精度。仅在向用户显示数据时设置精度。此外,您似乎遇到的问题是从文件转换二进制数据的程序没有使用与文件中实际存储的值相同的浮点格式。请尝试创建一个minimal reproducible example 写入数据的程序(如果必须的话,硬编码值)和读取文件并呈现它的 Python 脚本。
  • 说真的,你用随机数测试你的程序吗?您需要使用诸如写入 2 行 0 之类的东西进行测试。thecn 检查文件大小并尝试在其他程序中读取它。一旦可行,请在两行上尝试类似 1, 0, 0 的内容。这样,您可以更轻松地分析实际文件内容。
  • @Phil1970,请看代码,二进制文件以float类型编写。这不仅仅是一个假设。更多关于 c++ 中浮点数的信息stackoverflow.com/questions/21198948/…
  • 精度仅在您使用&lt;&lt; 运算符作为文本编写时使用。您感知的“错误”只是一个表现性错误,您的 Python 脚本在打印值时没有设置所需的精度。在文件中,值存储为原始二进制数据,单精度浮点数的按位副本,您无法(或应该!)采取任何措施来防止这种情况发生。
  • 由于您正在编写原始二进制数据,您无法设置精度。精度是纯粹的表现形式。如果你想round 存储在文件中的值,你必须在写入之前明确地为每个数字做它。

标签: c++ fstream binaryfiles


【解决方案1】:

正如@Some 程序员在上述 cmets 中所建议的那样,只有当我们需要精确地呈现二进制文件中的值时,我们才能使用 std::setprecision。为了首先设置精度,我们需要将值精确存储到 .txt 文件中,然后将 .txt 中的值存储到 .bin 文件中。

【讨论】:

  • 不,您不需要为此进行文本文件往返。如果您想这样做,请在应用内四舍五入您的值。
  • @AsteroidsWithWings,我试过你的方法,它也有效,谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-25
  • 2015-11-29
  • 2017-10-20
  • 2012-02-12
  • 2021-06-13
相关资源
最近更新 更多