我必须在前面加上这个,因为我有一个使用bitshift和putpixel的工作方法,但它非常慢,而且我希望利用numpy来加速这个过程。我相信我很亲密,但并不完全在那里。有了我认为应该工作的时间,我看到时间改善0.3秒,因此我的动机。
当前的工作代码:
buff # a binary set of data
im = Image.new("RGBA",(xdim,ydim))
for y in xrange(ydim):
for x in xrange(xdim):
px = buff[x*y]
# the 255 is for the alpha channel which I plan to use later
im.putpixel((x,y),(px&0xF800) >> 8, (px&0x07E0) >> 3, (px&0x001F) <<3, 255))
return im
我正在努力获得工作的代码如下:
im16 = numpy.fromstring(buff,dtype=numpy.uint16) #read data as shorts
im16 = numpy.array(im16,dtype=numpy.uint32) #now that it's in the correct order, convert to 32 bit so there is room to do shifting
r = numpy.right_shift(8, im16.copy() & 0xF800)
g = numpy.right_shift(3, im16.copy() & 0x07E0)
b = numpy.left_shift( 3, im16 & 0x001F)
pA = numpy.append(r,g)
pB = numpy.append(b,numpy.ones((xdim,ydim),dtype=numpy.uint32) * 0xFF) #this is a black alpha channel
img = numpy.left_shift(img,8) #gives me green channel
im24 = Image.fromstring("RGBA",(xdim,ydim),img)
return im24
所以最后的问题是,通道没有合并,我不相信我应该做最后一位移位(请注意,如果我没有按8位移位,我会得到红色通道)。有关如何正确组合所有内容的帮助将非常感激。
import numpy as np
arr = np.fromstring(buff,dtype=np.uint16).astype(np.uint32)
arr = 0xFF000000 + ((arr & 0xF800) >> 8) + ((arr & 0x07E0) << 5) + ((arr & 0x001F) << 19)
return Image.frombuffer('RGBA', (xdim,ydim), arr, 'raw', 'RGBA', 0, 1)
不同之处在于你需要将它作为MSB(ALPHA,B,G,R)LSB计数器直接从putpixel打包,但它有效,并且运行良好
答案 0 :(得分:3)
警告:以下代码尚未检查过,但我认为这可以做你想要的(如果我正确理解了所有内容):
import numpy as np
arr = np.fromstring(buff,dtype=np.uint16).astype(np.uint32)
arr = ((arr & 0xF800) << 16) + ((arr & 0x07E0) << 13) + ((arr & 0x001F) << 11) + 0xFF
return Image.frombuffer('RGBA', (xdim,ydim), arr, 'raw', 'RGBA', 0, 1)
我将所有通道组合成32位,完成所有位移。最左边的8位是红色,接下来的8位是绿色,接下来的是8位蓝色,最后8位是alpha。移位数字似乎有点奇怪,因为我将16位格式的转换结合在一起。此外,我正在使用frombuffer
,因为我们希望利用Numpy使用的缓冲区而不是先转换为字符串。
查看this page可能有所帮助。在我看来,这并不是超级棒,但根据我的经验,这就是PIL的用武之地。文档实际上不是非常用户友好,事实上我经常发现它令人困惑,但我不打算自愿重写它,因为我没有使用PIL。
答案 1 :(得分:1)
如果你想适当地进行缩放,这里有一个更好的解决问题的方法。
FROM_5 = ((np.arange(32, dtype=numpy.uint16) * 255 + 15) // 31).astype(numpy.ubyte)
FROM_6 = ((np.arange(64, dtype=numpy.uint16) * 255 + 31) // 63).astype(numpy.ubyte)
data = numpy.fromstring(buff, dtype=numpy.uint16)
r = Image.frombuffer('L', shape, FROM_5[data >> 11], 'raw', 'L', 0, 1)
g = Image.frombuffer('L', shape, FROM_6[(data >> 5) & 0x3F], 'raw', 'L', 0, 1)
b = Image.frombuffer('L', shape, FROM_5[data & 0x1F], 'raw', 'L', 0, 1)
return Image.merge('RGB', (r, g, b))