Image dimensions swapped after sending through websocket

Viewed 61

I'm making an image viewer interface for a camera I have. The backend is written in python and works like this:

  1. Acquire image as numpy array.
  2. Convert numpy array to jpeg.
  3. Convert jpeg to base64 string.
  4. Send string over websocket.
def image_to_bytes(image):
    print('into: ', image.shape)
    buf = cv2.imencode('.jpg', image)[1]
    dec = cv2.imdecode(buf, cv2.IMREAD_COLOR)
    print('outa: ', dec.shape)
    return base64.b64encode(buf).decode('utf-8')
async def send_image(websocket: WebSocket):
    cam = Camera()
    for im in cam:
        w, h = im.shape[:2]
        resized = cv2.resize(im, (w // 4, h // 4), interpolation=cv2.INTER_LINEAR)
        await websocket.send_bytes(image_to_bytes(resized))

However when the javascript frontend receives the image the dimensions are swapped which distorts the image.

socket.onmessage = function(event) {
    let im    = new Image();
    const buf = event.data;
    im.src    = 'data:image/jpeg;base64,' + buf;

    im.onload = function() {
        context.drawImage(im, 0, 0);
        console.log('w=' + im.width + ', h=' + im.height);
    };
};

I know that the dimensions are swapped because I checked the dimensions before I encoded the image. Then I decoded it again to make sure the ecoding process didn't swap width and height. Finally I check the dimension on the JS side and width and height are reversed.

Any idea why the dimensions are getting swapped?

1 Answers

From the documentation of OpenCV:

The shape of an image is accessed by img.shape. It returns a tuple of the number of rows, columns, and channels (if the image is color):

Hence instead of w, h = im.shape[:2] you need h, w = im.shape[:2].

Related