1

I have found many examples in opencv of sending a mat through socket from java to java or c++, but I can't get it to work on python.

The server code:

MatOfByte bytemat = new MatOfByte();
    Highgui.imencode(".jpg", out, bytemat);
    byte[] bytes = bytemat.toArray();
    r.write(String.valueOf(bytes.length));
    Log.d(TAG, String.valueOf(bytes.length));
    r.write(bytes);

The python code:

def recvall(sock, count):
buf = b''
while count:
    newbuf = sock.recv(count)
    if not newbuf: return None
    buf += newbuf
    count -= len(newbuf)
return buf

length = recvall(camera_socket, 5)
if not length:
    continue
print length
data = recvall(camera_socket, int(length))
if not data:
    continue

nparr = np.fromstring(data, np.uint8)
frame = cv2.imdecode(nparr, cv2.CV_LOAD_IMAGE_UNCHANGED)

window = cv2.namedWindow('frame', cv2.WINDOW_NORMAL)
cv2.imshow('frame', frame)

The weird part is that imdecode returns None always. I just can't get it to work. PS: the java client works using ObjectInputStream

----EDIT---- Thanks all for advices, I've replaced the byte stream with predefined bytes and discovered that Java was sending some headers when sending bytes because it was using ObjectOutputStream.

Now the java code for writing to socket is:

    DataOutputStream oos = null;
    try {
        oos = new DataOutputStream(os);
        oos.write(byteImage);
    } catch (Exception e) {
        Log.e(TAG, "Error while writing to OutputStream", e);
        cancel();
        setState(STATE_NONE, this.type);
    }
andunhill
  • 61
  • 9
  • What is your error message? Have you compared file sizes prior and after sending, so are you sure that the transmission has been successful and complete? – tfv May 06 '16 at 20:06
  • There is no error message, the number of bytes transmitted is the same. I really don't know how to debug this thing – andunhill May 07 '16 at 12:22
  • can you write the result of imdecode into a file and share the file with us? imdecode in java works with that file? – tfv May 07 '16 at 12:35
  • The imdecode returns None in python. The best I can try is to send back the bytes and use imdecode in java but I suspect it would work. The number of transmited bytes is the same – andunhill May 07 '16 at 12:37
  • You could pickle "data" and share it with us: `pickle.dump(data, open('data_file.p', 'w'))` . Sending the data back is also a good diea, if it works, transmission is intact. What hardware and operation systems are you using on both machines? – tfv May 07 '16 at 12:58
  • Have you seen this?: http://stackoverflow.com/questions/32312908/cv2-imdecode-always-returning-none – tfv May 07 '16 at 13:03
  • Have a look here, I am not sure whether your flag is correct: http://stackoverflow.com/questions/17170752/python-opencv-load-image-from-byte-string – tfv May 07 '16 at 13:11

2 Answers2

1

Try using np.uint8(nparr) for conversion as in:

frame = np.uint8(nparr)

This example works:

import numpy as np
import cv2

nparr = np.zeros((512, 512))
nparr[200:300, 400:450]=255

cv2.imshow("Result", np.uint8(nparr))
cv2.waitKey()

[EDIT] In case of a colour image please keep in mind that OpenCV2 images are BGR instaed of RGB, so you may vae to use

rgb = cv2.cvtColor(frame_in_bgr, cv2.COLOR_BGR2RGB)

enter image description here

tfv
  • 6,016
  • 4
  • 36
  • 67
0

Thanks all for advices, I've replaced the byte stream with predefined bytes and discovered that Java was sending some headers when sending bytes because it was using ObjectOutputStream.

Now the java code for writing to socket is:

DataOutputStream oos = null;
        try {
            oos = new DataOutputStream(os);
            oos.write(byteImage);
        } catch (Exception e) {
            Log.e(TAG, "Error while writing to OutputStream", e);
            cancel();
            setState(STATE_NONE, this.type);
        }

This now works. The only problem left is that the colors are inverted. Any tip on how to invert them again?

andunhill
  • 61
  • 9