如何读取已知header和文件格式的二进制文件进行数据分析?

How to read a binary file with a known header and file format for data analysis?

我目前正在做一些基本的 analysis/trying 来制作工具来自动化我工作中一些更定量的部分。其中一项任务是分析来自本地仪器的数据,并使用该数据得出定量结论。最终目标是计算给定区域的数据覆盖百分比(区域 'x' 中的值超过值 'y' 的百分比是多少?)。但是,也有问题。

首先,我们正在查看的数据是二进制的。虽然数据的程序员指南记录了一些数据结构,但它们很少涉及如何实际利用数据在其专有程序之外进行分析。

其次,我是Python的新手。当我在 python 年前尝试编程任务时,我并没有做出任何有用的东西;我更擅长 shell 脚本编写,可以使用 html/javascript/php,并使用 Fortran 管理程序;我正在努力学习 Python 以实现多样化。

我对相关数据的了解:二进制文件包含 640 个字符长 header,由三部分组成。每个部分都是以下内容的混合体;无符号和有符号的 8、16 和 32 位整数;以及 16 位和 32 位二进制角度。在 header 之后,文件将数据的笛卡尔网格显示为 'image' 中的 'pixels'。 'image' 中的每个 'pixel' 都是一个 one-byte 无符号字符,其值介于 0 和 255 之间。'image' 是 'x by y' 的二维网格,其中next 'image' 出现在给定的字节数之后(在此数据集中,图像为 720 x 720 'pixels',因此 'images' 在 720^2 字节后分开)。

现在,我的目标只是将文件读入 python 程序并将各种“图像”分开以供检查。初始化的data/format如下:

testFile = 'C:/path/to/file/binaryFile'
headerFormat = '640c'
nBytesData = 720 * 720
# Below is commented out
inputFile = open(testfile, 'rb')

我已经能够将文件作为二进制文件读入,但我不知道如何检查它。第一直觉是尝试将其放入一个 numpy 数组中,但其他研究建议使用 struct 模块和 struct.unpack 来分解数据。根据我的阅读,以下块应该在初始 header 之后正确解压缩每个 'image',即使它不是最有效的方法:

header_size = struct.calcsize(headerFormat)
testUnpacked = []
with open(testFile, 'rb') as testData:
    headerOut = testData.read(header_size)
    print("header is: ", headerOut)
    while True:
        testContent = testData.read()
        if not testContent: break
        testArray = struct.unpack(testContent, nBytesData)
        testUnpacked.append(testArray)

问题是我不知道如何将代码设置为unpack/skip header 到二进制文件。我不认为 headerFormat = '640c' 行代码,加上接下来的几个命令来尝试格式化它的输出,是正确的。我能够输出一行程序 运行 in PyCharm,解释为“header”,下面是从第一个 [=62= 开始的输出示例]: b'\x1b\x00\x08\x00\x80\xd4\x0f\x00\x00\x00\x00\x00\x1a\x00\x06\x00@\x01\x00\x00\x00\x00\x00\x00\x03\x00\x02\x00\x00\x00\x00\x00}\t\x0

之后,我得到一个错误,指出有一个嵌入的空字符阻止数据保存到指定的数组。

我参考的其他问题以尝试弄清楚如何读取数据:

Reading a binary file with python Reading a binary file into a struct

主要问题如下:

根据此描述,很难说如何阅读 header,因为这取决于其特定结构。应该可以阅读文件的其余部分。

首先将文件读取为字节数组:

with open(testFile, 'rb') as testData:
    data = testData.read()

len(data) 会给出字节数。假设 header 包含少于 720^2 个字节,其余字节被细分为每个 720^2 个字节的图像,len(data) 除以 720^2 的提示将给出 header:

的长度
len_header = len(data) % 720**2

然后您可以忽略 header 并将剩余的字节转换为整数:

pixels = [b for b in data[len_header:]]

接下来,您可以使用 numpy 将此列表重新排列为具有 720^2 列的二维数组,以便每行由单个图像的像素组成:

import numpy as np

images = np.array(pixels).reshape(-1, 720**2)

每个图像现在都可以作为 images[i] 访问,其中 i 是行的索引。这是一个一维数组,所以要把它做成一个二维结构表示图像再reshape:

images[i].reshape(720, 720)  

最后,你可以使用matplotlib显示图像并检查它看起来是否正确:

import matplotlib.pyplot as plt

plt.imshow(images[i].reshape(720, 720), cmap="gray_r")
plt.show()