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


概述

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

詳細

 

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

先來看一下我的DEMO吧

接下來我們一個個介紹

 

一、聯網識別

也是從別人的Demo里截出來的,其實也是用的別人的一個在線接口,但是我看了看應該算“非正常調用”(這個意思大家自己理解吧)。下面分析一下這個方法的優劣點吧。

優點:速度極快,上傳照片,會返回身份證上所有信息,包括姓名 地址 出生等等

缺點:“非正常”調用就有一定的不可靠性,如果哪天人家關了或者改了這個接口,就比較尷尬了,當然你可以選擇購買人家的正式版。

二、本地識別

基於Tess_two做的識別,這個大家可放心使用。先看一下大概怎么使用吧!

 

首先引用:

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

 

然后使用,其實使用起來很簡單,但是要注意幾點

 

1.要在SD卡有他的識別庫,這個庫你可以理解為一個字典,這個字典可以自己訓練,因為我是用的別人訓練好的(只包含英文和數字),所以就不說怎么訓練了,百度一下會有很多。

2.需要注意的是,放他字典的路徑文件夾名必須為“tessdata”,否則報錯

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

//訓練數據路徑,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研究。

/**
     * 攝像頭數據回調
     * @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;
    }

三、源碼包截圖

blob.png

四、其他

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

 

 

 

注:本文著作權歸作者,由demo大師發表,拒絕轉載,轉載需要作者授權

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM