最近實驗室開了個新項目,是一個經過掃描單詞後把掃描過的單詞生成遊戲來讓小朋友記單詞的APP,掃描單詞這個功能須要用到OCR.
如今經常使用的OCR有html
Tesseract 這個用的人比較多,並且開源,目前google正在維護,可是我嘗試了一下,發現識別準確率不是特別理想。java
微軟的Azure上的認知服務 識別率很高,可是收費,如今有1元體驗的套餐,並且不須要驗證信用卡,感興趣的同窗能夠試試。android
百度的文字識別 之因此用這個是由於免費,不過有天天的限制次數,對於學生項目來講夠用,還要什麼自行車。git
下面進入正文github
1.在百度AI開放平臺中進入控制檯json
2.找到文字識別 產品服務
api
3,建立應用
安全
4,填寫信息,注意這裏的包名必定要和項目的包名一致
app
5.得到AK/SK
ide
6.下載license文件,在項目中若是直接用AK/SK明文調用百度的OCR,很不安全,可能會被別人反編譯以後得到你的AK.SK
license文件集成了AK/SK 放在項目中能夠防止別人破解。
7.下載以後將得到的api.license文件放入main目錄下的assets目錄中
1.下載 百度OCR的android Sdk
3.在main目錄下新建jniLibs目錄,並將libs文件夾中的其餘文件放入其中
4.在app下的build,gradle中添加
5.這裏下載的壓縮包中包括了百度提供的相機掃描時的UI,在拍完照有裁剪框,比較方便,這裏咱們能夠做爲module引入項目中
作完準備工做咱們就能夠開始調用百度的OCR接口了。
首先在咱們須要進行識別的頁面所在的文件中建立 根據License文件初始化OCR實例的函數,並在onCreate()方法中調用
/** * 自定義license的文件路徑和文件名稱,以license文件方式初始化 */
private void initAccessTokenLicenseFile() {
OCR.getInstance(mActivity.getApplicationContext()).initAccessToken(new OnResultListener<AccessToken>() {
@Override
public void onResult(AccessToken accessToken) {
String token = accessToken.getAccessToken();
Log.d(TAG,token);
hasGotToken = true;
}
@Override
public void onError(OCRError error) {
error.printStackTrace();
alertText("自定義文件路徑licence方式獲取token失敗", error.getMessage());
}
}, "aip.license", mActivity.getApplicationContext());
}
複製代碼
定義咱們的打開相機事件
/** * 打開相機,進入的相機頁面是借用百度OCR 官方DEMO中的相機頁面 * 可以在相機中裁剪圖片,和進入圖庫 * @author cyd */
private void openCameraForResult() {
if (!checkTokenStatus()) {
return;
}
Intent intent = new Intent(mActivity, CameraActivity.class);
intent.putExtra(CameraActivity.KEY_OUTPUT_FILE_PATH,
FileUtil.getSaveFile(getActivity()).getAbsolutePath());
intent.putExtra(CameraActivity.KEY_CONTENT_TYPE,
CameraActivity.CONTENT_TYPE_GENERAL);
startActivityForResult(intent, REQUEST_CODE_GENERAL_BASIC);
}
複製代碼
這裏的CameraActivity用的是引入OCR_UI中的相機活動,自帶剪裁框
接下來須要咱們新建一個能夠存放OCR的識別方法的類RecognizeService
**
* 這個類是用於將拍攝或者圖庫中得到的圖片進行識別,返回JSON格式的字符串。
*/
public class RecognizeService {
public interface ServiceListener {
public void onResult(String result);
}
//高精度版
public static void recAccurateBasic(Context ctx, String filePath, final ServiceListener listener) {
GeneralParams param = new GeneralParams();
param.setDetectDirection(true);
param.setVertexesLocation(true);
param.setLanguageType(GeneralBasicParams.ENGLISH);
param.setRecognizeGranularity(GeneralParams.GRANULARITY_SMALL);
param.setImageFile(new File(filePath));
//這裏的recognizeAccurateBasic方法爲百度OCR識別的核心方法
OCR.getInstance(ctx).recognizeAccurateBasic(param, new OnResultListener<GeneralResult>() {
@Override
public void onResult(GeneralResult result) {
StringBuilder sb = new StringBuilder();
for (WordSimple wordSimple : result.getWordList()) {
WordSimple word = wordSimple;
sb.append(word.getWords());
sb.append("\n");
}
listener.onResult(result.getJsonRes());
}
@Override
public void onError(OCRError error) {
listener.onResult(error.getMessage());
}
});
}
}
複製代碼
在onActivityResult方法中,咱們調用剛剛新建的類的recAccurateBasic方法,此方法接收三個參數,分別是context,拍照獲取的圖片路徑,和在RecognizeService類中定義的監聽接口,這裏的獲取圖片路徑方法,我用的是百度官方DEMO中的方法
在onResult方法中,返回的result字符串即爲識別結果的json字符串,只須要對JSON解析一下就能獲得識別結果啦
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_CODE_GENERAL_BASIC:
if (resultCode == Activity.RESULT_OK) {
RecognizeService.recAccurateBasic(mActivity, FileUtil.getSaveFile(mActivity.getApplicationContext()).getAbsolutePath(),
new RecognizeService.ServiceListener() {
@Override
public void onResult(String result) {
Bundle bundle = new Bundle();
bundle.putString("wordResultJson",result );
Intent intent = new Intent(mActivity,SelectWordsActivity.class);
intent.putExtra("wordResultBundle",bundle );
startActivity(intent);
}
});
}
break;
default:
Log.d(TAG, "onActivityResult: "+"run in default");
break;
}
}
複製代碼
FileUtil類
public class FileUtil {
public static File getSaveFile(Context context) {
File file = new File(context.getFilesDir(), "pic.jpg");
return file;
}
}
複製代碼
(完~)