gpt4 book ai didi

python - 如何将 numpy bool 数组打包成一串位?

转载 作者:太空狗 更新时间:2023-10-30 02:29:57 24 4
gpt4 key购买 nike

概览

在 numpy 中,我有一个 bool 数组。该数组是从图像中检索的;它是二维的,包含 1024 列和 768 行。我想通过以太网电缆推送此数据。有多种方法可以做到这一点,但就我的目的而言,速度极其重要,因此内存也非常重要。

由于每个数组中有 1024 x 768 = 786432 个元素(像素),并且每个元素要么为 True 要么为 False,因此理论上可以将数组打包成 98,304 个未压缩字节或 96 KB。

786432 bits / 8 bits per byte =         98304 bytes
98304 bytes / 1024 bytes per kilobyte = 96 kilobytes

这需要展平数组

[ [True, False, True, ..., True]
[False, True, True, ..., True]
...
[True, True, False, ..., False] ]

# flatten the array

[True, False, True, ..., False]

理论上可以表示为字节的位,因为 786,432 位均匀地适合 98,304 字节;每个数组应该能够由 98,304 个八位字符表示。

问题

如何通过以太网快速发送 1024×768 bool numpy 数组?我正在查看 bitstring python 库,但我不确定如何快速将 numpy 数组传输到 bitstring 类中。

其他信息/问题

具体来说,我将这些阵列从 Raspberry Pi 2 发送到普通 Raspberry Pi。

  1. socketSOCK_STREAM 是最快的解决方法吗?
  2. 鉴于 RPis 的计算能力,压缩和解压缩数组会更快吗?如果是这样,压缩必须是无损的。
  3. 我研究了序列化 numpy 数组而不是使用 bitstring 东西,但是 pickle 对象太大而无法通过 SOCK_STREAM 发送。我对 socket 做错了什么吗?

我的代码/解决方案 [已解决]

客户端

import socket
from scipy.misc import imread
import numpy

IP = '127.0.0.1'
PORT = 7071
ADDRESS = (IP, PORT)

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

image = imread('input.png')[:,:,[2]]
image[image < 170] = 0
image[image != 0] = 1
image = numpy.reshape(image, (-1, 1))
image = numpy.packbits(image)
data = image.tostring()

sock.connect(ADDRESS)
for i in range(0, 93804, 1024):
sock.send(data[i:i+1024])
sock.shutdown(socket.SHUT_WR)
sock.close()

服务器

import socket
from scipy.misc import imsave
import numpy

IP = '127.0.0.1'
PORT = 7071
ADDRESS = (IP, PORT)

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(ADDRESS)
sock.listen(1)

while True:
c, addr = sock.accept()
data = ''
package = c.recv(1024)
while package:
data += package
package = c.recv(1024)
image = numpy.fromstring(data, dtype=numpy.uint8)
image = numpy.unpackbits(image)
image = numpy.reshape(image, (-1, 768))
imsave('output.png', image)
c.close()
sock.close()

如您所见,我通过一系列 1024 字节的数据包结束了 TCP/SOCK_STREAM 上的每个数组。

最佳答案

您可以使用 np.packbitsnp.bool 数组的内容打包到大小为 1/8 的 np.uint8 数组中,这样每个“打包”的 bool 元素仅使用一个位.可以使用 np.unpackbits 恢复原始数组.

import numpy as np

x = array([0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1], dtype=np.bool)

print(x.itemsize, x.nbytes)
# (1, 16)

xp = np.packbits(x)
print(xp)
# [ 24 139]

print(xp.itemsize, xp.nbytes)
# (1, 2)

print(np.unpackbits(xp))
# [0 0 0 1 1 0 0 0 1 0 0 0 1 0 1 1]

最明显的方法是将打包数组序列化为原始字节字符串,pipe it through a UDP socket ,然后将其反序列化并在另一侧解压。 numpy 的原生序列化(.tostring()np.fromstring())可能比使用 picklecPickle 快得多。

如果您想尝试压缩,一种选择是使用 native zlib模块在通过管道传递之前压缩字节串,然后在另一端解压缩。您是否从中看到任何好处将在很大程度上取决于您的输入数组的可压缩性,以及执行压缩/解压缩的硬件。

关于python - 如何将 numpy bool 数组打包成一串位?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29907228/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com