在内存中处理Kivy帆布纹理



我想将像素从kivy帆布传递到keras模型(神经网络)。简单的方法是将图像导出到PNG,然后使用Scikit-image或PIL读取图像。问题是可以在没有这样冗余步骤的情况下在内存中完成吗?

这就是我想到的:

fbo = Fbo()
fbo.add(self.canvas)
fbo.draw()
img = Image.frombytes('RGBA', img_size, fbo.pixels)

为了检查一切是否有效,img被保存为PNG。不幸的是,事实证明这是一团糟。我的问题是如何使它正常工作?

这是复制/演示此问题的代码:

from PIL import Image
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.graphics import Line, Fbo
from kivy.uix.floatlayout import FloatLayout
class Painter(Widget):
    def on_touch_down(self, touch):
        with self.canvas:
            touch.ud['line'] = Line(points=(touch.x, touch.y), width=50)
    def on_touch_move(self, touch):
        touch.ud['line'].points += [touch.x, touch.y]
    def save(self, obj):
        fbo = Fbo()
        fbo.add(self.canvas)
        fbo.draw()
        img = Image.frombytes('RGBA', self.size, fbo.pixels)
        img.save('img.png')
class App(App):
    def build(self):
        layout = FloatLayout()
        painter = Painter()
        btn = Button(text='Save', on_release=painter.save, size_hint=(0.2,0.2))
        layout.add_widget(painter)
        layout.add_widget(btn)
        return layout
App().run()

每个kivy窗口小部件都有一个export_to_png方法,该方法允许保存该小部件的画布的png图像,因此可以使用FBO和PIL图像,您可以使用它。

类似的东西:

...
class Painter(Widget):
    ...
    def save(self, *args):
        self.export_to_png(filename='img')
    ...
...

您可以读取源以查看Widget.export_to_png的工作原理,然后自己使用类似的方法。具有纹理后,可能您可以从Pixels属性中获取所需的像素信息。

您也可以用FBO替换小部件的画布,以避免每次都需要制作新的画布。

最新更新