最近開發一個項目須要用到Ocr文字識別技術來識別手寫文字,在評估過程當中體驗了百度的文字識別和騰訊的文字識別。查找官方開發文檔,發現它們都有印刷體和手寫體兩種符合項目需求的識別模式,可是騰訊的手寫體模式並沒找到sdk,只能直接根據文檔手動post請求並返回結果,但網上卻找不到具體的例子,致使進行過程當中出現了一些小困難。這篇文章主要記錄一下在Android Studio中百度Ocr的用法(主要參考官方文檔)。下篇文章記錄騰訊Ocr的用法。android
1.首先須要下載百度文字識別的sdk。SDK下載頁面
2.解壓縮下載的包,而後進入libs目錄,找到ocr-sdk.jar,複製到工程的libs目錄下,而後點擊Android Studio的Build->Edit Libralies and Dependencies...,點擊+號,再點擊jar dependency,找到ocr-sdk.jar並添加便可。
3.查看下載的包的libs目錄下,發現有armeabi,arm64-v8a,armeabi-v7a,x86這幾個文件夾,選擇本身設備對應的文件夾,複製到android studio工程src/main/jniLibs目錄中,若是不知道設備的arm架構,能夠用Android Studio鏈接設備,而後在Android Studio的控制檯中輸入:
adb shell getprop ro.product.cpu.abi
便可查看當前設備的arm架構。
4.添加必要的權限:shell
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
注意:android6.0以上須要申請動態權限。
5.若是在本身的工程中集成SDK,爲了防止release發佈時打包報錯,須要在Proguard配置文件中增長:json
-keep class com.baidu.ocr.sdk.**{*;} -dontwarn com.baidu.ocr.**
6.在代碼中初始化sdk:安全
/** * 用明文ak,sk初始化 */ private void initAccessTokenWithAkSk() { OCR.getInstance(mContext).initAccessTokenWithAkSk(new OnResultListener<AccessToken>() { @Override public void onResult(AccessToken result) { String token = result.getAccessToken(); hasGotToken = true; //用來判斷是否成功獲取受權 ocrNormal(); //開始文字識別(爲了簡單起見,直接在這裏進行文字識別,實際上使用看項目須要進行判斷token) } @Override public void onError(OCRError error) { error.printStackTrace(); } }, mContext.getApplicationContext(), "替換成你的Api Key", "替換成你的Secret Key"); }
Api Key和Secret Key須要去百度開放平臺註冊獲取(百度ai開放平臺)。還有一種安全模式受權這裏不詳說了。
7.開始文字識別:架構
private void ocrNormal() { // 通用文字識別參數設置 GeneralBasicParams param = new GeneralBasicParams(); param.setDetectDirection(true); //這裏調用的是本地文件,使用時替換成你的本地文件 File file=getBitmapFile(mBitmap); param.setImageFile(file); // 調用通用文字識別服務 OCR.getInstance(mContext).recognizeAccurateBasic(param, new OnResultListener<GeneralResult>() { @Override public void onResult(GeneralResult result) { StringBuilder sb = new StringBuilder(); // 調用成功,返回GeneralResult對象 for (WordSimple wordSimple : result.getWordList()) { // wordSimple不包含位置信息 WordSimple word = wordSimple; sb.append(word.getWords()); //sb.append("\n"); } //file.delete(); //String返回 ocrResult = sb.toString(); // json格式返回字符串result.getJsonRes()) } @Override public void onError(OCRError error) { // 調用失敗,返回OCRError對象 } }); }
手寫體文字識別只須要把上述調用的方法ocrNormal()修改成ocrHandwrite(),而後第7步修改成如下便可:app
private void orcHandwrite() { // 通用文字識別參數設置 OcrRequestParams param = new OcrRequestParams(); File file=getBitmapFile(mBitmap); param.setImageFile(file); // 調用通用文字識別服務 OCR.getInstance(mContext).recognizeHandwriting(param, new OnResultListener<OcrResponseResult>() { @Override public void onResult(OcrResponseResult ocrResponseResult) { //file.delete(); // json格式返回字符串 ocrResult = ocrResponseResult.getJsonRes(); } @Override public void onError(OCRError ocrError) { } }); }
其中ocrResult返回的是json格式的字符串,須要本身去轉換成jsonObject而後讀取須要的數據。ide
爲了比較他們的準確度,我測試了印刷體和手寫體兩種文字的多個樣例,發現通常狀況下,都是高精度的普通印刷體模式識別準確率比較高,可是在比較潦草的狀況下,手寫體識別率比較高(這只是相對而言,實際上潦草字在不少狀況下兩種模式都未識別成功),因此得出結論,大部分狀況下用高精度印刷體文字識別模式便可。post