牙叔教程 简单易懂
待识别的图片
图片中的字符没有连接, 都是独立的,
我们按照之前的教程 https://www.yuque.com/yashujs/bfug6u/twgwg2 , 一步一步试试效果
第一步: 绘制轮廓
第二步: 分割数字
可以看到错了
第三步: 分析哪里搞错了
把找到的轮廓绘制出来, 一个一个的看轮廓, 发现0那个位置有两个轮廓,
因此, 我们把轮廓改一下
修改之前: Imgproc.RETR_LIST 检测所有的轮廓,包括内围、外围轮廓
Imgproc.findContours(binary, contours, hierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE, Point());
修改之后: RETR_EXTERNAL:只检测最外围轮廓
Imgproc.findContours(binary, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE, Point());
0 有内外两个轮廓, 这就是出错的原因,
修改之后再次切割字符
这下就对了;
如法炮制, 把0-9都提取出来
第三步: 提取指纹
1的指纹是这样的
明显不是1
我们看看代码哪里不合适
原来放大图片使用的resize, 统一宽29, 高29,
let newImg = images.resize(img, [29]);
现在我们改成scale
let newImg = images.scale(img, scale, scale);
再次查看数字1的指纹, 这是1的灰度图
自适应二值化后是一片全黑, 因此, 不能用自适应二值化, 因为前景和背景明暗类似,
我们需要指定合适的阈值,
在二值化中有一个步骤是matToStr
在这一步又报错了, 原来代码是正方形, 宽高颠倒不会报错,
现在宽高不一样, 要明确那个是宽, 那个是高
rows是高, row是行的意思, 有图片有多少行, 就有多高
cols是宽, column是列的意思, 图片有多少列, 就有多宽
let h = mat.rows(); log("h = " + h); // h = 62 let w = mat.cols(); log("w = " + w); // w = 29
我们遍历图片像素是从左往右, 从上往下, 那么双循环的时候,
内部循环是从左往右, 用列, cols;
外部循环是从上往下, 用行, rows;
function mat2Str(mat) { let h = mat.rows(); let w = mat.cols(); let lines = new Array(h); for (var i = 0; i < h; i++) { let line = new Array(w); for (var j = 0; j < w; j++) { // double[] get(int row,int col) let item = mat.get(i, j); let value = item[0]; line[j] = value; } lines[i] = line.join(""); } let content = lines.join("\n"); return content; }
数字1太长了, 我们展示 万 的指纹
二值化阈值153, 通过不同的阈值测试, 这个数值效果最佳, 仅针对当前图片;
如果你要用别的图片, 要自己选择合适的阈值
var thresholdImg = images.threshold(grayImg, 153, 1, "BINARY");
OK, 到这里大部分东西都弄完了, 然后就可以开始弄识别了
然后开始测试识别率, 那家伙感天动地, 基本一个都不对!!
燃后查看哪里不对, 经过n个时长的排查, 距离有问题,
之前的比较字符串距离使用的是汉明距离, 汉明距离是计算两个长度相等的字符串,
刚才我们把图片放大从resize改为了scale, 那么字符串长度就不相等了,
所有我又百度了一下, 比较不同长度字符串的方法, 查到一个 莱文斯坦算法;
但是速度太慢了, 完全接受不了, 平均时间 3 秒
这还搞个锤子
还是比较图片相似度吧, so级别的速度, 这样的话, 我们就不用提取指纹了, 直接比较原图的相似度, 都不用灰度化了
来比较图片相似度
报错了, 群里问问别人为啥报错, @宴西 说两张图片宽高要一样 , 改成同样的宽高, 果然不报错了
再次优化代码, 测试识别率, 100%正确
完美的一笔
总结
把图片变成0101010这种字符串, 然后比较字符串相似度, 这种方法不可用,
主要是计算两个字符串相似度算法耗时太长;
还是比较图片相似度速度快
测试环境
手机: Mi 11 Pro
Android版本: 12
Autojs版本: 9.1.20
名人名言
思路是最重要的, 其他的百度, bing, stackoverflow, github, 安卓文档, autojs文档, 最后才是群里问问 --- 牙叔教程
声明
部分内容来自网络 本教程仅用于学习, 禁止用于其他用途