我的编程空间,编程开发者的网络收藏夹
学习永远不晚

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

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

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; 
 
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); 
  } 
   
  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问题

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

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

//www.jb51.net/article/53487.htm

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

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

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

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

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

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

DecodeHandler


  
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; 
    } 
  } 
   
  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

您可能感兴趣的文章:Android上使用ZXing识别条形码与二维码的方法Android图片处理:识别图像方向并显示实例教程理解Android的手势识别提高APP的用户体验Android平台生成二维码并实现扫描 & 识别功能Android实现语音识别代码Android中的指纹识别demo开发实例Android 二维码 生成和识别二维码 附源码下载android 指纹识别调用实现方法及示例代码


免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

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

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

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

ocr OpenCV 想必做过程图像识别的同学们都对这两个词不陌生吧。 ocr (optical character recognition ,光学字符识别) 是指电子设备(例如扫描仪或数码相机)检查纸上的字符,通过检测暗,亮的模式确定其形
2022-06-06

php如何实现身份证OCR识别

这篇“php如何实现身份证OCR识别”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“php如何实现身份证OCR识别”文章吧。实
2023-07-04

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

目录需求分析步骤申请华为云OCR接口获取token调用身份证识别接口总结图像识别说白了就是把一张照片上面的文字进行提取,提供工作效率 需求分析 身份证识别主要是把一张身份证照片上面的文字信息进行提取,不用再使用人工去手动抄写了,下面给大家说
2022-06-02

C#OCR实现文字识别功能

OCR,中文叫做光学字符识别。它是利用光学技术和计算机技术把印在或写在纸上的文字读取出来,并转换成一种计算机能够接受、人又可以理解的格式。本文将利用OCR实现文字识别功能,感兴趣的可以了解一下
2022-11-21

C# paddlerocrsharp识别身份证号的实现示例

本指南提供了一个循序渐进的示例,展示如何使用C#PaddleOCRSharpr库从身份证图像中提取身份证号。该示例涵盖了图像预处理、身份证识别区域定位和文本识别等关键步骤,并提供了完整的代码示例供参考。通过遵循本指南,开发人员能够轻松实现身份证识别功能,提升其应用程序的证件识别能力。
C# paddlerocrsharp识别身份证号的实现示例
2024-04-02

Unity怎么实现OCR文字识别功能

今天就跟大家聊聊有关Unity怎么实现OCR文字识别功能,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。首先登陆百度开发者中心,搜索文字识别服务:创建一个应用,获取AppID、APIK
2023-06-22

android 集成人脸识别和身份证识别报重复的

如果在Android应用程序中集成人脸识别和身份证识别时遇到重复报告的问题,可能是由于以下原因:1. 重复的函数或方法调用:请检查代码中是否重复调用了相同的人脸识别或身份证识别方法。确保只调用一次即可。2. 重复的回调处理:如果使用异步回调
2023-09-20

C++ OpenCV如何实现身份证离线识别

这篇文章将为大家详细讲解有关C++ OpenCV如何实现身份证离线识别,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。OpenCV身份证离线识别技术的主要技术就是通过OpenCV找到身份证号码区域,然后通过
2023-06-22

C#实现身份证验证功能的示例代码

这篇文章主要为大家详细介绍了如何利用C#实现身份证验证功能,文中的示例代码讲解详细,对我们学习C#有一定的帮助,感兴趣的小伙伴可以跟随小编一起了解一下
2022-12-20

Python调用百度AI怎样实现身份证识别

Python调用百度AI怎样实现身份证识别,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。一、安装baidu-aip模块按win+R打开cmd,在里面输入pip3
2023-06-25

Android | 教你如何在安卓上实现二代身份证识别,一键实名认证

目录前言场景开发前准备android studio 安装在项目级gradle里添加华为maven仓在应用级的build.gradle里面加上SDK依赖在AndroidManifest.xml文件里面增量添加模型自动下载在AndroidMan
2022-06-06

利用Java怎么实现一个验证身份证功能

这期内容当中小编将会给大家带来有关利用Java怎么实现一个验证身份证功能,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。具体如下:package org.cxy.csdn.example;import ja
2023-05-31

轻松实现Android语音识别功能

苹果的iphone有语音识别用的是Google的技术,做为Google力推的Android 自然会将其核心技术往Android 系统里面植入,并结合google 的云端技术将其发扬光大。 所以Google Voice Recognition
2022-06-06

Android实现手势滑动识别功能

对于Android中的手势识别可以从以下三个Listener入手——OnTouchListener、OnGestureListener、OnDoubleTapListener。这三个监听器分别是触摸监听、手势滑动监听和屏幕双击操作监听。很多
2023-05-31

android语音识别功能怎么实现

要实现Android平台的语音识别功能,可以使用Android提供的语音识别API,具体步骤如下:在AndroidManifest.xml文件中添加必要的权限:在布局文件中添加一个按钮来触发语音识别:在Activity中初始化语音识别引擎,
2023-10-22

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

1.准备工作 首先实现识别数字等字符,我们要知道需要采用OCR (Optical Character Recognition,光学字符识别)来实现。而tesseract是非常不错的开源OCR工具,但是要在Android中直接使用可能要费点
2023-05-30

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录