在 python 中加载 64 位原始图像文件

Load 64-bit raw image file in python

我想知道如何在 python 中加载 this image。我可以使用图片设置在 imageJ 中加载它,但我不知道如何在 python.

中加载它

简而言之:

import numpy as np
import matplotlib.pyplot as plt

fname = 'Downloads/image.bdat'
with open(fname, 'r') as infile:
    infile.seek(4)
    data = np.fromfile(infile, dtype='>f8').reshape(1024, 256)

fig, ax = plt.subplots()
im = ax.imshow(data, cmap='gray')
ax.set(xticks=[], yticks=[])
fig.colorbar(im)
fig.savefig('figure_1.png', bbox_inches='tight')
plt.show()


让我备份并解释发生了什么。

首先,要将文件中的 "raw" 数据读入 numpy 数组,使用 numpy.fromfile 和适当的数据类型,然后重塑它。

您拥有我们需要的大部分信息(形状、数据开始的文件偏移量和数据类型)。然而,还有一些其他的事情我们需要知道:数据的字节顺序和数组的顺序(通常是 C 或 F 顺序)。

要以 numpy.fromfile 的偏移量读取数据,最简单的方法是在调用函数之前 seek 到该偏移量。在您的情况下,您在数据开始之前在文件中有 4 个字节的偏移量(大概前 4 个字节是图像 size/shape 或其他内容)。

这给了我们:

fname = 'Downloads/image.bdat'
with open(fname, 'r') as infile:
    infile.seek(4)

接下来使用fromfile。但是,您可能尝试的第一件事会产生奇怪的结果:

fname = 'Downloads/image.bdat'
with open(fname, 'r') as infile:
    infile.seek(4)
    data = np.fromfile(infile, dtype=np.float64).reshape(1024, 256)

这些值似乎不合理,我们得到的图像有噪声。我们可能使用了错误的数据类型。根据您的信息,我们知道它是某种 64 位浮点数,因此最有可能的情况是 endianness 存在差异。现在大多数系统都是小端,但是很多文件格式出于各种原因使用大端。在 numpy 中,您可以通过切换到 dtypes 的字符串规范并使用 > 来指示 big-endian 来指定 big-endian dtype。 (< 表示小端,= 指定使用本机字节顺序)

这让我们完成了剩下的事情:

fname = 'Downloads/image.bdat'
with open(fname, 'r') as infile:
    infile.seek(4)
    data = np.fromfile(infile, dtype='>f8').reshape(1024, 256)

请注意,如果您觉得它更具可读性,我们也可以使用 byteswap 方法:

fname = 'Downloads/image.bdat'
with open(fname, 'r') as infile:
    infile.seek(4)
    data = np.fromfile(infile, dtype=np.float64).reshape(1024, 256)
    data = data.byteswap()

通常我们需要最后一条信息:ordering of the array。对于二维数组,只有 C 和 Fortran 排序。对于高维数组,技术上还有其他顺序,但几乎从未使用过。

在这种情况下,它是 C 序的(或 "row-major"),因此可能的第一个猜测 (.reshape(nrows, ncols)) 是正确的。如果它是 fortran 顺序的,我们将交换 reshape 中的数字或行和列,然后转置它。

fname = 'Downloads/image.bdat'
with open(fname, 'r') as infile:
    infile.seek(4)
    data = np.fromfile(infile, dtype='>f8').reshape(256, 1024).T

或者,为了更好的可读性,您可以这样做:

data = np.fromfile(infile, dtype='>f8').reshape(1024, 256, order='F')