国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

android ocr——身份證識別的功能實現

2020-02-21 17:21:07
字體:
來源:轉載
供稿:網友

Android和IOS在智能手機的行列得到了廣泛應用,而身份證識別功能現在也在廣泛普及,下文是android ocr——身份證識別的功能實現,一起跟隨武林技術頻道小編來學習吧!

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://m.survivalescaperooms.com/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目錄 以及下面的文件? 如果沒有存在說明 應用沒有獲取到存儲權限。

以上就是關于android ocr——身份證識別的功能實現,我們要注意開發細節,希望武林技術頻道小編介紹的這些內容對你有所幫助哦。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 武冈市| 全南县| 台东县| 华宁县| 蓝田县| 台州市| 惠东县| 富裕县| 定陶县| 旺苍县| 文水县| 海晏县| 天峻县| 罗江县| 许昌市| 鄄城县| 黄陵县| 衡东县| 惠东县| 大埔区| 洛阳市| 潞西市| 曲沃县| 玉环县| 泰安市| 涪陵区| 元朗区| 大兴区| 衡阳县| 沅江市| 隆化县| 安多县| 达州市| 杭锦旗| 祁阳县| 双柏县| 泽普县| 静安区| 介休市| 高碑店市| 新郑市|