convert raw binary 8 bit unsigned file to 16 bit u

2019-09-01 07:44发布

I have an image file that is a grayscale 8 bit unsigned integer raw binary file and I need to convert it to a 16 bit file and keep it in raw binary. It is relatively easy to go from 16 to 8 because you are just cutting off information but I am curious how I can go the other way.

To be specific I have an image that is going into a processor written in C++ and the processor only takes 16 bit unsigned integer image files so I need to convert my 8 bit file into a 16 bit one. I have been doing some processing with the Python Imaging Library but haven't been able to find this specific function.

UPDATE:

I followed cgohlke's advice and have the following code that seems logical but it is not accepting my 'final' variable because of the following error:

Traceback (most recent call last):
  File "C:\Users\Patrick\workspace\colorCorrect\src\editGrayscale.py", line 36, in <module>
    u1 = np.fromfile(final, 'uint8')
TypeError: file() argument 1 must be encoded string without NULL bytes, not str

My code:

import Image
import numpy as np

fileName = raw_input("Enter a file name: ")
saveFile = raw_input("Enter a new save file name: ")

with open(fileName, 'rb') as f:
    im = Image.fromstring('L', (3032, 2016), f.read()) # also try 'L;16B', 'I;16', and 'I;16B'
    changed = im.point(lambda i: i/.4)    

final = changed.tostring()

np.arange(256).astype('uint8').tofile(final)

u1 = np.fromfile(final, 'uint8')
u2 = u1.astype('uint16')
u2 *= 257  # scale to full 16 bit range
u2.tofile(saveFile)

2条回答
爷的心禁止访问
2楼-- · 2019-09-01 08:10

The struct module would let you do that kind of conversion, although you would need to take care on your own of the reading and writing to file, but if you had it stored in 'data', this should work:

    import struct

    uint8 = 'B'
    uint16 = 'H'

    data = struct.pack(uint16 * len(data),
                       *struct.unpack(uint8 * len(data), data))

Adding a '>' or '<' will let you control whether your 16 bit stream is little-endian or big-endian, i.e.

    data = struct.pack('>' + uint16 * len(data),
                       *struct.unpack(uint8 * len(data), data))

would make it big-endian.

查看更多
我命由我不由天
3楼-- · 2019-09-01 08:12
import numpy as np

# create example file
np.arange(256).astype('uint8').tofile('uint8_file.bin')

# read example file and convert to uint16
u1 = np.fromfile('uint8_file.bin', 'uint8')
u2 = u1.astype('uint16')
u2 *= 257  # scale to full 16 bit range
u2.tofile('uint16_file.bin')
查看更多
登录 后发表回答