将十六进制值的行按列转换为二进制

4 投票
2 回答
832 浏览
提问于 2025-04-18 05:27

我正在处理来自一个串行设备的数据,这个设备输出的数据格式非常有趣。这个设备有一个256x256的像素阵列,每个像素都有一个14位的值,通过移位寄存器读取。

为了展示这个格式,我将用一个每个像素有6位值的例子来说明:

                             'Pixel #'
        0-8   9-16   17-24  25-32  33-40  41-48  48-56  57-64 ... 256
        --------------------------------------------------------------
    0   255    255    255    255    255    255    255    255  ...
    1   127    255    255    255    255    255    255    255  ...
    2   255    255    255    255    255    255    255    255  ...
    3   255    255    255    255    255    255    255    255  ...
    4   255    255    255    255    255    255    255    255  ...
    5   255    255    255    255    255    255    255    255  ...

    Note that the 2nd row starts with a value of 127

要获取第一个像素(像素#0)的6位值,需要进行以下操作:

  1. 每一行的值都需要被视为它的二进制/位的等价物
  2. 从上到下读取,每行对齐的位,从每行向下6行(为了得到6位的输出值),就能得到那个像素的值

也就是说:

                             'Pixel #'
          0-8     9-16     17-24    25-32  ...  256
        --------------------------------------------------------------
    0   *1*1111111 11111111 11111111 11111111 ...
    1   *0*1111111 11111111 11111111 11111111 ...
    2   *1*1111111 11111111 11111111 11111111 ...
    3   *1*1111111 11111111 11111111 11111111 ...
    4   *1*1111111 11111111 11111111 11111111 ...
    5   *1*1111111 11111111 11111111 11111111 ...

    Note that the 2nd row had a value of 127, which is 01111111 in binary
    --> Pixel 0 = 101111 = 47

现在,重复这个过程遍历所有256列,然后再向下移动到下一组6行,继续重复。

实际的输出需要是一个256x256的像素值数组。我需要处理的实际数据集是每个像素14位的,总共有3584x32(14位 * 256像素 = 3584行……而32字节 * 8位/字节 = 32字节宽)。

处理这个数据集的最佳方法是什么?另外,速度非常重要,有没有一些可以利用的高速函数?

感谢你的帮助 - 谢谢!


编辑:

关于所需速度的问题 - 理想情况下,我希望每秒至少执行10次,因为数据以每秒60次的速度到达。因此,我认为我需要避免常见的“连接”和字符串操作,因为我认为这些操作比较慢。

再说一次,真实的数据集(3584x32)每个像素有14位,所以是3584x32。

这是我正在使用的函数,采用Joran的方法,当提供真实数据集时,执行大约需要2.6秒:

def GetFrame(RawData):
    if np.shape(RawData) == (3584, 32):
        ProcessedData = np.zeros((256, 256), dtype='int16')
        data_blocks = [RawData[d:d+14] for d in range(0, 3584, 14)]
        for p in range(256):
            data_bin_rows = ["".join(map(lambda val:"{0:08b}".format(val,), row)) for row in data_blocks[p]]
            ProcessedData[p][:] = [int("".join(v),2) for v in zip(*data_bin_rows)]
        return ProcessedData
    else:
        return False

如何才能加快速度,缩短执行时间?谢谢!

2 个回答

1

使用numpy应该已经够快了,或者你需要用汇编语言来写这个:

import numpy
input_array = numpy.zeros((32,14,256), dtype="B")
output_array = numpy.zeros((32,8,256), dtype='int16')
for j in range(8):
    bits = (input_array[:,:,:]>>j) & 1
    for i in range(14):
        output_array[:,j,:]|= bits[:,i,:] << i
1

我读了好几遍,觉得我明白了。

data = \
"""255    255    255    255    255    255    255    255
127    255    255    255    255    255    255    255
255    255    255    255    255    255    255    255
255    255    255    255    255    255    255    255
255    255    255    255    255    255    255    255
255    255    255    255    255    255    255    255"""

data_rows = [map(int,row.split()) for row in data.splitlines()]
data_bin_rows = ["".join(map(lambda val:"{0:08b}".format(val,),row)) for row in data_rows]
pixel_values = zip(*data_bin_rows)
print pixel_values[0],"=",int("".join(pixel_values[0]),2) #pixel0

我不能确定它的速度……不过如果你不是每秒做一百万次,那应该还不错……无论如何,它应该比串行读取快很多。

撰写回答