我一直在尝试创建一个kivy相机扫描仪从许多来源(我会使用zbarcam如果我可以,但花园.xcamera模块不会导入,因此我正在尝试创建类似的内容)。在
问题是相机不能连续读取或更新纹理,也没有一种方法可以让我从相机捕捉一帧又一帧的图像。这意味着我只在初始化时得到纹理。在
首先,我试着安排一个每0.5秒更新一次纹理实例的事件。我无法获取相机的纹理实例,因为在加载相机时有一些延迟,这导致了一个错误。
其次,我在kv字符串中创建了一个on_texture
事件,但它只在初始化时读取纹理。
第三,我稍后在python脚本中尝试绑定on_texture
事件,方法是创建一个绑定函数并将其作为调度事件调用。它甚至没有得到实例。
第四,我created_triggers
和ask_update(callbacks)
事件,但是在相机实例化崩溃脚本之前,脚本再次加载到fast。
第五,我注意到有一个kivy.core.video
模块包含一个on_frame
属性。我重新编写了脚本以将其与kivy.uix.video
模块结合使用,但注意到如果不先加载视频文件,视频就无法运行。在
import kivy
import gi
kivy.require('1.11.1')
gi.require_version('Gst', '1.0')
from collections import namedtuple
from PIL import Image
from kivy.app import App
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ListProperty, ObjectProperty
from kivy.uix.camera import Camera
import time
from gi.repository import Gst
import pyzbar.pyzbar
from kivy.uix.modalview import ModalView
Builder.load_string('''
#: import Window kivy.core.window.Window
<ScanPreview>:
auto_dismiss: False
size_hint_x: 0.6
size_hint_y: None
height: Window.height / 9
pos_hint: {'top':0.7, 'x': 0.1}
background_normal: ''
background_color: (1, 1, 1, 0)
background: 'white.png'
Label:
id: sc_data
text: 'See me...'
<ScanCamera>:
orientation: 'vertical'
The_Camera:
id: camera
resolution: root.resolution
on_texture: root._on_texture(camera)
ToggleButton:
text: 'Stop'
on_press: camera.play = not camera.play
size_hint_y: None
height: '48dp'
''')
class ScanPreview(ModalView):
pass
class The_Camera(Camera):
pass
class ScanCamera(BoxLayout):
resolution = ListProperty([640, 480])
symbols = ListProperty([])
code_types = ListProperty(set(pyzbar.pyzbar.ZBarSymbol))
cam_cam = ObjectProperty(The_Camera())
the_preview = ObjectProperty(ScanPreview())
Symb = namedtuple('Symb', ['type','data'])
def __init__(self, **kwargs):
super(ScanCamera, self).__init__(**kwargs)
self.cam_cam.play = True
def _on_texture(self, instance):
#source: https://github.com/kivy-garden/garden.zbarcam/blob/develop
#/zbarcam/zbarcam.py
print(instance)
if not instance.texture == None:
print(instance.texture)
self.symbols = self._detect_qrcode_frame(
texture=instance.texture, code_types=self.code_types)
def _detect_qrcode_frame(cls, texture, code_types):
image_data = texture.pixels
size = texture.size
#source: https://github.com/kivy-garden/garden.zbarcam/blob/develop
#/zbarcam/zbarcam.py
# Fix for mode mismatch between texture.colorfmt and data returned
#by
# texture.pixels. texture.pixels always returns RGBA, so that
#should
# be passed to PIL no matter what texture.colorfmt returns. refs:
# https://github.com/AndreMiras/garden.zbarcam/issues/41
pil_image = Image.frombytes(mode='RGBA', size=size,
data=image_data)
symbols = []
print(pil_image)
print(size)
print(texture.tex_coords)
print(texture.target)
codes = pyzbar.pyzbar.decode(pil_image, symbols=code_types)
for code in codes:
symbol = CameraClick.Symb(type=code.type, data=code.data)
symbols.append(symbol)
print(symbols)
return symbols
class TestCamera(App):
title = 'Scan Camera'
def build(self):
return ScanCamera()
def on_stop(self):
cc = The_Camera()
print('Stop')
cc.play = False
def on_pause(self):
return True
def on_resume(self):
pass
TestCamera().run()
相机的纹理必须不断更新,这将允许pyzbar和PIL模块解码纹理?在
我不知道这是怎么做到的,但当我回答了我自己的问题时,我会把答案贴出来并做上标记。在
回答
因此,我通过使用下面的示例代码:https://kivy-fork.readthedocs.io/en/latest/_modules/kivy/uix/camera.html并混入zbarcam的一些函数来解决我的问题。
通过在
on_texture
调用中使用self.canvas.ask_update()
,它将更新texture
。我已经添加到代码,它现在不断更新纹理,并将条形码打印到一个切换按钮。目前我已经在Ubuntu仿生海狸上测试过了。本周末将在android上进行测试。在答案代码
相关问题 更多 >
编程相关推荐