在 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')
我想知道如何在 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')