gpt4 book ai didi

python - 快速截图 Winapi 和 Opencv

转载 作者:行者123 更新时间:2023-12-05 07:47:04 32 4
gpt4 key购买 nike

我需要为我正在处理的 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 更快,但肯定有更简单的方法吗?

编辑: 好吧,使用评论并对 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 的方法

最佳答案

我只会展示适合我的代码。

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()

关于python - 快速截图 Winapi 和 Opencv,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40098142/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com