Cristofer Fuentes Cristofer Fuentes - 2 months ago 28
Python Question

openCV not accept numpy array?

I want to do a

matchTemplate
from a screenshot (with mss)

from mss import mss
import cv2

import numpy

with mss() as sct:
screenshot_numpy = numpy.array(sct.shot())
template = cv2.imread('./templates/player.png')

result = cv2.matchTemplate(screenshot_numpy,template,cv2.TM_CCOEFF_NORMED)


Error message:

Traceback (most recent call last):
File "main.py", line 14, in <module>
result = cv2.matchTemplate(screenshot_numpy,template,cv2.TM_CCOEFF_NORMED)
TypeError: image data type = 18 is not supported

Answer Source

From the mss examples page:

img = numpy.array(sct.grab(monitor))

So here we can see the .grab() method to get the raw pixel data from the image. In this case sct.grab() returns a PIL Image, and numpy.array(Image) will thus convert the PIL Image object into a numpy ndarray.

Check the numpy ndarray dtype after you convert; for e.g. if your code is ndarray_img = numpy.array(sct.grab()), then check ndarray_img.dtype. If it's np.uint8 then you're done. If it's np.uint16, then you'll have to divide by 256 and convert to np.uint8 with ndarray_img = (ndarray_img/255).astype(np.uint8).

Further down you'll see another example which flips the R and B channels of the image:

cv2.imshow(title, cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

except this is actually backwards. It really doesn't matter because either way it's just swapping the first and third channel, so BGR2RGB and RGB2BGR do exactly the same thing, but PIL (and other libraries) give you RGB order while you need BGR order to display with OpenCV, so technically it should be

cv2.imshow(title, cv2.cvtColor(img, cv2.COLOR_RGB2BGR))