ocr opencv 想必做过程图像识别的同学们都对这两个词不陌生吧。

ocr (optical character recognition ,光学字符识别) 是指电子设备(例如扫描仪或数码相机)检查纸上的字符,通过检测暗,亮的模式确定其形状,然后用字符识别方法将形状翻译成计算机文字的过程。 这样就给我编程提供了接口,我们可以识别图片的文字了 (有些文档我们通过手机拍照的,直接生成word )身份证识别,银行卡识别等。

opencv 是什么呢

OpenCV的全称是:Open Source Computer Vision Library。OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux、Windows和Mac OS操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。

上面是 百度百科给出的定义说白了就是给我们编程提供的类库而已

android 如果想使用OCR

我们可以使用google 开源的项目tesseract-ocr

github 下载地址:https://github.com/justin/tesseract-ocr

今天我不讲如何编译 ocr 这个东西

主要说下,识别二维码的这个项目和tesseract-ocr 整合成一个识别身份证号码的 过程

后面我会把他们编译成类库供大家使用的

ORC 识别方法已经封装成一个简单的类 OCR

package com.dynamsoft.tessocr;import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.os.Environment;import com.googlecode.tesseract.android.TessBaseAPI;import java.io.File;/*** Created by CYL on 2016/3/26.* email:670654904@qq.com* 这个类 就是调用 ocr 的接口* 这个是识别过程是耗时的 操作  请放到线程 操作*/
public class OCR {private TessBaseAPI mTess;private boolean flag;private Context context;private AssetManager assetManager;public OCR() {// TODO Auto-generated constructor stubmTess = new TessBaseAPI();String datapath = Environment.getExternalStorageDirectory() + "/tesseract/";String language = "eng";//请将你的语言包放到这里 sd 的 tessseract 下的tessdata 下File dir = new File(datapath + "tessdata/");if (!dir.exists())dir.mkdirs();flag = mTess.init(datapath, language);}/*** 识别出来bitmap 上的文字* @param bitmap 需要识别的图片* @return*/public String getOCRResult(Bitmap bitmap) {String result = "dismiss langues";if(flag){mTess.setImage(bitmap);result = mTess.getUTF8Text();}return result;}public void onDestroy() {if (mTess != null)mTess.end();}
}

方法很简单 :

创建对象,调用getOcrResult方法就行了,注意这个识别过程是耗时,放到线程去操作。避免ANR问题

然后我们需要把识别集成到二维码扫描里面

下面这个对二维码扫描这个项目介绍的比较详细

http://www.cnblogs.com/weixing/archive/2013/08/28/3287120.html

 下面给大家介绍一下,ZXing库里面主要的类以及这些类的作用:

  • CaptureActivity。这个是启动Activity 也就是扫描器。
  • CaptureActivityHandler 解码处理类,负责调用另外的线程进行解码。
  • DecodeThread 解码的线程。
  • com.google.zxing.client.android.camera 包,摄像头控制包。
  • ViewfinderView 自定义的View,就是我们看见的拍摄时中间的框框了。

我可以简单考虑一下  图片识别,我们需要先获取图片才能识别,当识别成功以后应该将数据返回  并反馈给用户我们已经完成了识别。

第一首先 我们如何获取图像 即 bitmap 从上面主要功能的类可以看出来。

我应该去captureactivityhandler 解码处理处理中去找,不管识别二维码还是图片,身份证啊。最终都是识别bitmap

所以我们这里可以找到相机捕捉到的图像;

DecodeHandler
/** Copyright (C) 2010 ZXing authors** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**      http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package com.sj.app.decoding;import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;import com.dynamsoft.tessocr.OCR;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.ReaderException;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import com.sj.app.camera.CameraManager;
import com.sj.app.camera.PlanarYUVLuminanceSource;
import com.sj.app.utils.IdMatch;
import com.sj.erweima.MipcaActivityCapture;
import com.sj.erweima.R;import java.util.Hashtable;
import java.util.List;final class DecodeHandler extends Handler {private static final String TAG = DecodeHandler.class.getSimpleName();private final MipcaActivityCapture activity;private final MultiFormatReader multiFormatReader;DecodeHandler(MipcaActivityCapture activity,Hashtable<DecodeHintType, Object> hints) {multiFormatReader = new MultiFormatReader();multiFormatReader.setHints(hints);this.activity = activity;}@Overridepublic void handleMessage(Message message) {switch (message.what) {case R.id.decode:// Log.d(TAG, "Got decode message");decode((byte[]) message.obj, message.arg1, message.arg2);break;case R.id.quit:Looper.myLooper().quit();break;}}/*** Decode the data within the viewfinder rectangle, and time how long it* took. For efficiency, reuse the same reader objects from one decode to* the next.** @param data*            The YUV preview frame.* @param width*            The width of the preview frame.* @param height*            The height of the preview frame.*/private void decode(byte[] data, int width, int height) {long start = System.currentTimeMillis();Result rawResult = null;// modify herebyte[] rotatedData = new byte[data.length];for (int y = 0; y < height; y++) {for (int x = 0; x < width; x++)rotatedData[x * height + height - y - 1] = data[x + y * width];}int tmp = width; // Here we are swapping, that's the difference to #11width = height;height = tmp;PlanarYUVLuminanceSource source = CameraManager.get().buildLuminanceSource(rotatedData, width, height);BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));try {//相机中捕捉到的Bitmap image = source.renderCroppedGreyscaleBitmap();doorc(source);rawResult = multiFormatReader.decodeWithState(bitmap);} catch (ReaderException re) {// continue} finally {multiFormatReader.reset();}if (rawResult != null) {long end = System.currentTimeMillis();Log.d(TAG, "Found barcode (" + (end - start) + " ms):\n"+ rawResult.toString());Message message = Message.obtain(activity.getHandler(),R.id.decode_succeeded, rawResult);Bundle bundle = new Bundle();bundle.putParcelable(DecodeThread.BARCODE_BITMAP,source.renderCroppedGreyscaleBitmap());message.setData(bundle);// Log.d(TAG, "Sending decode succeeded message...");message.sendToTarget();} else {Message message = Message.obtain(activity.getHandler(),R.id.decode_failed);message.sendToTarget();}}private Handler handler = new Handler(){public void handleMessage(Message msg) {CardId cardId = (CardId) msg.obj;if(cardId != null){Message message = Message.obtain(activity.getHandler(),R.id.decode_succeeded, cardId.id);Bundle bundle = new Bundle();bundle.putParcelable(DecodeThread.BARCODE_BITMAP,cardId.bitmap);message.setData(bundle);// Log.d(TAG, "Sending decode succeeded message...");message.sendToTarget();}};};private void doorc(final PlanarYUVLuminanceSource source) {new Thread(new Runnable() {@Overridepublic void run() {Bitmap bitmap = source.renderCroppedGreyscaleBitmap();String id = new OCR().getOCRResult(bitmap);if(id != null){List<String> list = IdMatch.machId(id);if(list!= null && list.size()>0){String cardId = list.get(0);if(cardId != null){Message msg = Message.obtain();CardId cardId2 = new CardId(cardId, bitmap);msg.obj = cardId2;handler.sendMessage(msg);}}}}}).start();}public class CardId{private String id;private Bitmap bitmap;public CardId(String id, Bitmap bitmap) {super();this.id = id;this.bitmap = bitmap;}public String getId() {return id;}public void setId(String id) {this.id = id;}public Bitmap getBitmap() {return bitmap;}public void setBitmap(Bitmap bitmap) {this.bitmap = bitmap;}}}

当解析成功的时候就将结果通过handler 返回到UI 线程中去了,对于 扫描框我们可以响应调节。

CameraManager 这个类 控制扫描框的大小。
 
 public Rect getFramingRect() {Point screenResolution = configManager.getScreenResolution();if (framingRect == null) {if (camera == null) {return null;}int width = screenResolution.x * 7 / 8;if (width < MIN_FRAME_WIDTH) {width = MIN_FRAME_WIDTH;} else if (width > MAX_FRAME_WIDTH) {
//        width = MAX_FRAME_WIDTH;}int height = screenResolution.y * 3 / 4;if (height < MIN_FRAME_HEIGHT) {height = MIN_FRAME_HEIGHT;} else if (height > MAX_FRAME_HEIGHT) {height = MAX_FRAME_HEIGHT;}int leftOffset = (screenResolution.x - width) / 2;int topOffset = (screenResolution.y - height) / 2;framingRect = new Rect(leftOffset, topOffset, leftOffset + width, topOffset + height);Log.d(TAG, "Calculated framing rect: " + framingRect);}return framingRect;}

改变这个方法就可以改变这个扫描框的大小了。

demo 地址
链接: https://pan.baidu.com/s/1uPekNyHVUV2QFX7AAZ1QvQ 密码: xxiz   《百度云盘》
上面的找个地址对应应用源码文案可是二维码,给大家造成了很大的误会,今天特意更新一下地址基本逻辑没有变化
只是更新代码文案。。。 在这里也恳请大家原谅以前的粗心
需要提示的是 如果您的手机是android 6.0以上 请查看 sd卡根目录是否存在tesseract/tessdata目录 以及下面的文件  如果没有存在说明 应用没有获取到存储权限。
 
 

android ocr 身份证识别相关推荐

  1. Android Study 玩转百度ocr身份证识别不是梦~

    LZ-Says:最近好哥儿们因公来廊坊,在家里可谓夜夜笙歌,喝酒喝的俩眼发懵,最近状态欠佳,导致学习计划一直在滞留,今天通过简短的小例子,重新拾起学习之路,滚蛋吧,懒瘤君~ 前言 Today,由于昨晚 ...

  2. Android实现身份证识别

    Android实现身份证识别(印刷文字识别-身份证识别-阿里云) 在做实名认证的时候客户要求要自动识别身份证上的个人信息,我们使用的是阿里云的OCR印刷文字识别-身份证识别 阿里云的文档写的还是很清楚 ...

  3. 关于调用百度云OCR身份证识别接口,用Java语言,识别结果缺少身份证号码的问题解决

    问题描述: 最近项目系统开发,使用到了相关证件的信息提取.识别,由于是学校科研使用,选择了百度云OCR文字识别的API.具体的相关识别身份等证件的代码将在另一篇文章中叙述,最近真的太忙了,草稿箱中还有 ...

  4. 国航APP接入百度大脑OCR身份证识别技术,让机票购买更便捷!

    价值成果 中国国航APP通过接入百度大脑OCR身份证识别技术,实现了旅客线上自助修正错购机票信息的功能.购票信息错误的旅客只需在中国国航APP上传身份证照片,即可进行购票身份认证,并立即修正错误信息. ...

  5. springboot 集成 腾讯云ocr身份证识别

    //控制层 @GetMapping("/getCertification")@ApiOperation(value = "ocr身份证识别接口 positiveImg:正 ...

  6. 阿里OCR身份证识别相关信息

    阿里OCR身份证识别相关信息 maven <!-- fastjson--> <dependency><groupId>com.alibaba</groupId ...

  7. 腾讯OCR身份证识别信息

    腾讯OCR身份证识别信息 maven <!-- 腾讯身份证识别 --><dependency><groupId>com.qcloud</groupId> ...

  8. Android Ocr文字识别 身份证识别 实时扫描

    遇到一个需求需要扫描身份证,识别身份证号并进行查询,在网上百度需要用到文字识别技术,ocr tess-two,看到网上有关于中英文实时扫描和手机号实时扫描的功能,于是在这两者的基础上进行了改进,感谢顾 ...

  9. 身份证在日常生活重要性 OCR身份证识别的作用

    如何能快速识别提取身份证号.姓名呢?结合使用ocr识别技术,一秒提取,不用手工输入: 身份证识别,识别解决方案 身份证识别OCR技术影响识别率的因素有很多:其中重要因素是图片清晰度,决定因素为字符分割 ...

最新文章

  1. 5中div标签有没有url属性_[网页编程]-03 CSS 常用属性
  2. PMM 对MYSQL 的监控配制
  3. 【android-tips】SurfaceView的制作android游戏框架介绍
  4. 论软件的模块化与架构
  5. keepalived(3)——解决无法用vip来访问的问题
  6. 在线小词典(mysql扩展库操作)
  7. SAP云平台和SAP HANA Enterprise Cloud(HEC)的区别
  8. 在VMware 14中安装Centos7
  9. IDEA git修改远程仓库地址
  10. T系统和应用集成-从SOA架构思想到服务架构规划设计
  11. poj 2499第K短路模板
  12. jpa long oracle,springboot-data-jpa调用oracle存储过程
  13. Java敏捷开发框架
  14. dev万能头文件_Dev c++ 支持bits/stdc++.h万能头文件吗
  15. python文本自动伪原创_给大家分享的6款在线Ai伪原创工具 让你写作更简单
  16. tpm_crb MSFT0101:00: [Firmware Bug]: ACPI region does not cover the entire command/re处理
  17. 不使用拇指玩安装器安装GPK文件
  18. WIN10系统安装虚拟机以及CentOS7
  19. android rom结构_如何将新的ROM刷新到您的Android手机
  20. iOS APP下载安装时,如果出现此时无法下载安装APP的字样时,一些解决思路

热门文章

  1. 一对一或一对多音视频通话会议系统可以通过哪些方式实现?
  2. 秦曾昌人工智能课程---4、梯度下降算法
  3. java程序设计实用教程_清华大学出版社-图书详情-《Java程序设计实用教程》
  4. 7-47 打印选课学生名单 (25分)C++
  5. 操作系统 考研习题 详细解析(1)
  6. 服务器网口灯亮但显示未插网线,网线插路由器WAN口,但WAN口灯不亮怎么办?
  7. OSChina 周二乱弹 —— 掏心掏肺又掏钱,最终娶了个潘金莲
  8. Pikachu靶场之(XSS盲打)
  9. 如何从手机上恢复误删的微信聊天记录
  10. 无限循环小数四则运算_无尽小数的公理及其四则运算.doc