【问题标题】:Converting float32 to bit-equivalent int32将 float32 转换为位等效的 int32
【发布时间】:2019-04-28 18:47:09
【问题描述】:

Python 中的 Pillow 模块坚持打开我拥有的 32 位/像素 TIFF 文件,就好像像素是 float32 类型一样,而我相信正确的解释是 unsigned int32。如果我继续将数据加载到 float32 类型的 640x512 数组中,如何在保留底层二进制表示的同时将其重新键入为 uint32?

在 Fortran 和 C 中,很容易让不同类型的指针或数据结构指向同一个物理内存块,以便可以根据我想要的任何类型轻松解释原始内存内容。 Python中是否有等效的程序?

示例如下(请注意,我没有关于压缩等的信息;有问题的文件是由商业软件程序从专有文件格式中提取的):

from PIL import Image

infile = "20181016_071207_367_R.tif"        
im = Image.open(infile)

data = np.array(im.getdata())
print(data)

[ -9.99117374 -10.36103535 -9.80696869 ... -18.41988373 -18.35027885 -18.69905663]

【问题讨论】:

  • 您能否添加一个可重现的示例,或者至少为您的问题添加更多细节?它是压缩的 TIFF 图像吗?你是如何打开图片的,你怎么知道 Pillow 正在以浮动方式打开图片?
  • 查看添加的示例代码。
  • 但请注意,我的问题无论如何都是通用的(不依赖于 TIF 文件):一般来说,如何改变 Python 数据结构中二进制数据的解释(例如,一个numpy数组)?
  • 经过一些测试,似乎 32 位浮点数是灰度图像的有效 TIFF 格式。 TIFF 文件是否可能实际上是浮动的并且 Pillow 和 numpy 正在做正确的事情?尝试绘制数组以查看它是否再现了图像。
  • 至于像在 C 中那样转换数据结构,您可以使用 Python struct 模块。

标签: python image types binary type-conversion


【解决方案1】:

假设您的 im.mode 最初等于 F,您可以强制 Pillow 在不同的模式下重新加载相同的数据(确实是一个非常不寻常的愿望),这种方式有点像这样:

imnew = im.convert(mode='I')
imnew.frombytes(im.tobytes())

更一般地说(在 PIL 的上下文之外),每当您遇到需要在 Python 中处理原始内存表示时,您通常应该依赖 numpy 或 Python 的内置 memoryview 类和 struct 模块.

这是一个将 numpy float32 数组重新解释为 int32 的示例:

a = np.array([1.0, 2.0, 3.0], dtype='float32')
a_as_int32 = a.view('int32')

这是使用memoryview 执行相同操作的示例:

# Create a memory buffer
b = bytearray(4*3)

# Write three floats
struct.pack_into('fff', b, 0, *[1.0, 2.0, 3.0])

# View the same memory as three ints
mem_as_ints = memoryview(b).cast('I')

【讨论】:

    【解决方案2】:

    在这种情况下,答案是 Pillow 正在使用从热像仪导出的图像中指定的正确类型(浮点 32)加载图像。无需将图像转换为整数,这样做会导致错误的结果。

    【讨论】:

    • TIF 图像是我的问题的上下文,但不是问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-28
    • 1970-01-01
    • 2020-09-12
    • 1970-01-01
    • 1970-01-01
    • 2023-01-03
    • 2011-03-02
    相关资源
    最近更新 更多