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

时间:2015-02-06 01:08:33

标签: python numpy scipy python-imaging-library

我想知道如何在python中加载this image。我可以使用图片设置在imageJ中加载它,但我无法弄清楚如何在python中加载它。

enter image description here

1 个答案:

答案 0 :(得分:3)

简而言之:

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()

enter image description here


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

首先,要将“原始”数据从文件读入numpy数组,请使用具有相应dtype的numpy.fromfile,然后重新整形。

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

要在numpy.fromfile的偏移处读取数据,在调用函数之前最简单地seek到该偏移量。在您的情况下,在数据开始之前,您在文件中有4个字节的偏移量(可能前4个字节是图像大小/形状或其他东西)。

这给了我们:

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)

enter image description here

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

这让我们完成剩下的工作:

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。对于2D阵列,只有C和Fortran排序。对于更高维数组,技术上还有其他排序,但它们几乎从未使用过。

在这种情况下,它是C-ordered(或“row-major”),因此可能的第一次猜测(.reshape(nrows, ncols))正常工作。如果它是fortran命令,我们将交换重塑中的数字或行和列,然后转置它。

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')