2014-10-15 15 views
6

Ngày tốt,Gửi một mảng đa chiều trên một ổ cắm

Tôi đã tìm kiếm điều này nhưng chưa đưa ra bất kỳ câu trả lời nào. Tôi muốn gửi một mảng numpy đa chiều trên một ổ cắm. Do đó, tôi quyết định chuyển nó sang một chuỗi:

Tuy nhiên, nó phá hủy các đại diện của các mảng:

>>> 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] 

Liệu có cách nào tôi có thể nhận được chuyển đổi sang chuỗi bằng cách nào đó, tiết kiệm kích thước của nó ?

Trả lời

2

Thật vậy, .tostring chỉ trả về dữ liệu thô. Điều này có nghĩa là bạn cũng cần phải gửi hình dạng và loại dtype của mảng nếu chúng không được biết ở phía bên kia.

Có lẽ nó dễ dàng hơn để serialize mảng bằng cách sử dụng Pickle:

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]] 

Mặc dù đối với mảng rất nhỏ kích thước trên cao có thể là đáng kể:

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

Để biết thêm về việc sử dụng Pickle, see here.

+0

Pickle cực kỳ chậm và tạo mảng 2d lớn của tôi. Nó cũng đôi khi bị hỏng chương trình của tôi với một số ngoại lệ keyerror – ovfstack

+0

@ovfstack: Bạn nói đúng. Trên Python 3, overhead không đáng kể đối với các mảng lớn và nó chỉ chạy chậm gấp hai lần '.tostring()'. Đối với Python 2, bạn sẽ thấy một cải tiến lớn nếu bạn chỉ định 'protocol = 2', mặc dù nó vẫn có vẻ chậm hơn 4 lần so với' .tostring() 'trong trường hợp này. –

+0

Tôi chỉ sử dụng chức năng imencode mà opencv cung cấp. Nó cũng có thể "nén" mảng của tôi và imdecode đã có thể phục hồi nó với độ chính xác khá – ovfstack

5

Hãy thử ví dụ sau: -

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 

Trong ứng dụng khách mô hình này sẽ gửi ndarray đa chiều tới máy chủ. Có hai hàm startServer() và startClient(). startServer không có đối số nhưng startClient cần địa chỉ máy chủ cũng như ndarray làm đối số. Máy chủ khởi động đầu tiên và sau đó khởi động máy khách. Máy chủ bắt đầu đọc từ bộ đệm chỉ sau khi nhận được thông báo tắt máy từ máy khách.

Các vấn đề liên quan