I'm a big fan of the $1 Unistroke Recognizer - it's just so cool that it works so well with minimal training. I was itching for a reason to use it and threw it into a flag semaphore decoder. Then I realized it was completely the wrong tool for drawings with only (8 choose 2) combinations where rotation does matter, and did something else instead. So, I'm still itching for a good reason to use it.
There's a good reason for that. Graffiti was....derivative of Unistroke, which was developed at PARC as, IIRC, part of the Parctab project. Xerox even sued.
Sorry, correction: «which works really well right now».
I still use Graffiti, on Android, as the only keyboard on almost all of my devices. (Exceptions are relevant to technical constraints - no touch, low framerate screens etc.)
It only works if the starting point of a gesture is as expected. If I start a rectangle in the top right corner then it is characterized as a caret. Only a start in the top left results in a rectangle.
Right, this is expected. I would think of a "gesture" as a series of points over time (relative to the starting point) - it is path dependent, so a clockwise circle is recognized differently from a counter-clockwise circle.
The paper (citation 11 for the $1 version) goes into more detail. One neat feature is rotation invariance, where you can draw a tilted version and still have it be recognized.
I added a second rectangle as an example starting from a different point, and it never misrecognized any of my rectangles for carets or square brackets again.
Adding left and right parenthesis started messing up with the square brackets, but then I added a couple more of each square and round brackets and it worked perfectly.
Differentiating from lowercase y and g was next to impossible, though...
Palm apparently had to change graffiti later to use multiple strokes for some letters, as someone had a patent on letter-recognition via single-stroke letters.
This varied a lot for me during testing - It looks like it's actually comparing rotations of the gesture to find a match
It would nail the zigzag and most of the star/box shapes even if I intentionally started in a different place (Very first thing I tested, I'm left handed and start characters/shapes in different places)
It did not handle shapes that are rotationally similar - ex: right square bracket starting from the bottom is always detected as left square bracket, probably because the gesture matches the left bracket, rotated 180 degrees.
It also flubs arrows going right to left (they always come up as v for me)
They all need to be drawn in the same direction of the demo. If I draw them in the opposite direction ( example the circle instead of counter-clockwise, I draw it clockwise ), another shape is recognised:
When I was a teenager playing Dr Kawashima's Brain Training on DS, I had to completely change how I drew my 9s in order to get it to recognise them (it turned out I started in the wrong place for it to recognise the number).
I only played that game for a month or two, but it stuck with me and now more than a decade later I still draw my 9s differently.
Well, it's not magic. It probably recognizes direction of strokes. I imagine that you can start from scratch and train both directions to be valid, but then you will find more mismatches.
I used it to integrate sketching into a web-based diagram editor ~10 years ago and it was a breeze. OK, I had to train it myself. But it takes only minutes to draw all the shape variants needed. In practice I used 6 shapes and about 5 variants per shape. I conducted a usability test and the $1 recognizer only failed to recognizes the sketches 2-3 times out of ~300 shapes drawn by different users with no additional training.
This might be obvious to everyone but me, but how do you read "$1" in this context? Do I read it as "one-dollar", or "dollar-sign one", something else? Thank you in advance
I recall experimenting with similar approaches about 2 decades ago; depending on your gestures you can actually simplify a lot:
- normalize the draw height/width
- use polar coordinates before normalizing
- normalize the length of the drawn path
- DAG to recognize shapes faster, using partial paths
- only taking into account corners with angles over a certain treshold
- ...
The possibilities are endless, and this is a good exercise to explain that slight alterations on your problem space can have a huge impact on your solution space.
In case anyone is interested, the $N-Protractor algorithm was ported to Python for use in the Kivy framework [0]. Unfortunately it's tied to kivy's clock among other things, but easy to rip it out should you need it in a different context. There is also anexample application that can be used to create gesture templates [1]
There is an improved version of this algorithm called $Q Super-Quick Recognizer [0] which allows multi-stroke gesture and drawing stroke in different direction, a demo I implemented before [1]
The $1 algorithm could be used to implement gesture typing keyboard like SwiftKey/Swype, where direction matters, eg another project of mine [2]
70 comments
[ 4.7 ms ] story [ 150 ms ] threadhttps://cristal.univ-lille.fr/~casiez/1euro/
https://news.ycombinator.com/item?id=12310029
Fun fact: You can implement a "classic" Unistroke recognizer just by dividing the character up into quadrants. Every glyph had a unique sequence of quadrant traversals. http://www.yorku.ca/mack/ExperimentSoftware/javadoc/ca/yorku...
> Every glyph had a unique sequence of quadrant traversals.
That's pretty clever.
https://en.wikipedia.org/wiki/Marching_squares
I really liked their products on so many levels, especially the build quality. I thought they would be around forever.
...which I’ve reimplemented in SQL (yes, SQL) a while ago: https://github.com/doersino/handwriting/blob/master/code/han...
The paper (citation 11 for the $1 version) goes into more detail. One neat feature is rotation invariance, where you can draw a tilted version and still have it be recognized.
Differentiating from lowercase y and g was next to impossible, though...
https://designobserver.com/media/images/Palmsmall_525.jpg
It would nail the zigzag and most of the star/box shapes even if I intentionally started in a different place (Very first thing I tested, I'm left handed and start characters/shapes in different places)
It did not handle shapes that are rotationally similar - ex: right square bracket starting from the bottom is always detected as left square bracket, probably because the gesture matches the left bracket, rotated 180 degrees.
It also flubs arrows going right to left (they always come up as v for me)
[0]: https://imgur.com/a/wfyoPLF
Triangle -> Delete / Caret
X -> Delete
Rectangle -> Caret
Circle -> Caret
Check -> Right square bracket / Arrow
Caret -> V
Zig-zag -> Zig-zag
Arrow -> V
Left square bracket -> Right square bracket
Right square bracket -> Left square bracket
V -> Caret
Delete -> X
Left curly bracket -> Right curly bracket
Right curly bracket -> Left curly bracket
Star -> Left curly bracket / Delete
Pigtail -> Delete
I only played that game for a month or two, but it stuck with me and now more than a decade later I still draw my 9s differently.
So I drew a heart.
Drawn clockwise, I get a carrot :).
So now I know what to send to my loved ones.
Drawn counter-clockwise, I get a square. And maybe where the carrot will be left to be.
https://detexify.kirelabs.org/classify.html
Setting aside OSI's definition of OSS, has this been explored as a OSS funding model?
Bruce Perens recently published some thoughts on that:
https://perens.com/2020/08/24/what-comes-after-open-source/
https://perens.com/2020/10/06/post-open-source-license-early...
- normalize the draw height/width
- use polar coordinates before normalizing
- normalize the length of the drawn path
- DAG to recognize shapes faster, using partial paths
- only taking into account corners with angles over a certain treshold
- ...
The possibilities are endless, and this is a good exercise to explain that slight alterations on your problem space can have a huge impact on your solution space.
[update - formatting]
[0] https://github.com/kivy/kivy/blob/master/kivy/multistroke.py
[1] https://github.com/kivy/kivy/tree/master/examples/demo/multi...
The $1 algorithm could be used to implement gesture typing keyboard like SwiftKey/Swype, where direction matters, eg another project of mine [2]
[0] http://depts.washington.edu/acelab/proj/dollar/qdollar.html
[1] https://github.com/wcchoi/dollar-q
[2] https://github.com/wcchoi/swell.sh