android ocr——身份证识别的功能实现

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 stub 

    mTess = 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.jb51.net/article/53487.htm

下面给大家介绍一下,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;
  } 

  @Override
  public 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 here
    byte[] 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 #11
    width = 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() {
      @Override
      public 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;
 }

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

需要提示的是 如果您的手机是android 6.0以上 请查看 sd卡根目录是否存在tesseract/tessdata目录 以及下面的文件  如果没有存在说明 应用没有获取到存储权限。

原文链接:http://blog.csdn.net/tiandiyinghun/article/details/50985961

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android上使用ZXing识别条形码与二维码的方法

    目前有越来越多的手机具备自动对焦的拍摄功能,这也意味着这些手机可以具备条码扫描的功能.手机具备条码扫描的功能,可以优化购物流程,快速存储电子名片(二维码)等. 本文所述实例就使用了ZXing 1.6实现条码/二维码识别.ZXing是个很经典的条码/二维码识别的开源类库,早在很久以前,就有开发者在J2ME上使用ZXing了,只不过需要支持JSR-234规范(自动对焦)的手机才能发挥其威力,而目前已经有不少Android手机具备自动对焦的功能. 本文代码运行的结果如下,使用91手机助手截图时,无法截

  • Android图片处理:识别图像方向并显示实例教程

    在Android中使用ImageView显示图片的时候发现图片显示不正,方向偏了或者倒过来了. 解决这个问题很自然想到的分两步走: 1.自动识别图像方向,计算旋转角度: 2.对图像进行旋转并显示. 一.识别图像方向 首先在这里提一个概念EXIF(Exchangeable Image File Format,可交换图像文件),具体解释参见Wiki. 简而言之,Exif是一个标准,用于电子照相机(也包括手机.扫描器等)上,用来规范图片.声音.视屏以及它们的一些辅助标记格式. Exif支持的格式如下:

  • Android实现语音识别代码

    苹果的iphone 有语音识别用的是Google 的技术,做为Google 力推的Android 自然会将其核心技术往Android 系统里面植入,并结合google 的云端技术将其发扬光大. 所以Google Voice Recognition在Android 的实现就变得极其轻松. 语音识别,借助于云端技术可以识别用户的语音输入,包括语音控制等技术,下面我们将利用Google 提供的Api 实现这一功能. 功能点为:通过用户语音将用户输入的语音识别出来,并打印在列表上. 功能界面如下: 用户

  • Android平台生成二维码并实现扫描 & 识别功能

    1.二维码的前世今生 "二维条码/二维码(2-dimensional bar code)是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的:在代码编制上巧妙地利用构成计算机内部逻辑基础的"0"."1"比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图象输入设备或光电扫描设备自动识读以实现信息自动处理:它具有条码技术的一些共性:每种码制有其特定的字符集:每个字符占有一定的宽度:具有一定的校验功能

  • 理解Android的手势识别提高APP的用户体验

    对于触摸屏,其原生的消息无非按下.抬起.移动这几种,我们只需要简单重载onTouch或者设置触摸侦听器setOnTouchListener即可进行处理.不过,为了提高我们的APP的用户体验,有时候我们需要识别用户的手势,Android给我们提供的手势识别工具GestureDetector就可以帮上大忙了. 基础 GestureDetector的工作原理是,当我们接收到用户触摸消息时,将这个消息交给GestureDetector去加工,我们通过设置侦听器获得GestureDetector处理后的手

  • Android 二维码 生成和识别二维码 附源码下载

    今天讲一下目前移动领域很常用的技术--二维码.现在大街小巷.各大网站都有二维码的踪迹,不管是IOS.Android.WP都有相关支持的软件.之前我就想了解二维码是如何工作,最近因为工作需要使用相关技术,所以做了初步了解.今天主要是讲解如何使用ZXing库,生成和识别二维码.这篇文章实用性为主,理论性不会讲解太多,有兴趣可以自己查看源码. 1.ZXing库介绍 这里简单介绍一下ZXing库.ZXing是一个开放源码的,用Java实现的多种格式的1D/2D条码图像处理库,它包含了联系到其他语言的端口

  • Android中的指纹识别demo开发实例

    指纹识别是在Android 6.0之后新增的功能,因此在使用的时候需要先判断用户手机的系统版本是否支持指纹识别.另外,实际开发场景中,使用指纹的主要场景有两种: 纯本地使用.即用户在本地完成指纹识别后,不需要将指纹的相关信息给后台. 与后台交互.用户在本地完成指纹识别后,需要将指纹相关的信息传给后台. 由于使用指纹识别功能需要一个加密对象(CryptoObject)该对象一般是由对称加密或者非对称加密获得.上述两种开发场景的实现大同小异,主要区别在于加密过程中密钥的创建和使用,一般来说,纯本地的

  • android 指纹识别调用实现方法及示例代码

    activity_main.xml源码 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="

  • android ocr——身份证识别的功能实现

    ocr OpenCV 想必做过程图像识别的同学们都对这两个词不陌生吧. ocr (optical character recognition ,光学字符识别) 是指电子设备(例如扫描仪或数码相机)检查纸上的字符,通过检测暗,亮的模式确定其形状,然后用字符识别方法将形状翻译成计算机文字的过程. 这样就给我编程提供了接口,我们可以识别图片的文字了 (有些文档我们通过手机拍照的,直接生成word )身份证识别,银行卡识别等. opencv 是什么呢 OpenCV的全称是:Open Source Com

  • Android开发人脸识别登录功能

    近来,很多公司的APP都实现了人脸识别登录的功能.今天呢,银鹏带大家从头到尾做一下这个人脸识别登录. 首先呢,我们需要采用一个拥有人脸识别算法的平台,这边我建议使用虹软的人脸识别,因为我个人用的就是这个,关键有一点好处,就是免费.注册链接:点击进入注册. 注册完毕以后,话不多说,我们进入流程. 第一步:在虹软平台创建应用 直接安装SDK查看激活码 下载虹软识别库地址:点击下载识别库 下载好之后进行依赖添加: implementation 'com.github.tyhjh:PermissionU

  • java实现百度云OCR文字识别 高精度OCR识别身份证信息

    本文为大家分享了java实现百度云OCR识别的具体代码,高精度OCR识别身份证信息,供大家参考,具体内容如下 1.通用OCR文字识别 这种OCR只能按照识别图片中的文字,且是按照行识别返回结果,精度较低. 首先引入依赖包: <dependency> <groupId>com.baidu.aip</groupId> <artifactId>java-sdk</artifactId> <version>4.6.0</version&

  • Python中AI图像识别实现身份证识别

    目录 需求分析 步骤 申请华为云OCR接口 获取token 调用身份证识别接口 总结 图像识别说白了就是把一张照片上面的文字进行提取,提供工作效率 需求分析 身份证识别主要是把一张身份证照片上面的文字信息进行提取,不用再使用人工去手动抄写了,下面给大家说的这个身份识别主要是使用python+flask+华为云OCR进行实现的. 步骤 申请华为云OCR接口 获取token 调用身份证识别接口 提取身份证信息 申请华为云OCR接口 图像识别主要使用的就是华为云OCR平台申请的接口,申请地址为:"ht

  • 基于C#技术实现身份证识别功能

    最近研究C#相关的ORC技术,图像识别一般C和C++这种底层语言做的比较多,C#主要是依托一些封装好的组件进行调用,这里介绍三种身份证识别的方法. 一:调用大公司API接口,百度.云脉,文通科技都有相关的API介绍. 二:调用图像处理类库,EmguCV是OpenCV的一个跨平台的.Net封装,该封装也可以被编译到Mono平台和允许在Windows.Mac OS.Android.iPhone.iPad等多个平台上运行 三:调用Office2007 组件 一.证件识别API接口 以聚合数据中的API

  • Android实现扫一扫识别数字功能

    1.准备工作 首先实现识别数字等字符,我们要知道需要采用OCR (Optical Character Recognition,光学字符识别)来实现.而tesseract是非常不错的开源OCR工具,但是要在Android中直接使用可能要费点功夫.不过不用担心,tess-two拯救了我们. 其次是扫一扫识别,那么很快联想到的就是常见的二维码扫描这类的项目.通过扫一扫实时拿到图像,来做识别. 接下来在Github上找到了QrCodeScanner项目,作者通过一定的优化,使得识别的效率有所提升.那么我

  • IOS身份证识别(OCR源码)详解及实例代码

    IOS身份证识别(OCR源码)详解 最近项目用到身份证识别,在github上搜了一堆demo,在Google上找了一堆代码,有能识别出证件照的,但是都是打包成.a的静态库,没有源码,我努力吃了几天书,有了一点研究成果,现在贴出来与大家分享,要是有更好的方法,希望大神指正,共同探讨解决方案.(以下代码本人亲测可用,正在进一步探索智能识别,如有兴趣,请加入) 这里用到了两个开源库:OpenCV.TesseractOCRiOS,两个语言包chi_sim.eng.身份证识别的流程主要有:灰度化,阀值二值

  • Android自动文本框输入识别提示功能代码

    自动提示文本框(AutoCompleteTextView)可以加强用户体验,缩短用户的输入时间(百度的搜索框就是这个效果). 相信大家都熟悉自动识别提示吧,在我们的生活中随处可见,今天就让我为大家简单介绍一下它是如何设计的. 所谓自动识别输入即是根据用户输入的已有信息,为用户提示可能的值,方便用户完成输入.在Android设备上这种功能分为:AutoCompleteTextView和MultiAutoCompleteTextView,前者为单个的自动识别,类似与搜索引擎的输入框提示:后者为多个值

  • C#身份证识别相关技术功能详解

    最近研究C#相关的OCR技术,图像识别一般C和C++这种底层语言做的比较多,C#主要是依托一些封装好的组件进行调用,这里介绍一种身份证识别的方法. 环境搭建 下载地址:EmguCV官网 在File类别下下载这个EXE,进行安装,安装后在目录下能找相应组件,还有些应用的案例. dll文件夹中的dll引用到C#项目中,x64,x86,tessdata对应OCR识别的类库和语言库,我tessdata中已添加中文语言包,将这三个文件夹放入程序执行文件夹中. Demo 自己做的小Demo如图:身份证图片是

  • android实现指纹识别功能

    功能介绍 支持指纹识别,兼容 Android 6.0 和 Android 9.0 提供界面友好的指纹识别弹窗,可自定义其样式 实现国际化(支持中文和英文) Gradle依赖 dependencies { implementation 'com.github.ZuoHailong:BiometricPrompt:0.2.3' } 指纹识别用法简述 FingerprintVerifyManager.Builder builder = new FingerprintVerifyManager.Buil

随机推荐