2

我使用以下函数使用 Tesseract OCR 的 Android fork Tess-Two 执行离线 OCR:

private String startOCR(Uri imgUri) {
    try {
        ExifInterface exif = new ExifInterface(imgUri.getPath());
        int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
        int rotate = 0;
        switch(exifOrientation) {
            case ExifInterface.ORIENTATION_ROTATE_90:
                rotate = 90;
                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                rotate = 180;
                break;
            case ExifInterface.ORIENTATION_ROTATE_270:
                rotate = 270;
                break;
        }
        Log.d(TAG, "Rotation: " + rotate);

        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 4; // 1 - means max size. 4 - means maxsize/4 size. Don't use value <4, because you need more memory in the heap to store your data.
        // set to 300 dpi
        options.inTargetDensity = 300;
        Bitmap bitmap = BitmapFactory.decodeFile(imgUri.getPath(), options);

        // Change Orientation via EXIF
        if (rotate != 0) {

            // Getting width & height of the given image.
            int w = bitmap.getWidth();
            int h = bitmap.getHeight();

            // Setting pre rotate
            Matrix mtx = new Matrix();
            mtx.preRotate(rotate);

            // Rotating Bitmap
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, false);

        }

        // To Grayscale
        bitmap = toGrayscale(bitmap);

        final Bitmap b = bitmap;

        final ImageView ivResult = (ImageView)findViewById(R.id.ivResult);
        if(ivResult != null) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    ivResult.setImageBitmap(b);
                }
            });

        }
        return extractText(bitmap);
    } catch (Exception e) {
        Log.e(TAG, e.getMessage());
        return "";
    }
}

这是extractText()方法:

private String extractText(Bitmap bitmap) {
    //Log.d(TAG, "extractText");
    try {
        tessBaseApi = new TessBaseAPI();
    } catch (Exception e) {
        Log.e(TAG, e.getMessage());
        if (tessBaseApi == null) {
            Log.e(TAG, "TessBaseAPI is null. TessFactory not returning tess object.");
        }
    }

    tessBaseApi.init(DATA_PATH, lang);

    //EXTRA SETTINGS
    tessBaseApi.setVariable(TessBaseAPI.VAR_CHAR_WHITELIST, "abcdefghijklmnopqrstuvwxyz1234567890',.?;/ ");

    Log.d(TAG, "Training file loaded");
    tessBaseApi.setDebug(true);
    tessBaseApi.setPageSegMode(TessBaseAPI.PageSegMode.PSM_AUTO_OSD);
    tessBaseApi.setImage(bitmap);
    String extractedText = "empty result";
    try {
        extractedText = tessBaseApi.getUTF8Text();
    } catch (Exception e) {
        Log.e(TAG, "Error in recognizing text.");
    }
    tessBaseApi.end();
    return extractedText;
}

的返回值extractText()显示在以下屏幕截图中:

结果不准确

精度超低,尽管我在执行 OCR 之前将图像灰度和放大到 300 dpi。我怎样才能改善结果?训练出来的数据不够好?

4

2 回答 2

4

我已经进行了一些测试,但是,我有一些可以改善您的结果的观点和结论。

  1. 尝试在 VAR_WHITE_CHARLIST 变量参数中传递小写和大写字母:

查看我的输入结果:

在此处输入图像描述

a) 仅小写:

范围:

baseApi.setVariable(TessBaseAPI.VAR_CHAR_WHITELIST, "abcdefghijklmnopqrstuvwxyz1234567890',.?;/ ");

结果:

05 atenienenses nnito, hdeleto e laicao, os principais acusadores de gocrates, nao defiam apenas que o filosofo corrompia a juventude; eles lutavam tama bern pelas virtudes da tradigaopoetica vinculada a liornero。nristofanes, um dos responsaveis, segundo socrates, dos preconceitos contra o filosofo, era outro grande defensor dessa virtude。

socrates, de certa forma, estava em guerra com a tradieao Potica grega。0 meodo de socrates era o opposto a narrativa epica de tlornero。sua dialetica nao tinha nada de semideuses 玉米 superpoderes 6

b) 大写和小写字母:

范围:

baseApi.setVariable(TessBaseAPI.VAR_CHAR_WHITELIST, "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ1234567890',.?;/ ");

结果:

Os atenienenses Anito, Meleto e Licao, os principais acusadores de Socrates, nao defiam apenas que o filosofo corrompia a juventude; eles lutavam tama bern pelas virtudes da tradigao pointica vinculada a Homero。Aristofanes, um dos responsaveis, segundo socrates, dos preconceitos contra o filosofo, era outro grande defensor dessa virtude。

socrates, de certa forma, estava em guerra com a tradieao Potica grega。O metodo de socrates era o Oposto a narrativa epica de Homero。Sua dialetica nao tinha nada de semideuses 玉米 superpoderes 6

PS:我已经使用葡萄牙语运行了这个示例,检查一些需要不同字符的单词,例如:'é ó ç' 它不起作用,因为它没有作为字符传递到白名单中。

我也试过用你的图片跑,结果有改善(不是很多):

字体 20;其中polrlrcran已经捕捉到了曲线,总结了一种成长的心情。在一个可怕的演讲中?“你们的钢铁工业已经死了。像穆农一样死去。你的煤 yum mono 大大对铁 Vbur Ilk Mary 是和。o 你的羊毛产业是为什么。您的经典 Wilding 先生的行业。发送邮件

所以我检查了 tesseract 如何对图像进行二值化:

保留图像

您的图像有很多噪音,然后 api 尝试对您的图像进行二值化,这使您的图片的很大一部分难以辨认。我建议您再次尝试运行,但不要通过灰度,并尝试研究如何减少图像中的噪点。

为了帮助您完成调试任务,您可以保存保留的图像:

WriteFile.writeBitmap(baseApi.getThresholdedImage())

我希望它对你有用!感谢您分享您的问题!

阿布拉索斯!

于 2016-11-14T15:55:57.093 回答
0

在这一行中 options.inSampleSize = 4; 将数字从 4 更改为 1 并尝试再次执行 ocr

于 2017-02-05T05:31:39.640 回答