Text Recognition  Firebase Machine Learning OCR scancard 文字辨識 信用卡掃描

Google Firebase Machine Learning(ML Kit)應用-使用文字辨識功能掃描信用卡(Android)

Vivian Wu 2019/05/09 13:37:46
1544

    2018 Google I/O 大會上,宣布 Firebase 釋出了最新功能 Firebase ML Kit,一個專為行動裝置開發的 AI SDK,這是一個能簡易把 Google Machine Learning 應用到一般行動 App 產品中的封裝(iOS + Android),ML套件將Google Cloud Vision APITensorFlow LiteNeural Network API整合在一個SDK中,開發人員可以輕鬆地應用ML技術來實現如文字辨識、臉部偵測、條碼掃描、圖片標記及地標識別等功能,本篇將運用文字辨識 (Text Recognition) 來實作實務上常用功能-拍照取得信用卡圖片並掃描及顯示相關資訊,並針對實測結果作比較說明。 

 

一、 Firebase Text Recognition

1.   Firebase Vision API可從圖像中檢測和提取文字,其中有二個功能支持光學字元辨識(OCR)

        (1) TEXT_DETECTION:檢測並從任何圖像中擷取文字。JSON包括整個擷取的字串,以及單個單詞及其邊界框。

                                            

       (2) DOCUMENT_TEXT_DETECTION可以從圖像中擷取文字,但針對密集文字和文件進行了優化。JSON包括頁面,塊,段落,單詞和中斷信息。

                                         

 

2.  ML Kit 為本機端(On-device)及雲端(Cloud)提供了通用的使用介面。本機端的 API 能夠快速的處理數據;而雲端的 API 則使用 Google Cloud Platform 機器學習技術,提供更細緻、更高準確度的資料,二者可依使用者需求作選擇,相關功能及定價作列表說明如下:

 

 

On-device

Cloud

定價

Free

級距性定價:

1.   每月前1,000個單位:Free

2.   每月第 1,001 至第 5,000,000 個單位:$1.50 美元( 1,000 個單位)

3.   每月第 5,000,001 至第 20,000,000 個單位:$0.60 美元( 1,000 個單位)

備註:套用至圖片的每項功能都是一個計費「單位」。詳情請點我

適用

情境

即時處理 - 適用於相機或視頻輸入識別圖像中的少量文字

高精度文字識別、識別文件中的密集文字

語言

支援

識別拉丁字母語系的文字

大部分國家,包含中日韓,請參考詳細支援語言

         

           3.   文字辨識流程:

                          

(1)     獲取圖像

(2)     創建 detector 捕捉圖像內容,運行演算法產生檢測結果

(3)     結果傳遞給處理器,負責篩除、合併、或傳遞檢測到的項目

(4)     使用者基於自己商業邏輯編寫程式碼

 

二、 連結Google Firebase ML Kit步驟:

(一)    建立專案:至Firebase 控制台 (https://console.firebase.google.com/ )登入Google帳戶,完成登入後會看到如下歡迎畫面,請點擊「新增專案」並為專案命名 (本專案命名為ML Kit)



(二)    新增專案內的應用程式:開啟ML Kit專案及點擊「新增應用程式」,並選取適用平台 (本專案選擇Android)

(三)    連結FirebaseAndroid應用程式:

1.   註冊應用程式:依序填入Android套件名稱、應用程式暱稱(選填)、偵錯簽署憑證SHA-1(選填, 取得方式請參考https://anson-site.blogspot.com/2018/02/sha1md5.html )

       

2.   下載設定檔:點擊「下載google-services.json, 並依說明將檔案加入應用程式的模組根目錄中。

      

3.   新增Firebase SDK

     

4.   新增Text Recognition SDK

    

5.   執行應用程式以驗證是否連結成功:成功將Firebase新增至應用程式後,接下來即可開始編寫所需功能的程式碼。

    

 

三、 Recognize Text Code

() 官方指南:

    

 

     () 實作「拍照掃描信用卡+顯示卡號及到期日」主要程式碼:

          1. Initialize FirebaseApp

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //initialize FirebaseApp
        FirebaseApp.initializeApp(this);

        showCloud();//顯示信用卡號及到期日
    }

  

           2. 實作使用Cloud API顯示信用卡號及到期日:

private void showCloud() {
        btn_cloud.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                cameraKitView.captureImage(new CameraKitView.ImageCallback() {
                    @Override
                    public void onImage(final CameraKitView cameraKitView, final byte[] capturedImage) {

                        // capturedImage contains the image from the CameraKitView
                        Bitmap bitmap = BitmapFactory.decodeByteArray(capturedImage, 0, capturedImage.length);
                        mBitmap = bitmap;
                        FirebaseVisionImage image = FirebaseVisionImage.fromBitmap(bitmap);
                       
                        FirebaseVisionCloudDetectorOptions options =
                                new FirebaseVisionCloudDetectorOptions.Builder()
                                        .setModelType(FirebaseVisionCloudDetectorOptions.LATEST_MODEL)
                                        .setMaxResults(10)
                                        .build();

                        FirebaseVisionCloudTextDetector detector = FirebaseVision.getInstance().getVisionCloudTextDetector(options);

                        //Start image detection and wait for results
                        Task<FirebaseVisionCloudText> result = detector.detectInImage(image)
                                .addOnSuccessListener(new OnSuccessListener<FirebaseVisionCloudText>() {
                                    @Override
                                    public void onSuccess(FirebaseVisionCloudText firebaseVisionCloudText) {
                                        //辨識成功
                                        Toast.makeText(MainActivity.this, "success", Toast.LENGTH_SHORT).show();

                                        String str = firebaseVisionCloudText.getText();
                                        String[] words = str.split("\n");
                                        for (String num : words) {
                                            //信用卡卡號 REGEX
                                            if (num.replace(" ", "").matches(
                                                    "^(?:4[0-9]{12}(?:[0-9]{3})?|[25][1-7][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\d{3})\\d{11})$")) {
                                                String cardnumber = num;
                                                tv_result1.setText("CardNumber:" + cardnumber.replace(" ", "-"));
                                            }
                                            //信用卡到期日
                                            if (num.contains("/")) {
                                                String[] words1 = num.split(" ");
                                                for (String data : words1) {
                                                    if (data.contains("/")) {
                                                        String exp = data;
                                                        tv_result2.setText("CardExpired:" + exp);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                })
                                .addOnFailureListener(new OnFailureListener() {
                                    @Override
                                    public void onFailure(@NonNull Exception e) {
                                        //辨識失敗
                                        Toast.makeText(MainActivity.this, "fail", Toast.LENGTH_SHORT).show();
                                        tv_result2.setText(e.getMessage());
                                    }
                                });
                    }
                });
            }
        });
    }

 

四、 實測結果及說明:

本次針對各家信用卡分別進行測試,一般信用卡可區分為凸面及平面卡號,結果分別說明如下:

(一)    凸面卡號信用卡:卡號數字非一般手寫筆劃,實測發現數字568有機率會誤判為Sbs,如使用Cloud API另可偵測中文字,且結果較On-device精確,但因需連網檢測,故速度會較慢(如下圖示)。

          

(二)    平面卡號信用卡:卡號數字較接近一般手寫筆劃,實測發現數字在On-deviceCloud API均大多可精確顯示,但Cloud API因仍需連網檢測,故速度較慢;另有部份卡號設計方式如下右圖,如使用一般信用卡號正則表達式仍無法正常檢測,目前只當作是一般數字分列顯示。

          

        

(三)    整體來說,大部份檢測後資訊仍能忠實呈現,但此為從圖片去檢測出相關內容文字,故圖片本身解析度、內容複雜度及顏色對比等因素,均會影響檢測結果質量,故針對實測過程中,大家最關心的精確度及速度二面向作相關統整如下,可作為提昇效能參考。

1.     精確度:

(1)      於光線佳或減少抖動的環境下拍攝圖像。

(2)      使用 Google Cloud Vision (GCV) API

(3)      顏色:一般對黑白圖片辨識率較佳。

(4)      字體:手寫辨識率較低。

2.     速度:

(1)      避免將 detector 部署在 UI 線程。

(2)      尺寸:圖像尺寸小可較快處理

(3)      內容:複雜度低可較快處理

 

五、最後總結:

文字辨識API可應用在相當多的場景,如:掃描信用卡、收據、名片並自動化輸入表格;或是透過雲端的高精準度識別來完成文件翻譯等等,無論是否對於 Machine Learning 有過開發經驗,都能夠透過簡單的步驟,把強大的功能加入專案中;如果有興趣更進一步瞭解有關ML Kit API資料,也可以參考https://firebase.google.com/docs/ml-kit/ ,共同進入機器學習的領域!

 

此外,使用相關付費服務時,也別忘記先依使用情境及需求來選擇 Cloud API Pricing Plans,目前共有三大方案,分別為Spark Plan (Free) Flame Plan (固定定價,每月$25) Blaze Plan (用多少付多少),詳情請參考 Pricing Plans 

 

六、相關參考聯結

https://firebase.google.com/docs/ml-kit/android/recognize-text/ 官網

https://codelabs.developers.google.com/codelabs/mlkit-android/ ML Kit- Recognize Text 功能及Sample Code下載

https://www.appcoda.com.tw/ml-kit/  iOS 整合 Google ML Kit

 

 

< 以上分享,歡迎大家留言指教,謝謝 ! >

Vivian Wu