Google Firebase Machine Learning(ML Kit)應用-使用文字辨識功能掃描信用卡(Android)
2018 年Google I/O 大會上,宣布 Firebase 釋出了最新功能 Firebase ML Kit,一個專為行動裝置開發的 AI SDK,這是一個能簡易把 Google Machine Learning 應用到一般行動 App 產品中的封裝(iOS + Android),ML套件將Google Cloud Vision API、TensorFlow Lite及Neural 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)。
(三) 連結Firebase到Android應用程式:
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());
}
});
}
});
}
});
}
四、 實測結果及說明:
本次針對各家信用卡分別進行測試,一般信用卡可區分為凸面及平面卡號,結果分別說明如下:
(一) 凸面卡號信用卡:卡號數字非一般手寫筆劃,實測發現數字5、6、8有機率會誤判為S、b、s,如使用Cloud API另可偵測中文字,且結果較On-device精確,但因需連網檢測,故速度會較慢(如下圖示)。
(二) 平面卡號信用卡:卡號數字較接近一般手寫筆劃,實測發現數字在On-device及Cloud 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
< 以上分享,歡迎大家留言指教,謝謝 ! >