How can I pack numpy bool arrays into a string of bits?

Overview

In numpy, I have an array of bools. The array was extracted from the image; it is two-dimensional and contains 1024 columns and 768 rows. I want to move this data over an Ethernet cable. There are several ways to do this, but for my purposes, speed is extremely important, so memory is also very important.

Since each array has elements 1024 x 768 = 786432(pixels), and each element has either True, or False, it is theoretically possible to assemble an array of 98 304 uncompressed bytes or 96 kilobytes.

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

This requires smoothing the array.

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

# flatten the array

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

Which theoretically can be represented as bits of bytes, since 786,432 bits evenly fit into 98,304 bytes; each array must be represented by 98,304 eight-bit characters.

Question

1024--768 bool numpy Ethernet? python bitstring, , numpy bitstring.

/

, Pi 2 .

  • socket SOCK_STREAM ?
  • RPis, ? , .
  • numpy bitstring, SOCK_STREAM. - socket?

/​​ [SOLVED]

Client

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()

, TCP/SOCK_STREAM 1024- .

+4
1

np.packbits, np.bool np.uint8 1/8th , "" . 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]

- , UDP, . numpy native serialization (.tostring() np.fromstring()), , , pickle cPickle.

, zlib , , . , - , , , , /.

+6

Source: https://habr.com/ru/post/1584996/


All Articles