【发布时间】:2017-02-27 03:08:52
【问题描述】:
我需要为我正在处理的 OpenCV 项目快速截取游戏截图。例如,我可以轻松使用 PIL:
def take_screenshot1(hwnd):
rect = win32gui.GetWindowRect(hwnd)
img = ImageGrab.grab(bbox=rect)
img_np = np.array(img)
return cv2.cvtColor(img_np, cv2.COLOR_RGB2BGR)
但平均需要 0.05 秒,这对于实时捕捉来说不够快。
我可以使用here 发布的答案,但这只会将位图保存到文件中。这比使用 PIL 快 10 倍以上,但我不确定 OpenCV 中有什么方法可以将其转换为 bgr/hsv 图像。
def take_screenshot(hwnd):
wDC = win32gui.GetWindowDC(hwnd)
dcObj=win32ui.CreateDCFromHandle(wDC)
cDC=dcObj.CreateCompatibleDC()
dataBitMap = win32ui.CreateBitmap()
dataBitMap.CreateCompatibleBitmap(dcObj, 500, 500)
cDC.SelectObject(dataBitMap)
cDC.BitBlt((0, 0), (500, 500), dcObj, (0, 0), win32con.SRCCOPY)
dataBitMap.SaveBitmapFile(cDC, "foo.png")
dcObj.DeleteDC()
cDC.DeleteDC()
win32gui.ReleaseDC(hwnd, wDC)
win32gui.DeleteObject(dataBitMap.GetHandle())
im = cv2.imread("foo.png")
return cv2.cvtColor(im, cv2.COLOR_RGB2BGR)
编辑:窗口的大小为 500x500,因此在两个示例中它保存的区域相同。
即使我保存图像,然后用 OpenCV 重新打开它,它仍然比 PIL 快,但肯定有更简单的方法吗?
编辑:好的,所以使用 cmets 并对 winapi 进行一些研究,我现在可以直接访问位图数据,如下所示:
def take_screenshot1(hwnd):
wDC = win32gui.GetWindowDC(hwnd)
dcObj=win32ui.CreateDCFromHandle(wDC)
cDC=dcObj.CreateCompatibleDC()
dataBitMap = win32ui.CreateBitmap()
dataBitMap.CreateCompatibleBitmap(dcObj, 500, 500)
cDC.SelectObject(dataBitMap)
cDC.BitBlt((0, 0), (500, 500), dcObj, (0, 0), win32con.SRCCOPY)
im = dataBitMap.GetBitmapBits(True) # Tried False also
img = np.array(im)
cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
print(img)
dcObj.DeleteDC()
cDC.DeleteDC()
win32gui.ReleaseDC(hwnd, wDC)
win32gui.DeleteObject(dataBitMap.GetHandle())
但我不确定如何将返回的位图转换为 OpenCV 可以理解的形式,因为在 OpenCV 中没有将位图转换为 rgb/bgr 的方法
【问题讨论】:
-
在第一个版本中,您正在阅读窗口的整个区域。在第二个版本中,您正在阅读 500x500 像素区域。除非两个区域相同,否则您无法比较速度。
BitBlt有一个瓶颈,你真的无能为力。 -
@Barmak Shermirana Ahh 我应该指定得更好。我正在捕获的窗口是 500x500,所以大小是相同的。所以我想我可能只需要保存并打开看起来的 img ..
-
@IInspectable 如果我调用:win32gui.GetObject(dataBitMap) 我收到错误“TypeError: The object is not a PyHANDLE object”
-
那是错误的
GetObject电话。我指的是 GDI 功能(如文档所述)。作为替代方案,如果您想存储位图数据的副本,您可以调用GetDIBits。您使用的所有操作都需要对Windows GDI 有一定的了解。
标签: python opencv numpy winapi