将大块位图转换为 3 维位图

2024-05-05

Problem

我需要这个大量的数据作为输入(对于基于C的arduino)。

这是上面示例中所需格式的大量数据:

const byte bitmap[8][8] = {
    {0xFF, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xFF},
    {0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81},
    {0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81},
    {0x81, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x81},
    {0x81, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x81},
    {0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81},
    {0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81},
    {0xFF, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xFF},
};

正如你所看到的,上面大量使用了十六进制,例如二进制中的0xFF是0b11111111

这是有道理的:想象一下通过 z 轴从显示器发出的比特形成一条 8 个正方形的整条线。

如果您将字节分解为位并想象这些位形成层(具有并行位),那么您可以看到这个巨大的块代表了 3D 立方体(如上面的介绍所示)。 *或者,您可以将其可视化为通过 z 轴的整个字节 - 无论哪种方式,您最终都会得到介绍中的 3D 立方体。

我需要一个函数来转换大量数据,使得:

Input:

       [[63, 62, 61, 60, 59, 58, 57, 56, 48, 40, 32, 24, 16, 8, 0, 1, 2, 3, 4, 5, 6, 7, 15, 23, 31, 39, 47, 55], 
       [63, 56, 0, 7], 
       [63, 56, 0, 7], 
       [35, 36, 27, 56, 28, 0, 7, 63], 
       [63, 56, 0, 7, 36, 35, 27, 28], 
       [63, 7, 56, 0], 
       [7, 0, 56, 63], 
       [7, 6, 5, 4, 3, 2, 1, 0, 8, 16, 32, 24, 40, 48, 56, 57, 58, 59, 60, 61, 62, 63, 55, 39, 47, 31, 23, 15]]

Output:

{
    {0xFF, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xFF},
    {0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81},
    {0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81},
    {0x81, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x81},
    {0x81, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x81},
    {0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81},
    {0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81},
    {0xFF, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xFF},
};

Attempt

以下是我的尝试:

massive = [[63, 62, 61, 60, 59, 58, 57, 56, 48, 40, 32, 24, 16, 8, 0, 1, 2, 3, 4, 5, 6, 7, 15, 23, 31, 39, 47, 55], 
           [63, 56, 0, 7], 
           [63, 56, 0, 7], 
           [35, 36, 27, 56, 28, 0, 7, 63], 
           [63, 56, 0, 7, 36, 35, 27, 28], 
           [63, 7, 56, 0], 
           [7, 0, 56, 63], 
           [7, 6, 5, 4, 3, 2, 1, 0, 8, 16, 32, 24, 40, 48, 56, 57, 58, 59, 60, 61, 62, 63, 55, 39, 47, 31, 23, 15]]


rows, cols = (8, 8)
arr = [['' for i in range(cols)] for j in range(rows)]
arr[0][0] = ''

for row in arr:
  print(row)


def convert():
  for i in range(0, 64):
    for n in range(0,64):
      for each in massive:
        if i == massive[massive.index(each)][n]:
          arr[massive.index(each)][n] = '1'
        else:
          arr[massive.index(each)][n] = '0'

convert()

for row in arr:
  print(row)

Output:

['', '', '', '', '', '', '', '']
['', '', '', '', '', '', '', '']
['', '', '', '', '', '', '', '']
['', '', '', '', '', '', '', '']
['', '', '', '', '', '', '', '']
['', '', '', '', '', '', '', '']
['', '', '', '', '', '', '', '']
['', '', '', '', '', '', '', '']
Traceback (most recent call last):
  File "main.py", line 28, in <module>
    convert()
  File "main.py", line 23, in convert
    if i == massive[massive.index(each)][n]:
IndexError: list index out of range

我确实理解我在这里的错误,但我陷入困境,无法想出一种巧妙的方法来获得所需的输出。

编辑:*请考虑立方体的层数从下到上。 因此,massage[0] 将是第一层,因此是最底层,而 Massive[7] 将是最后一层,因此是顶部层(当可视化为立方体时,请参阅简介中的 3D Massive 表示)。


绝对不是最有效的,但希望具有可读性和简单的解决方案。

从一个简单的函数开始,将索引转换为所需的图层位图:

def bitmap(indices, side=8):
    """Transform a list of indices to an 8x8 bitmap with those indices turned on"""
    indices = set(indices)
    return [[int(side*i+j in indices) for j in range(side)] for i in range(side)]

例如,对于第一行massive,你会得到:

[[1, 1, 1, 1, 1, 1, 1, 1],
 [1, 0, 0, 0, 0, 0, 0, 1],
 [1, 0, 0, 0, 0, 0, 0, 1],
 [1, 0, 0, 0, 0, 0, 0, 1],
 [1, 0, 0, 0, 0, 0, 0, 1],
 [1, 0, 0, 0, 0, 0, 0, 1],
 [1, 0, 0, 0, 0, 0, 0, 1],
 [1, 1, 1, 1, 1, 1, 1, 1]]

这与您的图层插图相匹配,并且还可以用于以视觉方式创建它们matplotlib --

plt.imshow(bitmap(massive[0]), cmap='gray_r')
plt.show()

或者甚至作为使用体素的 3D 绘图:

cube = np.array([bitmap(layer) for layer in massive])
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
# Use transpose of `cube` to get the direction right
# (bottom->up rather than left->right)
ax.voxels(cube.T, edgecolor='k')
ax.set(xticklabels=[], yticklabels=[], zticklabels=[])
plt.show()

然后是一个小函数来根据需要添加这些垂直层:

def hexaize(massive, side=8):
    """Adds the values for each column across vertical layers"""
    final_map = [[0] * side for _ in range(side)]
    # Reverse-iterate over massive since it's given bottom-up and not top-down
    for i, layer in enumerate(reversed(massive)):
        for j, row in enumerate(bitmap(layer)):
            for k, val in enumerate(row):
                final_map[i][j] += val*2**k
    # Finally convert the added values to hexadecimal
    # Use the f-string formatting to ensure upper case and 2-digits
    return [[f"0x{val:02X}" for val in row] for row in final_map]

然后打电话hexaize(massive)返回:

[['0xFF', '0x81', '0x81', '0x81', '0x81', '0x81', '0x81', '0xFF'],
 ['0x81', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x81'],
 ['0x81', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x81'],
 ['0x81', '0x00', '0x00', '0x18', '0x18', '0x00', '0x00', '0x81'],
 ['0x81', '0x00', '0x00', '0x18', '0x18', '0x00', '0x00', '0x81'],
 ['0x81', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x81'],
 ['0x81', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x81'],
 ['0xFF', '0x81', '0x81', '0x81', '0x81', '0x81', '0x81', '0xFF']]

最后,如果您想要如上所述的精确输出(用类似 C 的表示法?),那么您可以链接多个replace像这样调用:

def massive_to_arduino(massive, side=8):
    """Converts a massive to Arduino style input"""
    # Get the hexa format of massive
    in_hex = hexaize(massive, side=side)
    # Replace square brackets with curly ones
    in_hex = str(in_hex).replace("[", "{").replace("]", "}")
    # Break rows to join them with new lines and indentation
    in_hex = "},\n   ".join(in_hex.split("},"))
    # Add new line, indentation, and semicolon to start and end
    return in_hex.replace("{{", "{\n    {").replace("}}", "},\n};")

然后打电话

print(massive_to_arduino(massive))

produces

{
    {'0xFF', '0x81', '0x81', '0x81', '0x81', '0x81', '0x81', '0xFF'},
    {'0x81', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x81'},
    {'0x81', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x81'},
    {'0x81', '0x00', '0x00', '0x18', '0x18', '0x00', '0x00', '0x81'},
    {'0x81', '0x00', '0x00', '0x18', '0x18', '0x00', '0x00', '0x81'},
    {'0x81', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x81'},
    {'0x81', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x81'},
    {'0xFF', '0x81', '0x81', '0x81', '0x81', '0x81', '0x81', '0xFF'},
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将大块位图转换为 3 维位图 的相关文章

随机推荐