我需要为我正在开发的OpenCV项目拍摄非常快速的游戏截图。我可以轻松地使用PIL,例如:
int
但它平均需要0.05秒,这对于实时捕捉来说还不够快。
我可以使用here发布的答案,但这只会将位图保存到文件中。这比使用PIL快10倍,但我不确定OpenCV中的任何方法将其转换为bgr / hsv图像。
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)
编辑:窗口大小为500x500,因此在两个示例中都保存了相同的区域。
即使我保存图像,然后使用OpenCV重新打开它,它仍然比PIL快,但肯定有更简单的方法吗?
编辑:好的,所以使用评论并对winapi进行一些研究我现在可以直接访问位图数据,如下所示:
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)
但是我不知道如何将返回的位图转换为OpenCV可以理解的形式,因为没有方法可以将位图转换为OpenCV中的rgb / bgr
答案 0 :(得分:0)
我只会展示对我有用的代码。
import time
import win32gui
import win32ui
import win32con
import win32api
import numpy as np
import cv2
def window_capture():
hwnd = 0
hwndDC = win32gui.GetWindowDC(hwnd)
mfcDC = win32ui.CreateDCFromHandle(hwndDC)
saveDC = mfcDC.CreateCompatibleDC()
saveBitMap = win32ui.CreateBitmap()
MoniterDev = win32api.EnumDisplayMonitors(None, None)
w = MoniterDev[0][2][2]
h = MoniterDev[0][2][3]
saveBitMap.CreateCompatibleBitmap(mfcDC, w, h)
saveDC.SelectObject(saveBitMap)
saveDC.BitBlt((0, 0), (w, h), mfcDC, (0, 0), win32con.SRCCOPY)
im = saveBitMap.GetBitmapBits(True) # Tried False also
img = np.frombuffer(im, dtype=np.uint8).reshape((h, w, 4))
cv2.imshow("demo", img)
cv2.waitKey(100)
beg = time.time()
for i in range(100):
window_capture()
end = time.time()
print(end - beg)
cv2.destroyAllWindows()