2017-03-02 322 views
1

我有一个摄像机的原始数据,它是mono12packed格式。这是一种隔行位格式,用3个字节存储2个12位整数以消除开销。明确每个3个字节的内存布局是这样的:用python轻松解开mono12packed bitstring格式

Byte 1 = Pixel0 Bits 11-4 
Byte 2 = Pixel1 Bits 3-0 + Pixel0 Bits 3-0 
Byte 3 = Pixel1 Bits 11-4 

我有一个文件,其中所有的字节可以使用二进制读来读取,让我们假设它被称为binfile

要获得从文件中PixelData取出我做的:

from bitstring import BitArray as Bit 

f = open(binfile, 'rb') 
bytestring = f.read() 
f.close() 
a = [] 
for i in range(len(bytestring)/3): #reading 2 pixels = 3 bytes at a time 
    s = Bit(bytes = bytestring[i*3:i*3+3], length = 24) 
    p0 = s[0:8]+s[12:16] 
    p1 = s[16:]+s[8:12] 
    a.append(p0.unpack('uint:12')) 
    a.append(p1.unpack('uint:12')) 

它的工作原理,但可怕的慢,我想更有效地做到这一点,因为我必须做的是一个巨大的数据量。

我的想法是,通过一次读取多于3个字节,我可以在转换步骤中省下一些时间,但我无法想象如何做到这一点。

另一个想法是,由于位是4的包,也许有办法处理半字节而不是位。

数据例如:

的字节

'\x07\x85\x07\x05\x9d\x06' 

导致

[117, 120, 93, 105] 

回答

0

你试过位运算的数据?也许这是一个更快的方法:

with open('binfile.txt', 'rb') as binfile: 
    bytestring = list(bytearray(binfile.read())) 


a = [] 

for i in range(0, len(bytestring), 3): 
    px_bytes = bytestring[i:i+3] 
    p0 = (px_bytes[0] << 4) | (px_bytes[1] & 0x0F) 
    p1 = (px_bytes[2] << 4) | (px_bytes[1] >> 4 & 0x0F) 
    a.append(p0) 
    a.append(p1) 

print a 

这也输出: [117, 120, 93, 105]

希望它能帮助!

+0

差不多200倍!太棒了,谢谢你! – Dschoni

+0

您能否解释一下,在按位运算符中发生了什么,以及为什么这会起作用? – Dschoni

+0

当然我可以,但我想看看维基百科https://en.wikipedia.org/wiki/Bitwise_operation等来源更合理。 – Szabolcs