【发布时间】:2012-05-09 20:55:26
【问题描述】:
我正在使用一个外部库,该库输出一个数据类型为“>u2”(大端、无符号、2 字节/16 位)的 numpy 数组。就我而言,只有 10 位有效(输出来自实际输出 little-endian 的硬件设备)。例如:
65283是最大值,对应bin(65283)=0b1111111100000011作为直接python输出,或者00001111111111如果是little-endian。
我想将库输出的0-65283 范围映射到0-1023 范围,这对10 位硬件功能来说是有意义的。我该怎么做?
我尝试了以下方法:
>>>import numpy as np
>>>arr=np.array([65283, 6528, 652, 65, 6], dtype=">u2")
>>>print arr/64 # same as arr/2**6 and arr >> 6
[1020 102 10 1 0]
>>>print arr.byteswap()
[ 1023 32793 35842 16640 1536]
但这并没有给出预期的结果。我发现bin() 函数以大端格式输出(在这个 numpy 数组的情况下),但省略了填充零。例如,65283 表示所有 16 位,但 bin(6528)=0b1100110000000(中间缺少 3 个零)。
为了解决这个问题(并返回一个 10 位 little-endian 数字),我可以得到 6528 的二进制形式,在中间添加 3 个零,然后进行字节交换。但是 1)这是非常繁琐的(每个元素都完成)和 2)零填充不一致(例如 652 需要另外 6 个零)。
有没有内置的方法来做到这一点?看起来struct 模块(带有pack 和或unpack)可能会有所帮助,但它现在对我来说是希腊语。任何帮助将不胜感激!
编辑:
相信我已经找到了罪魁祸首。我上面的示例(从 65238 的相机/库中获取实际值并假设半任意附加值,显然只是删除了最右边的数字)不会发生!例如6528 要求最低有效字节中的 1 (00011001**1**0000000) 永远不会发生(只有 10 位有效)。
经过进一步检查,我的代码中的一个简单的arr.byteswap()(其中arr 具有合法值)有效。例如:
>>>arr=np.array([12288, 13312, 12800, 12032, 13312, 13824, 65283, 0, 7936], dtype=">u2")
>>>arr.byteswap()
array([ 48, 52, 50, 47, 52, 54, 1023, 0, 31], dtype=uint16)
我从来没有在我的代码中真正尝试过,只是在这个虚构的例子中。对困惑感到抱歉。但希望它可以帮助其他人解决这个问题(特别是如果你使用 Basler 相机!),我猜这结果是微不足道的......
【问题讨论】:
标签: python numpy bit-manipulation