我正在使用一个外部库,它输出一个带有数据类型“>u2”(大端、无符号、2 字节/16 位)的 numpy 数组。在我的例子中,只有 10 位有效(输出来自实际输出 little-endian 的硬件设备)。例如:
65283是最大值,对应bin(65283)=0b1111111100000011作为直接的python输出,或者00001111111111如果它很小-字节序。
我想将库的输出范围 0-65283 映射到 10 位硬件功能有意义的范围 0-1023。我该怎么做?
我试过以下方法:
>>>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 位小尾数法),我可以获得 6528 的二进制形式,在中间添加 3 个零,然后进行字节交换。但是 1) 这是非常乏味的(按元素完成)和 2) 零填充不一致(例如 652 需要 6 个以上的零)。
有没有内置的方法来做到这一点?看起来 struct 模块(w/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 相机!),我猜这被证明是微不足道的......
请您参考如下方法:
import struct
struct.pack('<H',val)
或者,更好的是:
>>> arr.byteswap().newbyteorder()
array([65283, 6528, 652, 65, 6], dtype=uint16)
>>> arr.byteswap().newbyteorder().tostring()
'\x03\xff\x80\x19\x8c\x02A\x00\x06\x00'
