pythonnumpymediapipe

Why does a numpy transpose break mediapipe's Image command?


I would like to rotate an image in opencv before putting it into mediapipe. I took a transpose using numpy but, although the type is still numpy.uint8, mediapipe complains,

import cv2
import numpy as np
import mediapipe as mp

image_file_name = "IMG_0237.JPG"
cvImage = cv2.imread(image_file_name)
cvImage = np.transpose(cvImage, axes=[1,0,2]) #without this line code runs fine
print(cvImage.dtype)
mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=cvImage)

returns,

uint8

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[4], line 9
      7 cvImage = np.transpose(cvImage, axes=[1,0,2]) #without this line code runs fine
      8 print(cvImage.dtype)
----> 9 mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=cvImage)

TypeError: __init__(): incompatible constructor arguments. The following argument types are supported:
    1. mediapipe.python._framework_bindings.image.Image(image_format: mediapipe::ImageFormat_Format, data: numpy.ndarray[numpy.uint8])
    2. mediapipe.python._framework_bindings.image.Image(image_format: mediapipe::ImageFormat_Format, data: numpy.ndarray[numpy.uint16])
    3. mediapipe.python._framework_bindings.image.Image(image_format: mediapipe::ImageFormat_Format, data: numpy.ndarray[numpy.float32])

Invoked with: kwargs: image_format=<ImageFormat.SRGB: 1>, data=array([[[176, 223, 255],
        [176, 223, 255],

I tried commenting out the transpose line and the code runs fine. I checked my types and they seem to be good too.

As a bonus question, if anyone knows of an AI model that gives a face and hair (i.e. a selfie) mask without mediapipe that would be most welcome.


Solution

  • The issue here is that ndarray.transpose does not actually move anything in memory. It simply resets the strides so that accesses APPEAR to be using new locations.

    mediapipe, on the other hand, requires that the input array be physically contiguous in memory. Your array isn't. You can use np.ascontiguousarray to force it to rearrange the contents.

    Is numpy.transpose reordering data in memory?