问题
I'm trying to capture a window with wxPython and process the result with cv2. This seems fairly straight forward as wx has a built in function to convert a bitmap object to a simple RGB array.
The problem is that I can't figure out the syntax. The documentation is sparse and the few examples I can find are either deprecated or incomplete.
Here's basically what I want
app = wx.App(False)
img = some_RGBA_array #e.g. cv2.imread('some.jpg')
s = wx.ScreenDC()
w, h = s.Size.Get()
b = wx.EmptyBitmap(w, h)
m = wx.MemoryDCFromDC(s)
m.SelectObject(b)
m.Blit(0, 0, w, h, s, 0, 0)
m.SelectObject(wx.NullBitmap)
b.CopyFromBuffer(m, format=wx.BitmapBufferFormat_RGBA, stride=-1)#<----problem is here
img.matchSizeAndChannels(b)#<----placeholder psuedo
img[:,:,0] = np.where(img[:,:,0] >= 0, b[:,:,0], img[:,:,0])#<---copy a channel
For simplicity this doesn't specify a window and only processes one channel but it should give an idea of what I'm attempting to do.
Whenever I try to run it like that using CopyFromBuffer it tells me that the bitmap stored in "b" isn't a readable buffer object yet if I pass it to SaveFile it writes out the image as expected.
Not sure what I'm doing wrong here.
EDIT: Turns out what I'm doing wrong is trying to use BitmapBufferFormat_RGBA to convert wxBitmaps to cv2 rgb's. As per the answer below I should use the following (where "b" is the bitmap):
wxB = wx.ImageFromBitmap(b)#input bitmap
buf = wxB.GetDataBuffer()
arr = np.frombuffer(buf, dtype='uint8',count=-1, offset=0)
img2 = np.reshape(arr, (h,w,3))#convert to classic rgb
img2 = cv2.cvtColor(img2, cv2.COLOR_RGB2BGR)#match colors to original image
回答1:
Haven't done this for some while: But an OpenCV bitmap is essentially a numpy array. And for creating a wx.Bitmap
from a generic array you'll have to take the wx.Image
route. See the entry from the wxPython wiki (somewhere in the middle) regarding converting numpy arrays:
array = ... # the OpenCV image
image = ... # wx.Image
image.SetData(array.tostring())
wxBitmap = image.ConvertToBitmap() # OR: wx.BitmapFromImage(image)
EDIT: And to go the other way round:
import numpy
img = wx.ImageFromBitmap(wxBitmap)
buf = img.GetDataBuffer() # use img.GetAlphaBuffer() for alpha data
arr = numpy.frombuffer(buf, dtype='uint8')
# example numpy transformation
arr[0::3] = 0 # turn off red
arr[1::3] = 255 # turn on green
回答2:
for those who get:
wxpython AttributeError: 'memoryview' object has no attribute '__buffer__'
the solution is to use:
arr = np.asarray(img.GetDataBuffer())
img_data = np.copy(np.reshape(arr, (img.GetHeight(),img.GetWidth(),3)))
来源:https://stackoverflow.com/questions/32995679/converting-wx-bitmap-to-numpy-using-bitmapbufferformat-rgba-python