def _start_element(self, name, attrs): self._tag = name if self._first_tag: self._first_tag = False if self._tag != "dictionary": raise ValueError, "The very first tag should be <dictionary>" if self._tag == "character": self._writing = Writing() if self._tag == "stroke": self._stroke = Stroke() elif self._tag == "point": point = Point() for key in ("x", "y", "pressure", "xtilt", "ytilt", "timestamp"): if attrs.has_key(key): value = attrs[key].encode("UTF-8") if key in ("pressure", "xtilt", "ytilt"): value = float(value) else: value = int(float(value)) else: value = None setattr(point, key, value) self._stroke.append_point(point)
def to_stroke_collection(self, dictionary, silent=True): """ @type dictionary: L{CharacterStrokeDictionary """ strokecol = CharacterCollection() for char in self.get_all_characters_gen(): stroke_labels = dictionary.get_strokes(char.get_unicode())[0] strokes = char.get_writing().get_strokes(full=True) if len(strokes) != len(stroke_labels): if silent: continue else: raise ValueError, "The number of strokes doesn't " \ "match with reference character" for stroke, label in zip(strokes, stroke_labels): utf8 = label.encode("utf-8") strokecol.add_set(utf8) writing = Writing() writing.append_stroke(stroke) writing.normalize_position() schar = Character() schar.set_utf8(utf8) schar.set_writing(writing) strokecol.append_character(utf8, schar) return strokecol
def testWritingEqualityNone(self): s1 = Stroke() s1.append_point(Point(x=2, y=3)) s1.append_point(Point(x=3, y=4)) s2 = Stroke() s2.append_point(Point(x=2, y=3)) s2.append_point(Point(x=3, y=4)) w1 = Writing() w1.append_stroke(s1) w1.append_stroke(s2) self.assertTrue(w1 != None) self.assertFalse(w1 == None)
def testWritingCopy(self): s1 = Stroke() s1.append_point(Point(x=2, y=3)) s1.append_point(Point(x=3, y=4)) s2 = Stroke() s2.append_point(Point(x=2, y=3)) s2.append_point(Point(x=3, y=4)) w1 = Writing() w1.append_stroke(s1) w1.append_stroke(s2) w2 = w1.copy() self.assertTrue(w1 == w2)
def setDictionary(self, recognizerSettings={}): #self.clear_strokes() #initialize the default dictionary and a simple recognizer if recognizerType == 'tomoe' \ and 'tomoe' in recognizerSettings \ and 'dictionary' in recognizerSettings['tomoe']: tomoeDict = Dict("XML", filename=recognizerSettings['tomoe']['dictionary']) self.recognizer = Recognizer('Simple', dictionary=tomoeDict) # will encapsulate stroke data if not self.writing: self.writing = Writing() elif recognizerType == 'tegaki': recognizers = Recognizer.get_available_recognizers() if not recognizers: raise Exception('No recognizer available') if 'tegaki' in recognizerSettings \ and 'recognizer' in recognizerSettings['tegaki']: engine = recognizerSettings['tegaki']['recognizer'] if engine not in recognizers: raise Exception('recognizer not available') else: engine = recognizers.keys()[0] recognizer_klass = recognizers[engine] self.recognizer = recognizer_klass() if 'tegaki' in recognizerSettings \ and 'model' in recognizerSettings['tegaki']: model = recognizerSettings['tegaki']['model'] if model not in recognizer_klass.get_available_models(): raise Exception('Model not available') else: model = recognizer_klass.get_available_models().keys()[0] self.recognizer.set_model(model) # will encapsulate stroke data if not self.writing: self.writing = Writing() else: self.writing = None
def _getWriting(self): point = Point() point.x = 1 point.y = 2 point.timestamp = 3 point2 = Point() point2.x = 4 point2.y = 5 point2.pressure = 0.1 stroke = Stroke() stroke.append_point(point) stroke.append_point(point2) writing = Writing() writing.append_stroke(stroke) return writing
def _start_element(self, name, attrs): self._tag = name if self._first_tag: self._first_tag = False if self._tag != "kanjis": raise ValueError, "The very first tag should be <kanjis>" if self._tag == "kanji": self._writing = Writing() self._utf8 = attrs["midashi"].encode("UTF-8") if self._tag == "stroke": self._stroke = Stroke() if attrs.has_key("path"): self._stroke_svg = attrs["path"].encode("UTF-8") svg_parser = SVG_Parser(self._stroke_svg) svg_parser.parse() self._stroke.append_points(svg_parser.get_points()) else: sys.stderr.write("Missing path in <stroke> element: " + self._utf8 + "\n")
class KVGXmlDictionaryReader(_XmlBase): def __init__(self): self._charcol = CharacterCollection() def get_character_collection(self): return self._charcol def _start_element(self, name, attrs): self._tag = name if self._first_tag: self._first_tag = False if self._tag != "kanjis": raise ValueError, "The very first tag should be <kanjis>" if self._tag == "kanji": self._writing = Writing() self._utf8 = attrs["midashi"].encode("UTF-8") if self._tag == "stroke": self._stroke = Stroke() if attrs.has_key("path"): self._stroke_svg = attrs["path"].encode("UTF-8") try: svg_parser = SVG_Parser(self._stroke_svg) svg_parser.parse() self._stroke.append_points(svg_parser.get_points()) except: sys.stderr.write("Something went wrong in this character: " + self._utf8 + "\n") else: print "Missing path in <stroke> element: " + self._utf8 def _end_element(self, name): if name == "kanji": char = Character() char.set_utf8(self._utf8) char.set_writing(self._writing) self._charcol.add_set(self._utf8) self._charcol.append_character(self._utf8, char) for s in ["_tag", "_stroke"]: if s in self.__dict__: del self.__dict__[s] if name == "stroke": self._writing.append_stroke(self._stroke) self._stroke = None self._tag = None def _char_data(self, data): if self._tag == "utf8": self._utf8 = data.encode("UTF-8") elif self._tag == "width": self._writing.set_width(int(data)) elif self._tag == "height": self._writing.set_height(int(data))
def _start_element(self, name, attrs): self._tag = name if self._first_tag: self._first_tag = False if self._tag != "kanjivg": raise ValueError, "The very first tag should be <kanjivg>" if self._tag == "kanji": self._writing = Writing() self._utf8 = unichr(int(attrs["id"].split('_')[1], 16)).encode("UTF-8") if self._tag == "path": self._stroke = Stroke() if attrs.has_key("d"): self._stroke_svg = attrs["d"].encode("UTF-8") svg_parser = SVG_Parser(self._stroke_svg) svg_parser.parse() self._stroke.append_points(svg_parser.get_points()) else: sys.stderr.write("Missing data in <path> element: " + self._utf8 + "\n")
class KVGXmlDictionaryReader(_XmlBase): def __init__(self): self._charcol = CharacterCollection() def get_character_collection(self): return self._charcol def _start_element(self, name, attrs): self._tag = name if self._first_tag: self._first_tag = False if self._tag != "kanjivg": raise ValueError, "The very first tag should be <kanjivg>" if self._tag == "kanji": self._writing = Writing() self._utf8 = unichr(int(attrs["id"].split('_')[1], 16)).encode("UTF-8") if self._tag == "path": self._stroke = Stroke() if attrs.has_key("d"): self._stroke_svg = attrs["d"].encode("UTF-8") svg_parser = SVG_Parser(self._stroke_svg) svg_parser.parse() self._stroke.append_points(svg_parser.get_points()) else: sys.stderr.write("Missing data in <path> element: " + self._utf8 + "\n") def _end_element(self, name): if name == "kanji": char = Character() char.set_utf8(self._utf8) char.set_writing(self._writing) self._charcol.add_set(self._utf8) self._charcol.append_character(self._utf8, char) for s in ["_tag", "_stroke"]: if s in self.__dict__: del self.__dict__[s] if name == "path": self._writing.append_stroke(self._stroke) self._stroke = None self._tag = None def _char_data(self, data): if self._tag == "utf8": self._utf8 = data.encode("UTF-8") elif self._tag == "width": self._writing.set_width(int(data)) elif self._tag == "height": self._writing.set_height(int(data))
def testWritingEquality(self): s1 = Stroke() s1.append_point(Point(x=2, y=3)) s1.append_point(Point(x=3, y=4)) s2 = Stroke() s2.append_point(Point(x=2, y=3)) s2.append_point(Point(x=3, y=4)) w1 = Writing() w1.append_stroke(s1) w1.append_stroke(s2) s1 = Stroke() s1.append_point(Point(x=2, y=3)) s1.append_point(Point(x=3, y=4)) s2 = Stroke() s2.append_point(Point(x=2, y=3)) s2.append_point(Point(x=3, y=4)) w2 = Writing() w2.append_stroke(s1) w2.append_stroke(s2) s1 = Stroke() s1.append_point(Point(x=2, y=3)) s1.append_point(Point(x=3, y=4)) s2 = Stroke() s2.append_point(Point(x=2, y=3)) s2.append_point(Point(x=3, y=5)) w3 = Writing() w3.append_stroke(s1) w3.append_stroke(s2) self.assertEquals(w1, w2) self.assertNotEqual(w1, w3)
class KVGXmlDictionaryReader(_XmlBase): def __init__(self): self._charcol = CharacterCollection() def get_character_collection(self): return self._charcol def _start_element(self, name, attrs): self._tag = name if self._first_tag: self._first_tag = False if self._tag != "kanjivg": raise ValueError, "The very first tag should be <kanjivg>" if self._tag == "kanji": self._writing = Writing() self._utf8 = unichr(int(attrs["id"].split("_")[1], 16)).encode("UTF-8") if self._tag == "path": self._stroke = Stroke() if attrs.has_key("d"): self._stroke_svg = attrs["d"].encode("UTF-8") svg_parser = SVG_Parser(self._stroke_svg) svg_parser.parse() self._stroke.append_points(svg_parser.get_points()) else: sys.stderr.write("Missing data in <path> element: " + self._utf8 + "\n") def _end_element(self, name): if name == "kanji": char = Character() char.set_utf8(self._utf8) char.set_writing(self._writing) self._charcol.add_set(self._utf8) self._charcol.append_character(self._utf8, char) for s in ["_tag", "_stroke"]: if s in self.__dict__: del self.__dict__[s] if name == "path": self._writing.append_stroke(self._stroke) self._stroke = None self._tag = None def _char_data(self, data): if self._tag == "utf8": self._utf8 = data.encode("UTF-8") elif self._tag == "width": self._writing.set_width(int(data)) elif self._tag == "height": self._writing.set_height(int(data))
def testRemoveStroke(self): s1 = Stroke() s1.append_point(Point(x=2, y=3)) s1.append_point(Point(x=3, y=4)) s2 = Stroke() s2.append_point(Point(x=2, y=3)) s2.append_point(Point(x=3, y=4)) w = Writing() w.append_stroke(s1) w.append_stroke(s2) w.remove_stroke(1) self.assertEquals(w.get_strokes(), [[(2, 3), (3, 4)]])
def _start_element(self, name, attrs): self._tag = name if self._first_tag: self._first_tag = False if self._tag != "kanjivg": raise ValueError, "The very first tag should be <kanjivg>" if self._tag == "kanji": self._writing = Writing() self._utf8 = unichr(int(attrs["id"].split("_")[1], 16)).encode("UTF-8") if self._tag == "path": self._stroke = Stroke() if attrs.has_key("d"): self._stroke_svg = attrs["d"].encode("UTF-8") svg_parser = SVG_Parser(self._stroke_svg) svg_parser.parse() self._stroke.append_points(svg_parser.get_points()) else: sys.stderr.write("Missing data in <path> element: " + self._utf8 + "\n")
def testRemoveStroke(self): s1 = Stroke() s1.append_point(Point(x=2, y=3)) s1.append_point(Point(x=3, y=4)) s2 = Stroke() s2.append_point(Point(x=2, y=3)) s2.append_point(Point(x=3, y=4)) w = Writing() w.append_stroke(s1) w.append_stroke(s2) w.remove_stroke(1) self.assertEquals(w.get_strokes(), [[(2,3),(3,4)]])
def testReplaceStroke(self): s1 = Stroke() s1.append_point(Point(x=2, y=3)) s1.append_point(Point(x=3, y=4)) s2 = Stroke() s2.append_point(Point(x=2, y=3)) s2.append_point(Point(x=3, y=4)) w = Writing() w.append_stroke(s1) w.append_stroke(s2) s3 = Stroke() s3.append_point(Point(x=22, y=33)) s3.append_point(Point(x=33, y=44)) w.replace_stroke(1, s3) self.assertEquals(w.get_strokes(), [[(2, 3), (3, 4)], [(22, 33), (33, 44)]])
def testReplaceStroke(self): s1 = Stroke() s1.append_point(Point(x=2, y=3)) s1.append_point(Point(x=3, y=4)) s2 = Stroke() s2.append_point(Point(x=2, y=3)) s2.append_point(Point(x=3, y=4)) w = Writing() w.append_stroke(s1) w.append_stroke(s2) s3 = Stroke() s3.append_point(Point(x=22, y=33)) s3.append_point(Point(x=33, y=44)) w.replace_stroke(1, s3) self.assertEquals(w.get_strokes(), [[(2,3),(3,4)],[(22,33),(33,44)]])
def testDuration(self): point = Point() point.x = 1 point.y = 2 point.timestamp = 0 point2 = Point() point2.x = 4 point2.y = 5 point2.timestamp = 5 stroke = Stroke() stroke.append_point(point) stroke.append_point(point2) point3 = Point() point3.x = 1 point3.y = 2 point3.timestamp = 7 point4 = Point() point4.x = 4 point4.y = 5 point4.timestamp = 10 stroke2 = Stroke() stroke2.append_point(point3) stroke2.append_point(point4) self.assertEquals(stroke2.get_duration(), 3) writing = Writing() writing.append_stroke(stroke) writing.append_stroke(stroke2) self.assertEquals(writing.get_duration(), 10)
def get_character_collection(self): charcol = CharacterCollection() # group characters with the same label into sets sets = {} for i in range(len(self._labels)): # Create Character writing = Writing() if self.height and self.width: writing.set_height(self.height) writing.set_width(self.width) for delin_range in self._delineations[i]: if delin_range.start_comp == (delin_range.end_comp - 1): stroke_points = self._strokes[delin_range.start_comp][delin_range.start_point:delin_range.end_point] writing.append_stroke(Stroke.from_list(stroke_points)) else: # add first stroke to writing start_stroke_points = self._strokes[delin_range.start_comp][delin_range.start_point:-1] if len(start_stroke_points) > 0: writing.append_stroke(Stroke.from_list(start_stroke_points)) # add last stroke to writing end_stroke_points = self._strokes[delin_range.end_comp - 1][0:delin_range.end_point] if len(end_stroke_points) > 0: writing.append_stroke(Stroke.from_list(end_stroke_points)) # add the remaining strokes to writing for stroke in self._strokes[delin_range.start_comp + 1:delin_range.end_comp - 1]: writing.append_stroke(stroke) character = Character() character.set_writing(writing) utf8 = self._labels[i] character.set_utf8(utf8) sets[utf8] = sets.get(utf8, []) + [character] charcol.add_sets(sets.keys()) for set_name, characters in sets.items(): charcol.append_characters(set_name, characters) return charcol
def testNewWriting(self): writing = Writing() writing.move_to(0, 0) writing.line_to(1, 1) writing.line_to(2, 2) writing.line_to(3, 3) writing.move_to(4, 4) writing.line_to(5, 5) writing.move_to(6, 6) writing.line_to(7, 7) writing.line_to(8, 8) strokes = writing.get_strokes() expected = [[(0, 0), (1, 1), (2, 2), (3, 3)], [(4, 4), (5, 5)], [(6, 6), (7, 7), (8, 8)]] self.assertEquals(strokes, expected)
class LineDrawingGraphicsScene(QtGui.QGraphicsScene): """Graphics scene for drawing strokes and handling recognizer.""" def __init__(self, parent, recognizerSettings=None, size=100): QtGui.QGraphicsScene.__init__(self, parent) self.size = 100 self.writing = None # set pen for handwriting self.pen = QtGui.QPen() self.pen.setWidth(3) self.strokeItemGroups = [] self.currentStrokeItems = [] self.setSize(size) if recognizerSettings: self.setDictionary(recognizerSettings) def setDictionary(self, recognizerSettings={}): #self.clear_strokes() #initialize the default dictionary and a simple recognizer if recognizerType == 'tomoe' \ and 'tomoe' in recognizerSettings \ and 'dictionary' in recognizerSettings['tomoe']: tomoeDict = Dict("XML", filename=recognizerSettings['tomoe']['dictionary']) self.recognizer = Recognizer('Simple', dictionary=tomoeDict) # will encapsulate stroke data if not self.writing: self.writing = Writing() elif recognizerType == 'tegaki': recognizers = Recognizer.get_available_recognizers() if not recognizers: raise Exception('No recognizer available') if 'tegaki' in recognizerSettings \ and 'recognizer' in recognizerSettings['tegaki']: engine = recognizerSettings['tegaki']['recognizer'] if engine not in recognizers: raise Exception('recognizer not available') else: engine = recognizers.keys()[0] recognizer_klass = recognizers[engine] self.recognizer = recognizer_klass() if 'tegaki' in recognizerSettings \ and 'model' in recognizerSettings['tegaki']: model = recognizerSettings['tegaki']['model'] if model not in recognizer_klass.get_available_models(): raise Exception('Model not available') else: model = recognizer_klass.get_available_models().keys()[0] self.recognizer.set_model(model) # will encapsulate stroke data if not self.writing: self.writing = Writing() else: self.writing = None def enabled(self): #return True return self.writing != None # TODO bug ? def setSize(self, size): for group in self.strokeItemGroups: for item in group: self.removeItem(item) self.clear() self.setSceneRect(0, 0, size, size) # draw character grid self.setBackgroundBrush(QtCore.Qt.lightGray) self.addRect(-1, -1, size+2, size+2, QtCore.Qt.white, QtCore.Qt.white).setZValue(-1) self.addRect(0.1 * size, 0.1 * size, 0.8 * size, 0.8 * size) self.addLine(0.5 * size, 0.1 * size, 0.5 * size, 0.9 * size, QtGui.QPen(QtCore.Qt.DashLine)) self.addLine(0.1 * size, 0.5 * size, 0.9 * size, 0.5 * size, QtGui.QPen(QtCore.Qt.DashLine)) # recalculate drawn strokes scaleFactor = 1.0 * size / self.size for group in self.strokeItemGroups: for item in group: self.addItem(item) line = item.line() line.setLine(line.x1() * scaleFactor, line.y1() * scaleFactor, line.x2() * scaleFactor, line.y2() * scaleFactor) item.setLine(line) self.size = size def clear_strokes(self): """Removes all strokes and clears the drawing area.""" if self.strokeItemGroups: for group in self.strokeItemGroups: for item in group: self.removeItem(item) self.strokeItemGroups = [] if self.writing: self.writing.clear() def remove_last_stroke(self): """Removes the latest stroke.""" if self.strokeItemGroups: for item in self.strokeItemGroups.pop(): self.removeItem(item) if self.writing: self.writing.remove_last_stroke() def strokeCount(self): return self.writing.get_n_strokes() def doSearch(self, maxResults=10): """Searches for the current stroke input and returns the results.""" if self.writing and self.writing.get_n_strokes() > 0: if recognizerType == 'tomoe': res = self.recognizer.search(self.writing) if maxResults != None: res = res[:min(maxResults, len(res))] return [(r.get_char().get_utf8().decode('utf8'), r.get_score()) for r in res] elif recognizerType == 'tegaki': return [(c.decode('utf8'), score) for c, score \ in self.recognizer.recognize(self.writing, maxResults)] else: return [] def mouseReleaseEvent(self, mouseEvent): if mouseEvent.button() & QtCore.Qt.LeftButton: # left button released #pos = mouseEvent.scenePos() #self.keepBounds(pos) #self.writing.line_to(pos.x() * 1000 / self.size, #pos.y() * 1000 / self.size) self.strokeItemGroups.append(self.currentStrokeItems) self.currentStrokeItems = [] self.emit(QtCore.SIGNAL("strokeAdded()")) def mousePressEvent(self, mouseEvent): if mouseEvent.button() & QtCore.Qt.LeftButton: # left button pressed pos = mouseEvent.scenePos() self.keepBounds(pos) self.writing.move_to(int(pos.x() * 1000 / self.size), int(pos.y() * 1000 / self.size)) def mouseMoveEvent(self, mouseEvent): if mouseEvent.buttons() & QtCore.Qt.LeftButton: # mouse is moved with the left button hold down lastPos = mouseEvent.lastScenePos() self.keepBounds(lastPos) pos = mouseEvent.scenePos() self.keepBounds(pos) self.currentStrokeItems.append( self.addLine(QtCore.QLineF(lastPos, pos), self.pen)) # tomoe seems to use a 1000x1000 pixel grid self.writing.line_to(int(pos.x() * 1000 / self.size), int(pos.y() * 1000 / self.size)) def keepBounds(self, point): """Keep the coordinates inside the scene rectangle.""" point.setX(min(max(0, point.x()), self.size)) point.setY(min(max(0, point.y()), self.size))
def testNewWriting(self): writing = Writing() writing.move_to(0,0) writing.line_to(1,1) writing.line_to(2,2) writing.line_to(3,3) writing.move_to(4,4) writing.line_to(5,5) writing.move_to(6,6) writing.line_to(7,7) writing.line_to(8,8) strokes = writing.get_strokes() expected = [ [(0, 0), (1,1), (2,2), (3,3)], [(4,4), (5,5)], [(6,6), (7,7), (8,8)] ] self.assertEquals(strokes, expected)
class TomoeXmlDictionaryReader(_XmlBase): def __init__(self): self._charcol = CharacterCollection() def get_character_collection(self): return self._charcol def _start_element(self, name, attrs): self._tag = name if self._first_tag: self._first_tag = False if self._tag != "dictionary": raise ValueError, "The very first tag should be <dictionary>" if self._tag == "character": self._writing = Writing() if self._tag == "stroke": self._stroke = Stroke() elif self._tag == "point": point = Point() for key in ("x", "y", "pressure", "xtilt", "ytilt", "timestamp"): if attrs.has_key(key): value = attrs[key].encode("UTF-8") if key in ("pressure", "xtilt", "ytilt"): value = float(value) else: value = int(float(value)) else: value = None setattr(point, key, value) self._stroke.append_point(point) def _end_element(self, name): if name == "character": char = Character() char.set_utf8(self._utf8) char.set_writing(self._writing) self._charcol.add_set(self._utf8) self._charcol.append_character(self._utf8, char) for s in ["_tag", "_stroke"]: if s in self.__dict__: del self.__dict__[s] if name == "stroke": self._writing.append_stroke(self._stroke) self._stroke = None self._tag = None def _char_data(self, data): if self._tag == "utf8": self._utf8 = data.encode("UTF-8") elif self._tag == "width": self._writing.set_width(int(data)) elif self._tag == "height": self._writing.set_height(int(data))