显示Kivy一个numpy的阵列 [英] Display a numpy array in Kivy

查看:963
本文介绍了显示Kivy一个numpy的阵列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我完全新kivy,所以我挣扎了一下。

我想显示在kivy窗口numpy的数组。
到目前为止,我想通了,这应该用结构类(的http:// kivy .ORG /文档/ API-kivy.graphics.texture.html )。

至于不时我numpy的阵列的变化,我想调整以下code到我的申请。

#创建一个64×64的质感,默认为RGB / UBYTE
质地= Texture.create(大小=(64,64))#创建64×64 RGB选项卡,然后从0至255与填充值
#我们必须从黑到白的渐变
大小= 64 * 64 * 3
BUF = [对于x INT(X * 255 /尺寸)的范围(大小)]#那么,该数组转换为字符串UBYTE
BUF = B''。加入(图(CHR,BUF))然后#blit的缓冲区
texture.blit_buffer(BUF,colorfmt =RGB,bufferfmt ='UBYTE')# 就这样 !现在你可以在你的显卡使用它:)
#如果自身是一个小部件,你可以这样做
与self.canvas:
    矩形(纹理质地=,= POS self.pos,大小=(64,64))

似乎创造的质地和改变工作,因为它应该,但我不明白,如何显示纹理。

任何人都可以向我解释,如何使用

与self.canvas:
    矩形(纹理质地=,= POS self.pos,大小=(64,64))

在某种程度上,我能看到我的照片/ numpy的数组。

非常感谢提前!
Holzroller

编辑:
我想通了,使用Kivy 1.8.0和结构类是有点乱。所以我升级到Kivy通过GitHub的1.9.0(通过安装Kivy apt-get的在Ubuntu 14.04 LTS为您供应的1.8.0版本),我能看到纹理使用以下code。我希望帮助谁是有同样的问题,人民我。

从kivy.graphics.texture进口纹理
从kivy.graphics进口矩形
从kivy.uix.widget进口的Widget
从kivy.base进口runTouchApp
从阵列导入阵列
从kivy.core.window导入窗口
#创建一个64×64的质感,默认为RGB / UBYTE
质地= Texture.create(大小=(1280,1024),colorfmt =RGB)#创建64×64 RGB选项卡,然后从0至255与填充值
#我们必须从黑到白的渐变
大小= 1280 * 1024 * 3
BUF = [对于x INT(X * 255 /尺寸)的范围(大小)]#那么,该数组转换为字符串UBYTE
ARR =阵列('B',BUF)
#BUF = B''。加入(图(CHR,BUF))然后#blit的缓冲区
texture.blit_buffer(ARR,colorfmt =RGB,bufferfmt ='UBYTE')# 就这样 !现在你可以在你的显卡使用它:)
#如果自身是一个小部件,你可以这样做
根=小工具()
与root.canvas:
    矩形(纹理=质地,POS =(0,0),大小=(1280 * 3 1024 * 3))runTouchApp(根)

EDIT2:
基本上我回到原来的问题:
我有一个numpy的阵列(类型'numpy.ndarray'; DTYPEUINT8'),我试图把它转换成一种格式,以便纹理会告诉我的形象。我试图打破它以同样的方式它是在例如code I贴上面完成。但遗憾的是我不能正常工作。我真的不知道我在做什么错在这里。
(我numpy的阵列是所谓的folling code IM2)

list1的= numpy.array(IM2).reshape(-1)。了ToList()ARR =阵列(B,list1的)texture.blit_buffer(ARR,colorfmt =RGB,bufferfmt ='UBYTE')


解决方案

numpy的有的ToString()属性,你可以直接使用,如果源数组是UINT8类型。你甚至都不需要重塑:

 纹理= Texture.create(大小=(16,16),colorfmt =RGB))
ARR = numpy.ndarray(形状= [16,16,3],DTYPE = numpy.uint8)
#填写你numpy的阵列这里
数据= arr.tostring()
texture.blit_buffer(数据,bufferfmt =UBYTE,colorfmt =RGB

关于你的评论在说这个问题,我看到2点:


  1. 确保从ROS回调堪称mainthread。也许该更新被忽略。

  2. 当你手动更改就地质地,使用它不被通知关联的对象,你需要做的。添加self.canvas.ask_update(),以确保在下一帧画布重新显示。

first of all, I'm totally new to kivy, so I'm struggling a bit.

I'm trying to display a numpy array in a kivy window. So far i figured out that this should work using the Texture Class (http://kivy.org/docs/api-kivy.graphics.texture.html).

As my numpy array changes from time to time, I'm trying to adjust the following code to my application.

# create a 64x64 texture, defaults to rgb / ubyte
texture = Texture.create(size=(64, 64))

# create 64x64 rgb tab, and fill with values from 0 to 255
# we'll have a gradient from black to white
size = 64 * 64 * 3
buf = [int(x * 255 / size) for x in range(size)]

# then, convert the array to a ubyte string
buf = b''.join(map(chr, buf))

# then blit the buffer
texture.blit_buffer(buf, colorfmt='rgb', bufferfmt='ubyte')

# that's all ! you can use it in your graphics now :)
# if self is a widget, you can do this
with self.canvas:
    Rectangle(texture=texture, pos=self.pos, size=(64, 64))

It seems that creating the texture and changing it works as it should, but i dont get, how to display the texture.

Can anybody explain to me, how to use the

with self.canvas:
    Rectangle(texture=texture, pos=self.pos, size=(64, 64))

in a way, that I get to see my picture/numpy array.

Thanks alot in advance! Holzroller

Edit: I figured out that using Kivy 1.8.0 and the Texture Class is a bit messy. So I upgraded to Kivy 1.9.0 via github (installing Kivy via apt-get in Ubuntu 14.04 LTS serves you the 1.8.0 version) and I get to see the Texture using the following code. I hope that helps people who are having the same problem as me.

from kivy.graphics.texture import Texture
from kivy.graphics import Rectangle
from kivy.uix.widget import Widget
from kivy.base import runTouchApp
from array import array
from kivy.core.window import Window


# create a 64x64 texture, defaults to rgb / ubyte
texture = Texture.create(size=(1280, 1024), colorfmt='rgb')

# create 64x64 rgb tab, and fill with values from 0 to 255
# we'll have a gradient from black to white
size = 1280 * 1024 * 3
buf = [int(x * 255 / size) for x in range(size)]

# then, convert the array to a ubyte string
arr = array('B', buf)
# buf = b''.join(map(chr, buf))

# then blit the buffer
texture.blit_buffer(arr, colorfmt='rgb', bufferfmt='ubyte')

# that's all ! you can use it in your graphics now :)
# if self is a widget, you can do this
root = Widget()
with root.canvas:
    Rectangle(texture=texture, pos=(0, 0), size=(1280*3, 1024*3))

runTouchApp(root)

Edit2: Basically I'm back to the original Problem: I have a numpy array (type 'numpy.ndarray'; dtype 'uint8') and I'm trying to convert it into a format, so that the texture will show me the image. I tried to break it down to the same way it is done in the example code i posted above. But i sadly doesn't work. I really do not know what I'm doing wrong here. (my numpy array is called im2 in the folling code)

list1 = numpy.array(im2).reshape(-1,).tolist()

arr = array('B', list1)

texture.blit_buffer(arr, colorfmt='rgb', bufferfmt='ubyte')

解决方案

Numpy have a tostring() attribute, that you could use directly, if the source array is uint8 type. You don't even need to reshape:

texture = Texture.create(size=(16, 16), colorfmt="rgb"))
arr = numpy.ndarray(shape=[16, 16, 3], dtype=numpy.uint8)
# fill your numpy array here
data = arr.tostring()
texture.blit_buffer(data, bufferfmt="ubyte", colorfmt="rgb"

About the issue you're talking in the comment, i see 2 points:

  1. Ensure the callback from the ROS is called in the mainthread. Maybe the update is simply ignored.
  2. When you manually change inplace the texture, the associated object that use it are not notified, you need to do it. Add a self.canvas.ask_update() to ensure the canvas redisplay at the next frame.

这篇关于显示Kivy一个numpy的阵列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆