Android实现扫一扫识别数字功能
1.准备工作
- 首先实现识别数字等字符,我们要知道需要采用OCR (Optical Character Recognition,光学字符识别)来实现。而tesseract是非常不错的开源OCR工具,但是要在Android中直接使用可能要费点功夫。不过不用担心,tess-two拯救了我们。
- 其次是扫一扫识别,那么很快联想到的就是常见的二维码扫描这类的项目。通过扫一扫实时拿到图像,来做识别。
- 接下来在Github上找到了QrCodeScanner项目,作者通过一定的优化,使得识别的效率有所提升。那么我们用它来扫描数字,也会有效率上的提升。
2.实现细节
1.首先是tess-two的用法。
app下的build.gradle的配置如下
android {
defaultConfig {
....
ndk {
abiFilters 'armeabi' //自行选择添加
}
}
}
dependencies {
compile 'com.rmtheis:tess-two:8.0.0'
}
识别方法:
public String detectText(Bitmap bitmap) {
TessBaseAPI tessBaseAPI = new TessBaseAPI();
String path = ""; //训练数据路径
tessBaseAPI.setDebug(true);
tessBaseAPI.init(path, "eng"); //eng为识别语言
tessBaseAPI.setVariable(TessBaseAPI.VAR_CHAR_WHITELIST, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); // 识别白名单
tessBaseAPI.setVariable(TessBaseAPI.VAR_CHAR_BLACKLIST, "!@#$%^&*()_+=-[]}{;:'"|~`,./< ?"); // 识别黑名单
tessBaseAPI.setPageSegMode(TessBaseAPI.PageSegMode.PSM_AUTO_OSD);//设置识别模式
tessBaseAPI.setImage(bitmap); //设置需要识别图片的bitmap
String inspection = tessBaseAPI.getHOCRText(0);
tessBaseAPI.end();
return inspection ;
}
训练数据可以在tessdata下载,里面包含各种语言。当然你自己也可以训练它,有兴趣的可以学习一下相关内容。
2.从tess-two的用法可以知道,我们最终需要的是识别图片的Bitmap。在扫码项目中我们找到在DecodeHandler类的decode方法中,我们会得到一个PlanarYUVLuminanceSource类的实例。在使用HybridBinarizer算法解析数据源,最终采用MultiFormatReader解析图像出结果。代码大致如下:
Result rawResult = null;
MultiFormatReader mMultiFormatReade = new MultiFormatReader();
try {
PlanarYUVLuminanceSource source =
new PlanarYUVLuminanceSource(```, false);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
rawResult = mMultiFormatReader.decode(bitmap, mHints);
} catch (ReaderException ignored) {
} finally {
mMultiFormatReader.reset();
}
看完后懵逼了,没有Bitmap。经过一番查找,找到了在旧版的zxing中PlanarYUVLuminanceSource类有renderCroppedGreyscaleBitmap方法,不知为何去除了。。。
3.之后修改了一些相机的参数信息,适配了部分设备的预览效果。基本的页面修改了一下。这里就不赘述了。
走一波,如下效果:
可以发现除了数字以外,它将中文识别为了字母。其实问题首先是我们使用了英文的训练数据,同时白名单设置了a~z的字母。当然你也不能将字母设置为黑名单,那样只会让识别不出的字符识别为乱七八糟的数字。
这里我给出的建议是利用正则去筛选,这样你可以识别你想要的各种格式数据。我这里只是做了手机号的简单识别,大家可以举一反三去处理。
public static String getTelNum(String sParam){
if(TextUtils.isEmpty(sParam)){
return "";
}
Pattern pattern = Pattern.compile("(1|861)(3|5|7|8)d{9}$*");
Matcher matcher = pattern.matcher(sParam);
StringBuilder bf = new StringBuilder();
while (matcher.find()) {
bf.append(matcher.group()).append(",");
}
int len = bf.length();
if (len 0) {
bf.deleteCharAt(len - 1);
}
return bf.toString();
}
修改后如下:(同时支持多个号码)
当然本项目也保留了扫码功能(可在DecodeHandler中自己添加条码格式):
细心的同学可以从图中看到扫描框的大小都不一样,这里我是改成了可以手动调节大小的扫描框。毕竟扫码模式下,框大一点还是比较好识别(将二维码放入框中有时就费时间)。扫数字这些文字时,框小一点会好识别。具体可以下载自行体验。
最后我将代码已经上传至Github:Tesseract-OCR-Scanner
总结
以上所述是小编给大家介绍的Android实现扫一扫识别数字功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对ZaLou.Cn网站的支持!
- 洛谷 P1972 [SDOI2009]HH的项链【莫队算法学习】
- BZOJ 2257: [Jsoi2009]瓶子和燃料【数论:裴蜀定理】
- 在 EF 5 中跟踪SQL和缓存数据
- hihoCoder #1015 : KMP算法【KMP裸题,板子】
- 对X86汇编的理解与入门
- BZOJ 2748: [HAOI2012]音量调节【二维dp,枚举】
- POJ 3264 Balanced Lineup【线段树区间查询求最大值和最小值】
- HDU 2289 Cup【高精度,二分】
- BZOJ 1083: [SCOI2005]繁忙的都市【Kruscal最小生成树裸题】
- [快学Python3]二分查找[策略优化版本]
- 微服务与SOA架构(4)
- 移动测试Appium之API手册
- BZOJ 1088: [SCOI2005]扫雷Mine【思维题,神奇的模拟+枚举】
- 浅谈关于特征选择算法与Relief的实现
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- JavaScript的预编译过程分析
- 我对JavaScript中this的一些理解
- 【大家的项目】 socks5-rs 一个使用async-std的异步socks5 server实现
- JS浅拷贝与深拷贝
- 理解JS 原型链
- 关于跨域
- 创建对象的几种方法及优缺点
- 【Rust日报】2020-10-02 移动操作系统SailfishOS支持Rust了
- Git
- 网络协议
- 【crossbeam系列】5 crossbeam-util和crossbeam-queue:一些实用的小东西
- 数据结构
- 静态博客自动化部署教程
- 【每周一库】 Sincere - a micro web framework for Rust
- 小米路由器 HD(R3D) 折腾笔记