Kivy - 手势
Kivy 框架能够记录和识别手势。手势是鼠标指针或手指在多点触控设备上产生的一系列触摸。kivy.gesture 模块定义了 Gesture 类,其对象是通过 Kivy 画布上捕获的连续触摸事件的 (x,y) 坐标获得的。Kicy 中的 Gesture 是 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() 方法是运行手势规范化算法并计算自身点积所必需的。
此类 Gesture 对象存储在 GestureDatabase 中。
from kivy.gesture import Gesture, GestureDatabase # 创建手势 gdb = GestureDatabase() gdb.add_gesture(g)
针对存储在此数据库中的对象,您可以比较某个其他对象并查找数据库中的任何手势是否匹配。
g2 = Gesture() # ... gdb.find(g2)
kivy.gesture 模块在 Gesture 类中定义了以下方法 −
add_stroke() − 从触摸点列表构造一个笔触到手势并返回 Stroke 实例。
normalize() − 运行手势规范化算法并计算与自身的点积。
get_score() − 当一个手势与另一个手势匹配时,此方法返回匹配分数。
GestureDatabase 类具有以下重要方法 −
add_gesture() − 向数据库添加新手势。
find() − 在数据库中查找匹配的手势。您可以使用 min_score 参数定义查找的精度。它应该在 0 到 1 之间。
gesture_to_str(gesture) − 将手势转换为唯一字符串。
str_to_gesture(data) − 将唯一字符串转换为手势。
示例
我们定义 touch_down()、touch_move() 和 touch_up() 处理程序来捕获触摸点并从中绘制图案。所有点及其(touch.x 和 touch.y)坐标都收集在一个列表中。
按下添加按钮时,点列表用于构造手势。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() 方法会执行此工作。
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)
这是手势识别练习的完整代码 −
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()
输出
如果匹配存储大于或等于 min_score 参数,您将得到以下结果 −
(0.7093289348205829, <kivy.gesture.Gesture object at 0x000001B817C70490>)