Android 識別身份證號碼(圖片識別)

Android 身份證號碼識別 (本地,在線,實時),網絡識別用的別人的接口,不保障何時就用不了了,本地識別基於tess_two,位置對的話識別準確率達到90%以上。

詳細

 

前些天下午沒什麼事,朋友有個需求,說要識別身份證上面的身份證號碼,恰好閒着,就幫他解決了一下,不說多完美,可是至少算是解決需求了,好了,閒話少說。html

先來看一下個人DEMO吧java

接下來咱們一個個介紹vim

 

1、聯網識別

也是從別人的Demo裏截出來的,其實也是用的別人的一個在線接口,可是我看了看應該算「非正常調用」(這個意思你們本身理解吧)。下面分析一下這個方法的優劣點吧。數組

優勢:速度極快,上傳照片,會返回身份證上全部信息,包括姓名 地址 出生等等網絡

缺點:「非正常」調用就有必定的不可靠性,若是哪天人家關了或者改了這個接口,就比較尷尬了,固然你能夠選擇購買人家的正式版。ide

2、本地識別

基於Tess_two作的識別,這個你們可放心使用。先看一下大概怎麼使用吧!url

 

首先引用:spa

1
compile 'com.rmtheis:tess-two:6.0.0'

 

而後使用,其實使用起來很簡單,可是要注意幾點3d

 

1.要在SD卡有他的識別庫,這個庫你能夠理解爲一個字典,這個字典能夠本身訓練,由於我是用的別人訓練好的(只包含英文和數字),因此就不說怎麼訓練了,百度一下會有不少。code

2.須要注意的是,放他字典的路徑文件夾名必須爲「tessdata」,不然報錯

好了,準備工做作好了,接下來介紹怎麼使用,我直接貼核心代碼,代碼有註釋,看不懂的留言或者私信我

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//訓練數據路徑,tessdata
     static  final  String TESSBASE_PATH = Environment.getExternalStorageDirectory() + "/" ;
     //識別語言英文
     static  final  String DEFAULT_LANGUAGE = "eng" ;
 
     /**
      * 傳SD卡圖片路徑(固然大家也能夠傳Bitmap)
      * @param url
      */
     private  void  localre(String url) {
         //把圖片轉爲Bitmap
         Bitmap bmp = BitmapFactory.decodeFile(url);
         //建立Tess
         final  TessBaseAPI baseApi = new  TessBaseAPI();
         //下面這一塊代碼爲裁取身份證號碼區域(不然識別亂碼,不許確)
         int  x, y, w, h;
         x = ( int ) (bmp.getWidth() * 0.340 );
         y = ( int ) (bmp.getHeight() * 0.800 );
         w = ( int ) (bmp.getWidth() * 0.6  + 0 .5f);
         h = ( int ) (bmp.getHeight() * 0.12  + 0 .5f);
         Bitmap bit_hm = Bitmap.createBitmap(bmp, x, y, w, h);
         //這個只是我將裁取的號碼區展現在了一個ImageView上,這個能夠沒有
         iv_number.setImageBitmap(bit_hm);
         //初始化OCR的訓練數據路徑與語言
         baseApi.init(TESSBASE_PATH, DEFAULT_LANGUAGE);
         //設置識別模式
         baseApi.setPageSegMode(TessBaseAPI.PageSegMode.PSM_SINGLE_LINE);
         //設置要識別的圖片
         baseApi.setImage(bit_hm);
         //設置字典白名單
         baseApi.setVariable( "tessedit_char_whitelist" , "0123456789Xx" );
         //把識別內容設置到EditText裏
         tv_result.setText(baseApi.getUTF8Text());
         //收尾
         baseApi.clear();
         baseApi.end();
     }

OK,就這麼簡單,圖片清晰切裁取區域正確的狀況下,準確度幾乎100%;

給你們舉個身份證照片的例子吧,不然裁取號碼會不

 

上一張結果圖

實時識別

 

其實就是本地識別的拓展版,把攝像頭的數據轉爲Bitmap,去識別,仍是貼核心代碼吧,看不懂的本身下Demo研究。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/**
      * 攝像頭數據回調
      * @param data
      * @param camera
      */
     @Override
     public  void  onPreviewFrame( byte [] data, Camera camera) {
         camera.addCallbackBuffer(data);
         //將byte數組轉爲Bitmap
         ByteArrayOutputStream baos;
         byte [] rawImage;
         Bitmap bitmap;
         Camera.Size previewSize = camera.getParameters().getPreviewSize(); //獲取尺寸,格式轉換的時候要用到
         BitmapFactory.Options newOpts = new  BitmapFactory.Options();
         newOpts.inJustDecodeBounds = true ;
         YuvImage yuvimage = new  YuvImage(
                 data,
                 ImageFormat.NV21,
                 previewSize.width,
                 previewSize.height,
                 null );
         baos = new  ByteArrayOutputStream();
         yuvimage.compressToJpeg( new  Rect( 0 , 0 , previewSize.width, previewSize.height), 100 , baos); // 80--JPG圖片的質量[0-100],100最高
         rawImage = baos.toByteArray();
         //將rawImage轉換成bitmap
         BitmapFactory.Options options = new  BitmapFactory.Options();
         options.inPreferredConfig = Bitmap.Config.RGB_565;
         bitmap = BitmapFactory.decodeByteArray(rawImage, 0 , rawImage.length, options);
         if  (bitmap == null ) {
             Log.d( "zka" , "bitmap is nlll" );
             return ;
         } else  {
             //裁取圖片中央身份證區域
             int  height = bitmap.getHeight();
             int  width = bitmap.getWidth();
             final  Bitmap bitmap1 = Bitmap.createBitmap(bitmap, width/ 2  - dip2px( 150 ),height / 2  - dip2px( 92 ), dip2px( 300 ), dip2px( 185 ));
             //截取身份證號碼區域
             int  x, y, w, h;
             x = ( int ) (bitmap1.getWidth() * 0.340 );
             y = ( int ) (bitmap1.getHeight() * 0.800 );
             w = ( int ) (bitmap1.getWidth() * 0.6  + 0 .5f);
             h = ( int ) (bitmap1.getHeight() * 0.12  + 0 .5f);
             Bitmap bit_hm = Bitmap.createBitmap(bitmap1, x, y, w, h);
            // 識別
             if (bit_hm != null ){
                 String localre = localre(bit_hm);
                 if  (localre.length() == 18 ) {
                     Log.e(TAG, "onPreviewFrame: " +localre );
                     Toast.makeText(getApplicationContext(),localre,Toast.LENGTH_SHORT).show();
                 }
             }
         }
     }
 
 
     /**
      * 識別
      * @param bm
      * @return
      */
     private  String localre(Bitmap bm) {
         String content = "" ;
         bm = bm.copy(Bitmap.Config.ARGB_8888, true );
         iv_result.setImageBitmap(bm);
         TessBaseAPI baseApi = new  TessBaseAPI();
         baseApi.init(TESSBASE_PATH, DEFAULT_LANGUAGE);
         //設置識別模式
         baseApi.setPageSegMode(TessBaseAPI.PageSegMode.PSM_SINGLE_LINE);
         //設置要識別的圖片
         baseApi.setImage(bm);
         baseApi.setVariable( "tessedit_char_whitelist" , "0123456789Xx" );
         Log.e(TAG, "localre: " + baseApi.getUTF8Text());
         content = baseApi.getUTF8Text();
         baseApi.clear();
         baseApi.end();
         return  content;
     }

3、源碼包截圖

blob.png

4、其餘

Ok,就這樣吧!核心也就這些東西,有問題的能夠留言或私信,有好的解決辦法也能夠交流,,出於隱私,就把人家的信息打碼, 不過識別出來準確度是100%。

 

 

 

相關文章
相關標籤/搜索