使用BitmapBufferFormat_RGBA(python)将wx位图转换为numpy

06odsfpq  于 2023-04-12  发布在  Python
关注(0)|答案(3)|浏览(244)

我尝试用wxPython捕获一个窗口,然后用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

为了简单起见,这并没有指定一个窗口,只处理一个通道,但它应该给予一个想法,我试图做什么。
每当我尝试使用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
qco9c6ql

qco9c6ql1#

有一段时间没有这样做了:但是一个OpenCV位图is essentially a numpy array。为了从一个通用数组创建一个wx.Bitmap,你必须采取wx.Image的路线。关于转换numpy数组,请参阅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
ndasle7k

ndasle7k2#

对于那些得到:

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

lyr7nygr3#

如果你想将wx.Bitmap图像转换为数组以使用open cv,你可以这样做:

img = bmp.ConvertToImage()
img_arr= np.reshape(np.frombuffer(img_1.GetDataBuffer(), dtype='uint8'), 
                   (bmp.GetHeight(), bmp.GetWidth(), 3))

相关问题