Search code examples
pythonnumpysocketspickleros

"_pickle.UnpicklingError: the STRING opcode argument must be quoted" in py2 to py3 ndarray transmission


I have a workstation running Python2 with a ROS environment which obtains a camera image from a robot and sends it over the network to a Python3 machine using the standard socket library. I can't seem to unpickle correctly the opencv ndarray image.

I am able to successfully transfer simple data as lists, but I encounter an error when trying to transfer an image.

On the Python2 system, I obtain my image in this way:

img = CvBridge().imgmsg_to_cv2(img_data, desired_encoding='bgr8')     # Convert from ROS image to OpenCV image

Obtaining an ndarray. I serialize it with:

data = pickle.dumps(img, protocol=0)

And I send it. Back on the Python3 machine, I try to unpickle it using:

response = pickle.loads(data_in, encoding='latin1')     # To read a Python2 dump

At this point, I obtain the following error:

_pickle.UnpicklingError: the STRING opcode argument must be quoted

The only other solutions that I have found address cases in which data had been transferred between Unix and Windows machines, which is not my case.


Solution

  • An update on this topic, for possible future reference to whoever will experience the same problem.

    The problem was not caused, as I initially thought, by a misconversion between Py2 and Py3 pickled byte stream. It was caused, instead, by the incorrect transmission of the data: I was interrupting the connection before all the packages had arrived. This is the block of code that solved my problem:

    data_in = b''
    while True:
        block = self.socket.recv(4096)
        if block:
            data_in += block