Android OCR(Optical Character Recognition) API 初探

概述

有项目需要使用图片文字识别的功能, 基本需求:

  • 支持中,英文
  • 支持本地识别
  • 免费

开发环境: Android Studio
平台: Android
语言: Java

方案选择

从搜索到的情况看, 大部分的OCR都是在线API, 实际使用过程各种网络要求, 各种付费要求, 如某度. 最终尝试过的两个可用的方案:

参考代码

Firebase ML Kit

  • 使用前提
    • 需新建Firebase 项目 Firebase 管理后台
    • 下载google-services.json 并放置到项目模块根目录下, 如图
      在这里插入图片描述
    • 测试用的设备需要支持GMS, 即有内置google服务
    • 建议支持连接外网以便登陆google帐户
    • 在应用运行后, GMS服务会检测是否支持OCR, 当未发现模块或不支持时, 会联网下载并安装支持, 在国内的环境, 很艰难才成功了一次(若一直失败, 请尝试清除GMS数据,再重试, LOG参考如下)
2020-01-02 09:45:51.554 1189-1277/com.google.android.gms.persistent W/ConfigurationChimeraPro: Caller is not authorized to access Uri: content://com.google.android.gms.phenotype/com.google.android.gms.vision.sdk -- metadata{ service_id: 51 }
2020-01-02 09:45:51.556 2640-2691/com.testgoogleocr.ocrservice W/DynamiteModule: Local module descriptor class for com.google.android.gms.vision.dynamite.ocr not found.
2020-01-02 09:45:51.561 1189-1277/com.google.android.gms.persistent W/ProviderHelper: Unknown dynamite feature vision.dynamite.ocr
2020-01-02 09:45:51.567 2640-2691/com.testgoogleocr.ocrservice I/DynamiteModule: Considering local module com.google.android.gms.vision.dynamite.ocr:0 and remote module com.google.android.gms.vision.dynamite.ocr:0
2020-01-02 09:45:51.567 2640-2691/com.testgoogleocr.ocrservice D/TextNativeHandle: Cannot load feature, fall back to load dynamite module.
2020-01-02 09:45:51.571 1189-1277/com.google.android.gms.persistent W/ProviderHelper: Unknown dynamite feature vision.ocr
2020-01-02 09:45:51.573 2640-2691/com.testgoogleocr.ocrservice W/DynamiteModule: Local module descriptor class for com.google.android.gms.vision.ocr not found.
2020-01-02 09:45:51.573 2640-2691/com.testgoogleocr.ocrservice I/DynamiteModule: Considering local module com.google.android.gms.vision.ocr:0 and remote module com.google.android.gms.vision.ocr:0
2020-01-02 09:45:51.574 2640-2691/com.testgoogleocr.ocrservice E/Vision: Error loading module com.google.android.gms.vision.ocr optional module true: com.google.android.gms.dynamite.DynamiteModule$LoadingException: No acceptable module found. Local version is 0 and remote version is 0.
2020-01-02 09:45:51.575 2640-2691/com.testgoogleocr.ocrservice D/TextNativeHandle: Broadcasting download intent for dependency ocr
2020-01-02 09:45:51.586 2640-2691/com.testgoogleocr.ocrservice W/TextNativeHandle: Native handle not yet available. Reverting to no-op handle.
2020-01-02 09:45:51.617 1189-1277/com.google.android.gms.persistent W/ConfigurationChimeraPro: Caller is not authorized to access Uri: content://com.google.android.gms.phenotype/com.google.android.gms.clearcut.public -- metadata{ service_id: 51 }
2020-01-02 09:45:51.620 2640-2691/com.testgoogleocr.ocrservice W/DynamiteModule: Local module descriptor class for com.google.android.gms.vision.dynamite.ocr not found.
2020-01-02 09:45:51.627 1189-2278/com.google.android.gms.persistent W/ProviderHelper: Unknown dynamite feature vision.dynamite.ocr
2020-01-02 09:45:51.635 2640-2691/com.testgoogleocr.ocrservice I/DynamiteModule: Considering local module com.google.android.gms.vision.dynamite.ocr:0 and remote module com.google.android.gms.vision.dynamite.ocr:0
2020-01-02 09:45:51.635 2640-2691/com.testgoogleocr.ocrservice D/TextNativeHandle: Cannot load feature, fall back to load dynamite module.
2020-01-02 09:45:51.640 1189-2208/com.google.android.gms.persistent W/ProviderHelper: Unknown dynamite feature vision.ocr
2020-01-02 09:45:51.645 2640-2691/com.testgoogleocr.ocrservice W/DynamiteModule: Local module descriptor class for com.google.android.gms.vision.ocr not found.
2020-01-02 09:45:51.645 2640-2691/com.testgoogleocr.ocrservice I/DynamiteModule: Considering local module com.google.android.gms.vision.ocr:0 and remote module com.google.android.gms.vision.ocr:0
2020-01-02 09:45:51.646 2640-2691/com.testgoogleocr.ocrservice E/Vision: Error loading module com.google.android.gms.vision.ocr optional module true: com.google.android.gms.dynamite.DynamiteModule$LoadingException: No acceptable module found. Local version is 0 and remote version is 0.
2020-01-02 09:45:51.649 2640-2640/com.testgoogleocr.ocrservice W/System.err: com.google.firebase.ml.common.FirebaseMLException: Waiting for the text recognition model to be downloaded. Please wait.
2020-01-02 09:45:51.651 2640-2640/com.testgoogleocr.ocrservice W/System.err:     at com.google.android.gms.internal.firebase_ml.zzsc.zzd(com.google.firebase:firebase-ml-vision@@24.0.1:21)
2020-01-02 09:45:51.651 2640-2640/com.testgoogleocr.ocrservice W/System.err:     at com.google.android.gms.internal.firebase_ml.zzsc.zza(com.google.firebase:firebase-ml-vision@@24.0.1:39)
2020-01-02 09:45:51.651 2640-2640/com.testgoogleocr.ocrservice W/System.err:     at com.google.android.gms.internal.firebase_ml.zzpj.zza(com.google.firebase:firebase-ml-common@@22.0.1:31)
2020-01-02 09:45:51.652 2640-2640/com.testgoogleocr.ocrservice W/System.err:     at com.google.android.gms.internal.firebase_ml.zzpl.call(com.google.firebase:firebase-ml-common@@22.0.1)
2020-01-02 09:45:51.652 2640-2640/com.testgoogleocr.ocrservice W/System.err:     at com.google.android.gms.internal.firebase_ml.zzpf.zza(com.google.firebase:firebase-ml-common@@22.0.1:32)
2020-01-02 09:45:51.652 2640-2640/com.testgoogleocr.ocrservice W/System.err:     at com.google.android.gms.internal.firebase_ml.zzpe.run(com.google.firebase:firebase-ml-common@@22.0.1)
2020-01-02 09:45:51.652 2640-2640/com.testgoogleocr.ocrservice W/System.err:     at android.os.Handler.handleCallback(Handler.java:755)
2020-01-02 09:45:51.652 2640-2640/com.testgoogleocr.ocrservice W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
2020-01-02 09:45:51.652 2640-2640/com.testgoogleocr.ocrservice W/System.err:     at com.google.android.gms.internal.firebase_ml.zze.dispatchMessage(com.google.firebase:firebase-ml-common@@22.0.1:6)
2020-01-02 09:45:51.652 2640-2640/com.testgoogleocr.ocrservice W/System.err:     at android.os.Looper.loop(Looper.java:154)
2020-01-02 09:45:51.652 2640-2640/com.testgoogleocr.ocrservice W/System.err:     at android.os.HandlerThread.run(HandlerThread.java:61)
2020-01-02 09:45:51.673 1189-2696/com.google.android.gms.persistent I/CheckinUtil: Classify the device as Tablet.
2020-01-02 09:45:52.716 1455-2694/com.google.android.gms I/Vision: Details: ocr_armeabi_v7a.zip, a0fa9e293aa78a849c0951e9a9220ca9e9935bd9
2020-01-02 09:45:52.740 1455-2694/com.google.android.gms I/Vision: Engine already satisfied by existing download for ocr
2020-01-02 09:45:52.746 1189-2698/com.google.android.gms.persistent I/CheckinUtil: Classify the device as Tablet.
  • 加入GMS服务支持: 项目根目录下的build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
        google()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.4.0'
		classpath 'com.google.gms:google-services:4.3.3'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
        google()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

classpath 'com.google.gms:google-services:4.3.3’

  • 模块下的build.gradle
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    // ML Kit dependencies
    implementation 'com.google.firebase:firebase-ml-vision:24.0.1'
    // Barcode detection model.
    //implementation 'com.google.firebase:firebase-ml-vision-barcode-model:16.0.2'
    // Image Labeling model.
    //implementation 'com.google.firebase:firebase-ml-vision-image-label-model:19.0.0'
    // Face model
    //implementation 'com.google.firebase:firebase-ml-vision-face-model:19.0.0'
    // Custom model
    //implementation 'com.google.firebase:firebase-ml-model-interpreter:22.0.1'
    // Object model
    //implementation 'com.google.firebase:firebase-ml-vision-object-detection-model:19.0.3'
    // AutoML model
    //implementation 'com.google.firebase:firebase-ml-vision-automl:18.0.3'
}
apply plugin: 'com.google.gms.google-services'
  • AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
    <application>
        <activity ></activity>
        <meta-data
            android:name="com.google.firebase.ml.vision.DEPENDENCIES"
            android:value="ocr" />

	</application>
  • 调用部分代码相对简单
    public static String recorgnizeByFirebase(Context ctx, Bitmap bm){
    
    
        try {
    
    
            FirebaseApp.initializeApp(ctx);
            FirebaseVisionImage fImg = FirebaseVisionImage.fromBitmap(bm);//FirebaseVisionImage.fromFilePath(ctx, Uri.fromFile(new File(path)));
            FirebaseVisionTextRecognizer txtRec = FirebaseVision.getInstance().getOnDeviceTextRecognizer();
            txtRec.processImage(fImg).addOnSuccessListener(new OnSuccessListener<FirebaseVisionText>() {
    
    
                @Override
                public void onSuccess(FirebaseVisionText firebaseVisionText) {
    
    
                    Log.d("Firebase-vision", "onSuccess " + firebaseVisionText.getText());
                }
            }).addOnFailureListener(new OnFailureListener() {
    
    
                @Override
                public void onFailure(@NonNull Exception e) {
    
    
                    e.printStackTrace();
                }
            });
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        return "";
    }

tess-two OCR

  • 提前下载好tessdata文件 tessdata

  • 把tessdata文件放到指定目录

  • 模块下的build.gradle

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.rmtheis:tess-two:6.0.0'
}
  • TessOcr.java
package com.tessocr.ocrservice;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Rect;
import android.os.Environment;
import android.os.SystemClock;

import com.googlecode.tesseract.android.TessBaseAPI;

import java.io.File;

public class TessOcr {
    
    
    static final boolean D = true;
    static void d(String msg){
    
    if(D)android.util.Log.d("TessOcr", "ALog > " + msg);}
    public static final String TESSBASE_PATH = Environment.getExternalStorageDirectory() + "/OcrService";
    public static final String TESSBASE_PATH_FULL = TESSBASE_PATH + "/tessdata";
    public static final String[] SUPPORT_LANGUAGE = {
    
    "eng", "chi_sim"};
    //Bitmap bm;
    private OnOcrResult lis;
    private TessBaseAPI ocrApi;


    public TessOcr(int lan, OnOcrResult lis){
    
    
        this.lis = lis;
        ocrApi = new TessBaseAPI();
        ocrApi.init(TESSBASE_PATH, SUPPORT_LANGUAGE[lan]);
    }

    public String startSync(String path, Rect area) {
    
    
        long st = SystemClock.uptimeMillis();
        d("startSync for " + path);
        String resString = "";
        //ocrApi.setPageSegMode(TessBaseAPI.PageSegMode.PSM_SINGLE_LINE);
        ocrApi.setImage(new File(path));
        if(area != null)ocrApi.setRectangle(area);

        d("stage init api : " + (SystemClock.uptimeMillis() - st));
        resString = ocrApi.getUTF8Text();

        d("stage ocr done : " + (SystemClock.uptimeMillis() - st));

        ocrApi.clear();
        //ocrApi.end();

        return resString;
    }

    public void release(){
    
    
        if(ocrApi != null) ocrApi.end();
    }

    public void startAsync(final String path, final Rect area) {
    
    
        new Thread(){
    
    
            @Override
            public void run() {
    
    
                try {
    
    
                    String res = startSync(path, area);
                    if (lis != null) lis.onResult(res);
                }catch(Exception e){
    
    
                    if (lis != null) lis.onResult(null);
                }
            }
        }.start();
    }

    public interface OnOcrResult{
    
    
        void onResult(String res);
    }
}

相关

Firebase 管理后台
See and Understand Text using OCR with Mobile Vision Text API for Android
Android OCR之tesseract
tessdata
tess-two
利用tess-two和cv4j实现简单的ocr功能

猜你喜欢

转载自blog.csdn.net/ansondroider/article/details/103800947