我需要为一个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更快,但是肯定还有更简单的方法吗?
编辑:确定,所以使用注释并对进行一些研究,我现在可以直接访问位图数据,如下所示:
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的方法
发布于 2021-07-09 01:51:20
我只会展示对我有用的代码。
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()https://stackoverflow.com/questions/40098142
复制相似问题