我正试图使用numpy将二进制字符串转换为Python中的图像,但我很难找到一种用非常规位分布来处理它的好方法(据我所知)。
这些都是如何以及如何转换的具体细节。16位纹理瓷砖(256*256)。每个bitu16表示一个像素,其颜色为ARGB,MSB-to-LSB: 1位透明度。
5位红色通道5位绿色通道5位蓝色通道
Numpy并不真正支持任何1位或5位的东西。我尝试用不同的argb频道设置一个np.dtype,但没有任何成功。解包位似乎不能在uint16上工作,所以在这种情况下,我可能不得不将其分割成2 uint8 8。
dt = np.dtype([('a', np.bool_), ('r', np.half), ('g', np.half), ('b', np.half)])
data = data.read(131072)
dataFromBuffer = np.frombuffer(data, dtype=dt)
img = dataFromBuffer.reshape(256, 256)发布于 2020-07-24 16:16:29
以下是如何使您的方法有效:
# make small example
x = np.random.randint(0,1<<16,size=(5,5),dtype=np.uint16)
# set up dtype
dt = np.dtype([*zip('argb',(bool,*3*(np.uint8,)))])
# bit of bit twiddling
def unpack_argb(x):
out = np.empty(x.shape,dt)
for i,ch in enumerate(reversed('argb')):
out[ch] = (x>>(5*i))&31
return out
def pack_argb(x):
out = x['a'].astype(np.uint16)
for ch in 'rgb':
out <<= 5
out += x[ch]&31
return out
# check round trip
np.all(x == pack_argb(unpack_argb(x)))
# True更新:
def argb16_to_rgba32(x):
out = np.empty(x.shape+(4,),np.uint8)
out[...,3] = (x>>8)&0x80
out[...,0] = (x>>7)&0xf8
out[...,1] = (x>>2)&0xf8
out[...,2] = (x<<3)&0xf8
return out
def rgba32_to_argb16(x):
x16 = x.astype(np.uint16)&0xf8
out = (x16[...,3]&0x80)<<8
out += x16[...,0]<<7
out += x16[...,1]<<2
out += x16[...,2]>>3
return out发布于 2020-07-24 15:04:42
在这种情况下,对于缺少位numpy位级支持,您是正确的。一种处理双边投资条约的高级(但有功能的)方法可以如下所示:
image_16_bit = 123 # A 16bit integer.
bits = '{:016b}'.format(image_16_bit)
transparency = int(bits[0], 2)
red_channel = int(bits[1:6], 2)
green_channel = int(bits[6:11], 2)
blue_channel = int(bits[11:], 2)
print(transparency, red_channel, green_channel, blue_channel) # 0 0 3 27您可以在所有ints上运行此操作,然后收集单个信道值。最后,您可以将其转换为numpy数组,以便将图像转换为numpy数组。
https://stackoverflow.com/questions/63075984
复制相似问题