简体   繁体   中英

Converting float32 to bit-equivalent int32

The Pillow module in Python insists on opening a 32-bit/pixel TIFF file I have as if the pixels were of type float32, whereas I believe the correct interpretation is unsigned int32. If I go ahead and load the data into a 640x512 array of type float32, how can I retype it as uint32 while preserving the underlying binary representation?

In Fortran and C, it's easy to have pointers or data structures of different type pointing to the same block of physical memory so that the raw memory contents can be easily be interpreted according to whatever type I want. Is there an equivalent procedure in Python?

Sample follows (note that I have no information about compression etc.; the file in question was extracted by a commercial software program from a proprietary file format):

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]

Assuming you have im.mode originally equal to F , you can force Pillow to re-load the same data under a different mode (an very unusual desire indeed) in a somewhat hackish way like that:

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

More generally (outside the context of PIL), whenever you encounter the need to deal with raw memory representation in Python, you should usually rely on numpy or Python's built-in memoryview class with the struct module.

Here is an example of reinterpreting an array of numpy float32 as int32 :

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

Here is an example of doing the same using 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')

The answer, in this case, is that Pillow is loading the image with the correct type (float 32) as specified in the image exported from the thermal camera. There is no need to cast the image to integer, and doing so would cause an incorrect result.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM