Kivy 简明教程
Kivy - Gesture
Kivy 框架能够记录和识别手势。手势是由多点触控设备上的鼠标指针或手指生成的一系列触摸。kivy.gesture 模块定义了 Gesture 类,其对象通过 Kivy 画布上捕获的连续触摸事件的 (x,y) 坐标获得。Kivy 中的手势是 Oleg Dopertchouk 手势识别算法的 Python 实现。
同一个模块还具有 GestureDatabase 类。您可以在手势数据库中存储更多 Gesture 对象,并找出某个手势是否与已存储在数据库中的任何手势匹配。
若要创建 Gesture 对象,您需要一个 x、y 坐标列表。例如 −
from kivy.gesture import Gesture
g = Gesture()
g.add_stroke(point_list=[(1,1), (3,4), (2,1)])
g.normalize()
add_stroke() 方法从坐标对构造一个手势对象。normalize() 方法需要运行手势规范化算法并计算与 self 的点积。
此类 Gesture 对象存储在 GestureDatabase 中。
from kivy.gesture import Gesture, GestureDatabase
# Create a gesture
gdb = GestureDatabase()
gdb.add_gesture(g)
针对此数据库中存储的对象,您可以比较另一个对象并找出数据库中的任何手势是否匹配。
g2 = Gesture()
# ...
gdb.find(g2)
kivy.gesture 模块在 Gesture 类中定义了以下方法 −
-
add_stroke() − 从手势的触摸点列表构造一个笔触并返回 Stroke 实例。
-
normalize() − 运行手势规范化算法并计算与 self 的点积。
-
get_score() − 当一个手势与另一个手势匹配时,此方法返回匹配分数。
GestureDatabase 类具有以下重要方法:−
-
add_gesture() − 向数据库添加一个新的手势。
-
find() − 在数据库中查找匹配的手势。可以使用 min_score 参数定义查找精度。它应该介于 0 到 1 之间。
-
gesture_to_str(gesture) − 将手势转换为一个唯一字符串。
-
str_to_gesture(data) − 将一个唯一字符串转换为一个手势。
Example
我们定义 touch_down()、touch_move() 和 touch_up() 处理程序来捕获触点并从中绘制一个图案。带有其(touch.x 和 touch.y)坐标的所有点都收集在一个 List 中。
按 Add 按钮时,点 List 将用于构建一个 Gesture。gesture_to_string() 方法返回一个二进制字符串。
if instance.text=='Add':
g = Gesture()
g.add_stroke(point_list=Drawgesture.points)
g.normalize()
print (self.d.gdb.gesture_to_str(g))
self.d.gdb.add_gesture(g)
print (str(g))
手势字符串的一个示例可能如下所示 -
b'eNprYJmayc4ABj082ZlllXrpqcUlpUWpU3rY3aGsyVM0G6fUTtHoYS3PTCnJmOLuYO9kuU766IwetozUzPSMEqCIC9NEhiUOGj38UO3xBUX5KaXJICmhWZ/F3Pse9LAXlxTlZ6cWT4mdksHQwws1PRgsiLCDrSA/M68EpEgDqIoHqioAJIhQxFgxxX3/LdkuHrnEhh7Gyinu9g9vmvlOTnlRmpQhCFGTIQJXkSHqbn9/U85stZMXcMrfxiZ/TfZI/b2QH8TIXydH/pLsv8/zPDJA8pfJkT9jU3RuT/kBYuTPp4ACaAGq/AmbtU412Qo45Q/YKmn+CRIAyR+nUP4wWD4BVX5DtZ7Sj8IHIPltJ4EeUHdAlY9n/VPH/4ABJL92MtAAvwaS5O3n8Z6ZJZ8Gkt9fDLK/hwGn/CJQ8G1E078eZP5TB5D8RlDyunEAp/xOkPxNNPO3N3WGd3CD/Lf/AND4TTlo5u9vEingUAHLnwDLo4aP/eED54+4yH3AKX/8wNSAFu0JIPkzYHnU8Lc/fSDqzhELUPzuvwBynpkBqvz5AwqZLC4LQPJXwPKo4W9/8f6nX4s0iJK/hk3+6v0dbY9MNUDyNyiUvwNzf2oPT3FyUWpqHqKccHdIcNSwvsgQ4+5QGrZn4XqNnLYpyGJOuwTWtWijiultr197/w2qGNum2DXTs8FiE3XfGfUrYRcrubfWerXfa7DYQ+MFU2RfAsW2rZBcxQZWl2hoGfR1zXocYn2Lvq/Y+wosFmmjo1YijCq20vFeB9NNoFja3KvLS7NQxYJmuyy7qAkWu+iyfccpW6CY3YzNy3Qgen+6T3g5cQFQTGua0tKOVSCxJE9fZ2+FdKCY2OSJS55kgsUKA2Sqn59ydyh+15e/ePZLVLFb3fcWfV8JFpsJcrIuUOxYp++i4ExUsU1toIAGix0MPXe3bCJQbF6L9kKuF2CxlxEr+Gy/AMXK6jnnH8oAiSULRjfas4ajilnGReWf2Q0US6qpmC+nDhZLTAQGqhxQzK/y+bzKF6hiVuVhc6+uAIt1pvBcjG4EiqmVHJ1rmA4W25j2jEnpKQ4xoSKTOb3qKGJF/4BB8OI5SCyFMWdG8sbVOMRe5QrNdlmOKnYtq3HWArAdKZr5hVMq+ZHEUkuTEns4S/JzUosS85JTgTXUzpkgMKs0SQ8Ayq8zuw=='
您可以添加任意数量的手势。
然后,在画布上绘制一个图案,并尝试找出是否有什么手势与该图案匹配。当按 Find 按钮时,find() 方法完成这项工作。
if instance.text=='Find':
g=Gesture()
g.add_stroke(point_list=Drawgesture.points)
g.normalize()
g1=self.d.gdb.find(g, 0.65)
print (g1)
以下是用于手势识别练习的 complete code −
from kivy.app import App
from kivy.graphics import *
from kivy.uix.floatlayout import FloatLayout
from kivy.gesture import Gesture, GestureDatabase
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from random import random
from kivy.core.window import Window
Window.size = (720, 400)
class Drawgesture(Widget):
points = []
def __init__(self, *args, **kwargs):
super(Drawgesture, self).__init__()
self.gdb = GestureDatabase()
def on_touch_down(self, touch):
with self.canvas:
self.col = (random(), random(), random())
Color(self.col)
touch.ud["line"] = Line(points=(touch.x, touch.y), width=3)
Drawgesture.points.append((touch.x, touch.y))
def on_touch_move(self, touch):
with self.canvas:
Color(self.col)
touch.ud["line"].points += (touch.x, touch.y)
Drawgesture.points.append((touch.x, touch.y))
def on_touch_up(self, touch):
print('touch up')
class gestureApp(App):
def pressed(self, instance):
if instance.text == 'Add':
g = Gesture()
g.add_stroke(point_list=Drawgesture.points)
g.normalize()
print(self.d.gdb.gesture_to_str(g))
self.d.gdb.add_gesture(g)
print(str(g))
if instance.text == 'Find':
g = Gesture()
g.add_stroke(point_list=Drawgesture.points)
g.normalize()
g1 = self.d.gdb.find(g, 0.65)
print(g1)
if instance.text == 'Clear':
self.d.canvas.clear()
def build(self):
f = FloatLayout()
self.d = Drawgesture()
f.add_widget(self.d)
b1 = Button(
text='Add', pos_hint={'x': 0, 'y': 0},
size_hint=(None, None)
)
f.add_widget(b1)
b2 = Button(
text='Find', pos_hint={'x': .2, 'y': 0},
size_hint=(None, None)
)
f.add_widget(b2)
b3 = Button(
text='Clear', pos_hint={'x': .4, 'y': 0},
size_hint=(None, None)
)
f.add_widget(b3)
b1.bind(on_press=self.pressed)
b2.bind(on_press=self.pressed)
b3.bind(on_press=self.pressed)
return f
gestureApp().run()