9

I have pixmap:

pixmap = self._screen.grabWindow(0,
                                 self._x, self._y,
                                 self._width, self._height)

I want to convert it to OpenCV format. I tried to convert it to numpy.ndarray as described here but I got error sip.voidptr object has an unknown size

Is there any way to get numpy array (same format as cv2.VideoCapture read method returns)?

ingvar
  • 4,169
  • 4
  • 16
  • 29

3 Answers3

7

I got numpy array using this code:

channels_count = 4
pixmap = self._screen.grabWindow(0, self._x, self._y, self._width, self._height)
image = pixmap.toImage()
s = image.bits().asstring(self._width * self._height * channels_count)
arr = np.fromstring(s, dtype=np.uint8).reshape((self._height, self._width, channels_count)) 
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
ingvar
  • 4,169
  • 4
  • 16
  • 29
  • That indeed worked for me, thanks, however, it raises a DeprecationWarning. It is therefore recommended to replace np.fromstring in your last code line with np.frombuffer. – Shahar Gino Nov 21 '21 at 14:06
6

The copy can be avoided by doing:

channels_count = 4
pixmap = self._screen.grabWindow(0, self._x, self._y, self._width, self._height)
image = pixmap.toImage()
b = image.bits()
# sip.voidptr must know size to support python buffer interface
b.setsize(self._height * self._width * channels_count)
arr = np.frombuffer(b, np.uint8).reshape((self._height, self._width, channels_count))
Stefan
  • 4,380
  • 2
  • 30
  • 33
1

Heres a function:

def QPixmapToArray(pixmap):
    ## Get the size of the current pixmap
    size = pixmap.size()
    h = size.width()
    w = size.height()

    ## Get the QImage Item and convert it to a byte string
    qimg = pixmap.toImage()
    byte_str = qimg.bits().tobytes()

    ## Using the np.frombuffer function to convert the byte string into an np array
    img = np.frombuffer(byte_str, dtype=np.uint8).reshape((w,h,4))

    return img
Ivan
  • 311
  • 3
  • 7