标题当然是唬人的,不过代码真的是50行正好(不算注释和空行啊),可以玩简单的数字识别。玩法很简单,先把附加的RData文件加载到R空间中(就是load("train.RData")这句),然后调用函数guess(),会打开一个空白的图形窗口。按住鼠标左键画一个0到9范围内的数字,然后右击鼠标确认,R会把猜测的结果输出出来。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | library(grid); getData = function() { pushViewport(viewport()); grid.rect(); px = NULL; py = NULL; mousedown = function(buttons, x, y) { if(buttons == 2) return(invisible(1)); eventEnv$onMouseMove = mousemove; NULL } mousemove = function(buttons, x, y) { px <<- c(px, x); py <<- c(py, y); grid.points(x, y); NULL } mouseup = function(buttons, x, y) { eventEnv$onMouseMove = NULL; NULL } setGraphicsEventHandlers(onMouseDown = mousedown, onMouseUp = mouseup); eventEnv = getGraphicsEventEnv(); cat("Click down left mouse button and drag to draw the number, right click to finish.\n"); getGraphicsEvent(); dev.off(); s = seq(0, 1, length.out = length(px)); spx = spline(s, px, n = 500)$y; spy = spline(s, py, n = 500)$y; return(cbind(spx, spy)); } traceCorr = function(dat1, dat2) { cor(dat1[, 1], dat2[, 1]) + cor(dat1[, 2], dat2[, 2]); } # recogTrain = list(); # for(i in 1:10) # { # recogTrain[[i]] = getData(); # } # save(recogTrain, file = "train.RData"); load("train.RData"); guess = function(verbose = FALSE) { test = getData(); coefs = sapply(recogTrain, traceCorr, dat2 = test); num = which.max(coefs); if(num == 10) num = 0; if(verbose) print(coefs); cat("I guess what you have input is ", num, ".\n", sep = ""); } |
有玩成功了的同志在评论里吼一嗓子啊(貌似4很难识别对),谢谢。
下载:train.RData
不错不错,但貌似只识别单个数字?
4和9不大灵光~~~
说下方法嘛,貌似是求相关系数找最大的?
你这不是猜出来了吗。
8稍写斜后,猜成了5. 其它都没什么问题。我看只能识别0到9,试了10,识别为0.是根据点的相对位置来识别?
确实只能是0到9,单个数字。
另外,这都几点了,赶紧去睡觉。
下午睡过头的伤不起啊
太牛了!
SAS的问题就多向你请教啦。
训练集是不是应该去的更多点呢~这样就会更容易识别了。
比如,可能由于手写习惯导致的0和6的难以区分,4和6,7和9~~
对啊,目前的训练集就是我自己的手迹。
我觉得如果化一次图中间可以间断(左键按一下),然后再画一笔,比如4和,这样更符合写字的习惯,识别的成功率更大,
报错,什么原因……
> guess()
Error in setGraphicsEventEnv(which, as.environment(list(...))) :
this graphics device does not support event handling
Ubuntu吗?
如果是的话,在
getData()的第一行加上X11(type = "Xlib"),并把if(buttons == 2)改成if(length(buttons) > 1)。OK~我写了4次8都被识别成了5

我发现无论字多小,多偏都能识别,看来不是用坐标值,根据什么值算的?没怎么用过spline……
试过了,发现还是有很多辨别出现错误的,比如很多都会误判为4 6等等,相信这个跟每个人的写法以及它的识别方法还是有关联的
对啊,哈哈,现在训练集里面只有我自己的笔迹,其实可以再补充一些的。不过反正这个只是一个演示,就没考虑那么多了。
哈哈,太牛啦