我想将像素从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替换小部件的画布,以避免每次都需要制作新的画布。