Sending numpy arrays via Socket

2019-06-05 03:28发布

问题:

First of all, what I want to do: Sending Photos with Socket from my Raspberry Pi to my laptop.

Client:

#!/usr/bin/python

import socket
import cv2
import numpy as np
import pickle

#Upload image
img = cv2.imread('/path/to/image', 0)

#Turn image into numpy-array
arr = np.asarray(img)

#Receiver ip
ip = "XXX.XXX.X.XXX"

#Set up socket and stuff 
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

#Loop through each array (5 for test)
for each in range(5):

    #Encode each array
    msg = pickle.dumps(arr[each][0])

    #Send msg to ip with port
    s.sendto(msg, (ip, 50000))

s.close()

What happens here: I upload a picture and then turn it into an Numpy array. Then I take each line of the array (each list) and "encode" it with pickle to send it afterwards via Socket. Everything works fine to this point.

Server:

#!/usr/bin/python

import socket
import numpy as np
import cPickle as pickle

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

s.bind(("", 50000)) 

while True:
    data, addr = s.recvfrom(4096)
    conv = pickle.loads(data)
    print conv
    #print np.fromstring(conv,dtype=int)
s.close()

The server receives the encoded data and decodes it back into an Numpy array (that's what I want to achieve).

At the end, it should turn the array back into an image, but I didn't even get to that part, because of the issues I have at this point.

I've also tried to turn the array into a string first, encode it with pickle and then send it so when it gets decoded, it is an numpy array. But that didn't work well.

ValueError: string size must be a multiple of element size

I would appreciate any kind of help, be it a link or pointing out my mistake. Have been working on this for days and haven't found anything that could help me in this matter.

Thanks in advance.

回答1:

You don't need OpenCV and NumPy for this. Instead, simply send the bytes of the file directly. If you have Python 3.5 you can even use socket.sendfile().

For more detail see: Sending a file over TCP sockets in Python



回答2:

I dont know how many decimal places you need but you could encode your numpy array values in UTF16 BE and then decode after socket send with

def retrieve_and_decode_data():
    try:
        data,addr = s.recvfrom(4096)                                                                                                                                                                                
        list_of_converted_utf16chars = (repr(data.decode('utf-16')).split("\\")[1:])

    except (ValueError, IndexError) as e:
        **perform some conversion-error exception...**

The "repr" function gives you a representation of the utf16 char you can look up in the utf-table

you can then convert this representation into a int or float with

integer_value = int(list_of_converted_utf16chars[index], 16)