gpt4 book ai didi

python - OpenCV:imdecode 内存中的图像返回无

转载 作者:行者123 更新时间:2023-12-02 17:04:07 31 4
gpt4 key购买 nike

回答编辑:Dima 解决了我的问题,我不必要地调用 cv2.decode 来获取可以直接传递给 OpenCV 的数据。

首先,我对 Python 和 OpenCV 还很陌生,所以如果我遗漏了一些明显的东西,我很抱歉,我几乎可以肯定我是。我正在尝试使用 Python 从特定窗口中获取屏幕截图,然后将其传递给 OpenCV。如果我将屏幕截图写到磁盘然后读回来,一切都很好,但是因为我想每秒分析多个屏幕截图,等待磁盘 IO 似乎很愚蠢。不幸的是,我花了大约 4 个小时来尝试我想出的所有东西,但没有任何东西可以解决问题。这是我的代码:

from PIL import ImageGrab
from PIL import Image
import win32gui
import win32ui
from ctypes import windll
import os
import time
import cv2
import numpy as np
from matplotlib import pyplot

def enumHandler(hwnd, lParam):
if win32gui.IsWindowVisible(hwnd):
if 'Sword' in win32gui.GetWindowText(hwnd):
lParam.append(hwnd)

def screenGrab(rect):
im = ImageGrab.grab(rect)
im.save(os.getcwd() + '\\game__' + str(int(time.time())) +
'.png', 'PNG')

def main():
hwnds = []
win32gui.EnumWindows(enumHandler, hwnds)
rect = win32gui.GetWindowRect(hwnds[0])
w = rect[2] - rect[0]
h = rect[3] - rect[1]

hwndDC = win32gui.GetWindowDC(hwnds[0])
mfcDC = win32ui.CreateDCFromHandle(hwndDC)
saveDC = mfcDC.CreateCompatibleDC()

saveBitMap = win32ui.CreateBitmap()
saveBitMap.CreateCompatibleBitmap(mfcDC, w, h)

saveDC.SelectObject(saveBitMap)

result = windll.user32.PrintWindow(hwnds[0], saveDC.GetSafeHdc(), 0)
bmpinfo = saveBitMap.GetInfo()
bmpstr = saveBitMap.GetBitmapBits(True)

im = Image.frombuffer('RGB', (bmpinfo['bmWidth'], bmpinfo['bmHeight']), bmpstr, 'raw', 'BGRX', 0, 1)

im.save('thistest.png')

img = cv2.imread('thistest.png', cv2.IMREAD_UNCHANGED)

if img is not None:
print(img.shape)
print(type(img))
cv2.imshow('FRAME', img)
cv2.waitKey()

im2 = np.frombuffer(bmpstr, dtype='uint8')

im2.shape = (bmpinfo['bmHeight'], bmpinfo['bmWidth'], 4)

img2 = cv2.imdecode(im2, cv2.IMREAD_GRAYSCALE)
if img2 is not None:
print(img2.shape)
print(type(img2))
cv2.imshow('FRAME', img2)
cv2.waitKey()

win32gui.DeleteObject(saveBitMap.GetHandle())
saveDC.DeleteDC()
mfcDC.DeleteDC()
win32gui.ReleaseDC(hwnds[0], hwndDC)

if __name__ == '__main__':
main()

唯一让我印象深刻的是,如果我打印出 bmpstr 的大小/形状,它会显示类似 1000,1600,3 的内容。但是,在使用 numpy.frombuffer 后,我无法 reshape 为 1000,1600,3 而是必须使用 4 因为它会提示大小。当查看 bmpstr 的 len 时,它会显示 ~6400000,所以数学是有意义的,你需要“4”维度,但 bmpstr 显示与 3 相同的大小。我认为这意味着 bmpstr 从 0 开始计数,很好,但为什么可以'我对 numpy.shape/reshape 做同样的事情吗?

无论如何,这是我对出了什么问题的唯一猜测,并且可能完全偏离了基础。任何帮助表示赞赏。

编辑:我相信 Dima 在正确的轨道上指出我需要从 RGB 转换为 BGR。不幸的是,我尝试了多种方法,但仍然无法完成这项工作。这是我当前的代码。如果我取消注释 im.save,则图像写入成功。
from PIL import Image
import win32gui
import win32ui
from ctypes import windll
import os
import time
import cv2
import numpy as np
from matplotlib import pyplot

def enumHandler(hwnd, lParam):
if win32gui.IsWindowVisible(hwnd):
if 'Sword' in win32gui.GetWindowText(hwnd):
lParam.append(hwnd)

def main():
hwnds = []
win32gui.EnumWindows(enumHandler, hwnds)
rect = win32gui.GetWindowRect(hwnds[0])
w = rect[2] - rect[0]
h = rect[3] - rect[1]

hwndDC = win32gui.GetWindowDC(hwnds[0])
mfcDC = win32ui.CreateDCFromHandle(hwndDC)
saveDC = mfcDC.CreateCompatibleDC()
saveBitMap = win32ui.CreateBitmap()
saveBitMap.CreateCompatibleBitmap(mfcDC, w, h)
saveDC.SelectObject(saveBitMap)
result = windll.user32.PrintWindow(hwnds[0], saveDC.GetSafeHdc(), 0)
if (result):
bmpinfo = saveBitMap.GetInfo()
bmpstr = saveBitMap.GetBitmapBits(True)
im = Image.frombuffer('RGB', (bmpinfo['bmWidth'], bmpinfo['bmHeight']), bmpstr, 'raw', 'BGRX', 0, 1)

#im.save('thistest.png')

im2 = np.array(im)
#im2 = im2[..., :2]
im2 = im2[:, :, ::-1].copy()
img2 = cv2.imdecode(im2, cv2.IMREAD_UNCHANGED)

if img2 is not None:
cv2.imshow('FRAME', img2)
cv2.waitKey()
else:
print('img2 was empty')

win32gui.DeleteObject(saveBitMap.GetHandle())
saveDC.DeleteDC()
mfcDC.DeleteDC()
win32gui.ReleaseDC(hwnds[0], hwndDC)

if __name__ == '__main__':
main()

最佳答案

只要你有im ,其类型为 PIL.Image ,您可以立即将其转换为 numpy,从而像这样的 OpenCV

img = np.array(im)
# In case it is needed to get rid of alpha channel, if it is present
img = img[..., :2]
# To convert RGB to BGR
img = img[:, :, ::-1].copy()
cv2.imshow('FRAME', img)
cv2.waitKey()

一般来说,使用 PIL解码图像然后 OpenCV 处理它们是一种常见的做法。

关于python - OpenCV:imdecode 内存中的图像返回无,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57383269/

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