使用 BitmapBufferFormat_RGBA (python) 将 wx 位图转换为 numpy
Converting wx bitmap to numpy using BitmapBufferFormat_RGBA (python)
我正在尝试使用 wxPython 捕获 window 并使用 cv2 处理结果。这看起来相当简单,因为 wx 具有将位图对象转换为简单 RGB 数组的内置函数。
问题是我搞不懂语法。文档很少,我能找到的几个示例要么已弃用,要么不完整。
这基本上就是我想要的
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
为简单起见,这没有指定 window 并且只处理一个通道,但它应该让我了解我正在尝试做什么。
每当我尝试使用 CopyFromBuffer 运行 时,它会告诉我存储在 "b" 中的位图不是可读的缓冲区对象,但如果我将它传递给 SaveFile,它会写出图像符合预期。
不确定我做错了什么。
编辑:原来我做错的是试图使用 BitmapBufferFormat_RGBA 将 wxBitmaps 转换为 cv2 rgb。根据下面的答案,我应该使用以下内容(其中 "b" 是位图):
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
有一段时间没有这样做了:但是关于转换 numpy 数组的 OpenCV 位图 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(中间某处):
array = ... # the OpenCV image
image = ... # wx.Image
image.SetData(array.tostring())
wxBitmap = image.ConvertToBitmap() # OR: wx.BitmapFromImage(image)
编辑:反过来说:
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
获得者:
wxpython AttributeError: 'memoryview' object has no attribute '__buffer__'
解决方案是使用:
arr = np.asarray(img.GetDataBuffer())
img_data = np.copy(np.reshape(arr, (img.GetHeight(),img.GetWidth(),3)))
我正在尝试使用 wxPython 捕获 window 并使用 cv2 处理结果。这看起来相当简单,因为 wx 具有将位图对象转换为简单 RGB 数组的内置函数。
问题是我搞不懂语法。文档很少,我能找到的几个示例要么已弃用,要么不完整。
这基本上就是我想要的
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
为简单起见,这没有指定 window 并且只处理一个通道,但它应该让我了解我正在尝试做什么。
每当我尝试使用 CopyFromBuffer 运行 时,它会告诉我存储在 "b" 中的位图不是可读的缓冲区对象,但如果我将它传递给 SaveFile,它会写出图像符合预期。
不确定我做错了什么。
编辑:原来我做错的是试图使用 BitmapBufferFormat_RGBA 将 wxBitmaps 转换为 cv2 rgb。根据下面的答案,我应该使用以下内容(其中 "b" 是位图):
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
有一段时间没有这样做了:但是关于转换 numpy 数组的 OpenCV 位图 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(中间某处):
array = ... # the OpenCV image
image = ... # wx.Image
image.SetData(array.tostring())
wxBitmap = image.ConvertToBitmap() # OR: wx.BitmapFromImage(image)
编辑:反过来说:
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
获得者:
wxpython AttributeError: 'memoryview' object has no attribute '__buffer__'
解决方案是使用:
arr = np.asarray(img.GetDataBuffer())
img_data = np.copy(np.reshape(arr, (img.GetHeight(),img.GetWidth(),3)))