Python 将PIL图像转换为OpenCV2图像
我正在使用Python 将PIL图像转换为OpenCV2图像,python,opencv,numpy,python-imaging-library,Python,Opencv,Numpy,Python Imaging Library,我正在使用entireScreen=ImageGrab.grab()创建屏幕抓图,然后使用openCV2进行一些分析,以测试屏幕是否包含某些模板图像。这些模板加载了template=cv2.imread(name,0) 我现在有以下问题:在将我的截图与模板进行比较时,我始终需要首先使用以下内容保存我的截图: entireScreen.save('pics/screenshot.png',format='png') 然后重新加载: cv2.imread('screenshot.png',0) 否则
entireScreen=ImageGrab.grab()
创建屏幕抓图,然后使用openCV2进行一些分析,以测试屏幕是否包含某些模板图像。这些模板加载了template=cv2.imread(name,0)
我现在有以下问题:在将我的截图与模板进行比较时,我始终需要首先使用以下内容保存我的截图:
entireScreen.save('pics/screenshot.png',format='png')
然后重新加载:
cv2.imread('screenshot.png',0)
否则,以下操作将不起作用:
res=cv2.matchTemplate(img,模板,方法)
我会收到这样的错误消息:
TypeError:image不是numpy数组,也不是标量
我的问题是:如何将屏幕截图从entireScreen=ImageGrab.grab()
转换为与opencv2兼容的格式,而不必保存并使用cv2.imread重新加载它。在linux系统上,可以使用它作为其文档
状态,以替代ImageGrab模块,它只在Windows上工作
所以,在我的linux系统上,我做了类似的事情-
import pyscreenshot as ImageGrab
然后,您可以抓取屏幕截图,并直接在内存空间中以numpy数组的形式访问它,而无需实际保存到磁盘上并使用imread
读取,就像这样-
img = np.array(ImageGrab.grab().convert('RGB'))
该img
可按原样与cv2.matchTemplate
一起使用
一步一步的样本运行和输出验证-
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')
下面是一个示例运行,展示了如何将cv2.matchTemplate
与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]))
[41]中的res=cv2.matchTemplate(img[:,:,0],img[10:40,50:80,0],cv2.tmsqdiff)
在[42]:np.where(resI目前没有设置Windows系统,尝试导入ImageGrab
告诉我它只是Windows,所以这只是一个猜测:通过np.array()
传递entireScreen
,在传递到cv2.matchTemple()之前将其转换为numpy数组
。例如,res=cv2.matchTemplate(np.array(entireScreen),template,method)
这是一个非常有用的工具,顺便说一句,这个截图。感谢你提出这个问题!这似乎很有效。需要注意的是,有两个步骤。首先将img转换为RGB,然后是img[:,:,0]@Nicolas,这只是一个使用蓝色通道运行的示例。
,:,0]
。您可能正在使用其他版本的输入阵列,可能是灰度,可能是红色通道或绿色通道,或者其他修改版本的3D RGB输入阵列。如果我不这样做[:,:,0]然后我得到一个错误:cv2.error:..\..\..\opencv-3.0.0\modules\imgproc\src\templatmatch.cpp:910:error:(-215)(depth==CV_8U | | depth==CV_32F)和&type==temp.type()&&img.dims()@Nicolas我认为模板匹配需要2D数组。我不知道您打算如何在您的案例中使用模板匹配。我所展示的示例运行使用蓝色通道,即img[;,:,0]
。您计划如何在您的案例中使用此模板匹配?@Nicolas在这种情况下,您可以直接执行img=np.array(ImageGrab.grab().convert('L'))
,为我们提供了一个二维灰度图像,可以与模板匹配功能一起使用。