Python:NumPy数组的struct.pack和struct.unpack

2024-04-19 06:44:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在探索struct.packstruct.unpack的NumPy版本。我的特殊问题是将RGB值(r, g, b)转换为二进制

例如:

f = lambda r, g, b: struct.unpack('I', struct.pack('BBBB', r, g, b, 255))[0]
f(155, 156, 148)
#--> 4287929499

当我将此转换应用于图像(RGB的二维阵列)时,它会变得非常慢

例如:

import numpy as np
import struct

img_rgb = np.random.randint(0, 256, (480, 640, 3))
%%time
np.apply_along_axis(lambda rgb: struct.unpack('I', struct.pack('BBBB', rgb[0], rgb[1], rgb[2], 255))[0], 2, img_rgb)
#--> Wall time: 5.23 s

我的问题是struct.packstruct.unpack是否存在NumPy版本?或者,如何使用NumPy使代码更快


Tags: lambda图像import版本numpyimgtimenp
1条回答
网友
1楼 · 发布于 2024-04-19 06:44:31

在numpy中不需要^{}^{}操作,因为它使用原始二进制数组,而不是将每个值单独包装到单独的对象中。通常,您使用的操作是^{}^{}^{},有时是^{}

在您的特定情况下,您有和(M, N, 3)映像,您希望向其添加255个通道并将其转换为^{}

img_rgb = np.random.randint(0, 256, size=(480, 640, 3))
img_rgba = np.concatenate((img_rgb.astype(np.uint8), np.full((*img_rgb.shape[:-1], 1), 255, dtype=np.uint8)), axis=-1)

通过将最后一个维度设置为大小4,可以确保现在可以直接以^{}的形式查看数据:

result = img_rgba.view(np.uint32)

结果将是形状(M, N, 1)。您可以使用^{}删除额外维度:

result = np.squeeze(img_rgba.view(np.uint32))

这并没有给你带来多少好处:它删除了方便的3通道表示,而不改变内存布局。将img_rgbaresult转储到原始二进制文件将产生相同的结果

一般来说,像^{}这样的函数通常是numpy中的代码气味。它们并不比运行显式的for-循环好多少。您的目标应该始终是将代码矢量化,以便一次对所有元素执行操作

相关问题 更多 >