Nickpick
Nickpick

Reputation: 6597

Convert PIL image to OpenCV2 image

I'm using entireScreen=ImageGrab.grab() to create a screengrab and then conduct some analyses with openCV2 to test whether the screen contains certain template images. Those templates are loaded with template = cv2.imread(name,0).

I have now the following problem: when comparing my screenshot with the templates I always need to first save my screenshot with this :

entireScreen.save('pics/screenshot.png', format='png')

And then reload it with :

cv2.imread('screenshot.png',0)

Otherwise the following will not work:

res = cv2.matchTemplate(img,template,method)

I would get an error message like this one:

TypeError: image is not a numpy array, neither a scalar

My question: how can I convert the screenshot from entireScreen=ImageGrab.grab() into a format that is compatible with opencv2, without having to save and then reload it with cv2.imread.

Upvotes: 2

Views: 7466

Answers (1)

Divakar
Divakar

Reputation: 221684

On linux systems, one can use pyscreenshot which as its docs state, is a replacement for the ImageGrab Module, which works on Windows only.

So, on my linux system I did something like this -

import pyscreenshot as ImageGrab

Then, you can grab the screenshot and have access to it directly in memory space as a numpy array without having to actually save onto disk and read with imread, like so -

img = np.array(ImageGrab.grab().convert('RGB'))

This img could then by used with cv2.matchTemplate as it is.


A step-by-step sample run and verification of output -

In [32]: import pyscreenshot as ImageGrab

In [33]: img = np.array(ImageGrab.grab().convert('RGB'))

In [34]: img.shape
Out[34]: (768, 1366, 3)

In [35]: img.dtype
Out[35]: dtype('uint8')

Here's a sample run showing how cv2.matchTemplate could then be used with img -

In [41]: res = cv2.matchTemplate(img[:,:,0],img[10:40,50:80,0],cv2.TM_SQDIFF)

In [42]: np.where(res<10) # 10 is threshold for matching
Out[42]: (array([10]), array([50]))

Upvotes: 2

Related Questions