2014-10-15 5 views
6

Добрый день,Отправить многомерную матрицу numpy по гнезду

Я искал это, но не придумал никаких ответов. Я хочу отправить многомерный массив numpy через сокет. Таким образом, я решил преобразовать его в строку:

Однако, он разрушает представление массива:

>>> import numpy as np 
>>> x = np.array([[0, 1], [2, 3]]) 
>>> xstring = x.tostring() 
>>> print xstring 

>>> print x 
[[0 1] 
[2 3]] 
>>> print xstring 

>>> nparr = np.fromstring(xstring, dtype=np.uint8) 
>>> print nparr 
[0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0] 

есть в любом случае я могу получить преобразование в строку, чтобы каким-то образом, сохранить размер его ?

ответ

2

Действительно, .tostring возвращает только исходные данные. Это означает, что вам также необходимо отправить форму и тип массива, если они не известны с другой стороны.

Может быть, это проще сериализация массива с помощью Рассол:

import numpy as np 
from cPickle import dumps, loads 

x = np.array([[1, 2],[3, 4]], np.uint8) 
print loads(dumps(x)) 
# [[1 2] 
# [3 4]] 

Хотя для очень маленьких массивов накладных расходы размера могут быть значительными:

print len(x.tostring()), len(dumps(x)) 
# 4 171 

Для дополнительной информации об использовании маринованные, see here.

+0

Рассол был очень медленным и сделал массив 2d массивным. Это также изредка разбивало мою программу с некоторыми исключениями, связанными с замораживанием – ovfstack

+0

@ovfstack: Вы правы. На Python 3 накладные расходы незначительны для больших массивов, и он работает только в два раза медленнее, чем '.tostring()'. Для Python 2 вы должны увидеть значительное улучшение, если вы укажете 'protocol = 2', хотя в этом случае он по-прежнему кажется в 4 раза медленнее, чем' .tostring(). –

+0

Я просто использовал функцию imencode, которую предоставляет opencv. Он также смог «сжать» мой массив, и imdecode смог восстановить его с приличной точностью – ovfstack

5

Попробуйте использовать этот пример: -

import socket 
import numpy as np 
from cStringIO import StringIO 

class numpysocket(): 
    def __init__(self): 
     pass 

    @staticmethod 
    def startServer(): 
     port=7555 
     server_socket=socket.socket() 
     server_socket.bind(('',port)) 
     server_socket.listen(1) 
     print 'waiting for a connection...' 
     client_connection,client_address=server_socket.accept() 
     print 'connected to ',client_address[0] 
     ultimate_buffer='' 
     while True: 
      receiving_buffer = client_connection.recv(1024) 
      if not receiving_buffer: break 
      ultimate_buffer+= receiving_buffer 
      print '-', 
     final_image=np.load(StringIO(ultimate_buffer))['frame'] 
     client_connection.close() 
     server_socket.close() 
     print '\nframe received' 
     return final_image 

    @staticmethod 
    def startClient(server_address,image): 
     if not isinstance(image,np.ndarray): 
      print 'not a valid numpy image' 
      return 
     client_socket=socket.socket() 
     port=7555 
     try: 
      client_socket.connect((server_address, port)) 
      print 'Connected to %s on port %s' % (server_address, port) 
     except socket.error,e: 
      print 'Connection to %s on port %s failed: %s' % (server_address, port, e) 
      return 
     f = StringIO() 
     np.savez_compressed(f,frame=image) 
     f.seek(0) 
     out = f.read() 
     client_socket.sendall(out) 
     client_socket.shutdown(1) 
     client_socket.close() 
     print 'image sent' 
     pass 

В этой модели клиент отправляет многомерный ndarray на сервер. Существуют две функции startServer() и startClient(). startServer не принимает аргументов, но startClient требует адрес сервера, а также ndarray в качестве аргументов. Сначала запустите сервер, а затем запустите клиент. Сервер начинает считывать из буфера только после получения сообщения об отключении от клиента.

Смежные вопросы