利用tess-two和cv4j实现简单的ocr功能

本文涉及的产品
文档理解,结构化解析 100页
教育场景识别,教育场景识别 200次/月
自定义KV模板,自定义KV模板 500次/账号
简介: 利用tess-two和cv4j实现简单的ocr功能

ocr



光学字符识别(英语:Optical Character Recognition, OCR)是指对文本资料的图像文件进行分析识别处理,获取文字及版面信息的过程。


Tesseract



Tesseract是Ray Smith于1985到1995年间在惠普布里斯托实验室开发的一个OCR引擎,曾经在1995 UNLV精确度测试中名列前茅。但1996年后基本停止了开发。2006年,Google邀请Smith加盟,重启该项目。目前项目的许可证是Apache 2.0。该项目目前支持Windows、Linux和Mac OS等主流平台。但作为一个引擎,它只提供命令行工具。 现阶段的Tesseract由Google负责维护,是最好的开源OCR Engine之一,并且支持中文。


tess-two是Tesseract在Android平台上的移植。


下载tess-two:

compile 'com.rmtheis:tess-two:8.0.0'


然后将训练好的eng.traineddata放入android项目的assets文件夹中,就可以识别英文了。


1. 简单地识别英文


初始化tess-two,加载训练好的tessdata

private void prepareTesseract() {
        try {
            prepareDirectory(DATA_PATH + TESSDATA);
        } catch (Exception e) {
            e.printStackTrace();
        }
        copyTessDataFiles(TESSDATA);
    }
    /**
     * Prepare directory on external storage
     *
     * @param path
     * @throws Exception
     */
    private void prepareDirectory(String path) {
        File dir = new File(path);
        if (!dir.exists()) {
            if (!dir.mkdirs()) {
                Log.e(TAG, "ERROR: Creation of directory " + path + " failed, check does Android Manifest have permission to write to external storage.");
            }
        } else {
            Log.i(TAG, "Created directory " + path);
        }
    }
    /**
     * Copy tessdata files (located on assets/tessdata) to destination directory
     *
     * @param path - name of directory with .traineddata files
     */
    private void copyTessDataFiles(String path) {
        try {
            String fileList[] = getAssets().list(path);
            for (String fileName : fileList) {
                // open file within the assets folder
                // if it is not already there copy it to the sdcard
                String pathToDataFile = DATA_PATH + path + "/" + fileName;
                if (!(new File(pathToDataFile)).exists()) {
                    InputStream in = getAssets().open(path + "/" + fileName);
                    OutputStream out = new FileOutputStream(pathToDataFile);
                    // Transfer bytes from in to out
                    byte[] buf = new byte[1024];
                    int len;
                    while ((len = in.read(buf)) > 0) {
                        out.write(buf, 0, len);
                    }
                    in.close();
                    out.close();
                    Log.d(TAG, "Copied " + fileName + "to tessdata");
                }
            }
        } catch (IOException e) {
            Log.e(TAG, "Unable to copy files to tessdata " + e.toString());
        }
    }


image.png

取景框.JPG


拍完照后,调用startOCR方法。

private void startOCR(Uri imgUri) {
        try {
            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.
            Bitmap bitmap = BitmapFactory.decodeFile(imgUri.getPath(), options);
            String result = extractText(bitmap);
            resultView.setText(result);
        } catch (Exception e) {
            Log.e(TAG, e.getMessage());
        }
    }


extractText()会调用tess-two的api来实现ocr文字识别。

private String extractText(Bitmap bitmap) {
        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);
        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;
    }


最后,显示识别的效果,此时的效果还算可以。


image.png

简单地识别英文.JPG


2. 识别代码


接下来,尝试用上面的程序识别一段代码。


image.png

识别代码.JPG


此时,效果一塌糊涂。我们重构一下startOCR(),增加局部的二值化处理。

private void startOCR(Uri imgUri) {
        try {
            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.
            Bitmap bitmap = BitmapFactory.decodeFile(imgUri.getPath(), options);
            CV4JImage cv4JImage = new CV4JImage(bitmap);
            Threshold threshold = new Threshold();
            threshold.adaptiveThresh((ByteProcessor)(cv4JImage.convert2Gray().getProcessor()), Threshold.ADAPTIVE_C_MEANS_THRESH, 12, 30, Threshold.METHOD_THRESH_BINARY);
            Bitmap newBitmap = cv4JImage.getProcessor().getImage().toBitmap(Bitmap.Config.ARGB_8888);
            ivImage2.setImageBitmap(newBitmap);
            String result = extractText(newBitmap);
            resultView.setText(result);
        } catch (Exception e) {
            Log.e(TAG, e.getMessage());
        }
    }


在这里,使用cv4j来实现图像的二值化处理。

CV4JImage cv4JImage = new CV4JImage(bitmap);
            Threshold threshold = new Threshold();
            threshold.adaptiveThresh((ByteProcessor)(cv4JImage.convert2Gray().getProcessor()), Threshold.ADAPTIVE_C_MEANS_THRESH, 12, 30, Threshold.METHOD_THRESH_BINARY);
            Bitmap newBitmap = cv4JImage.getProcessor().getImage().toBitmap(Bitmap.Config.ARGB_8888);


图像二值化就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的黑白效果。图像的二值化有利于图像的进一步处理,使图像变得简单,而且数据量减小,能凸显出感兴趣的目标的轮廓。


cv4j的github地址:https://github.com/imageprocessor/cv4j


cv4jgloomyfish和我一起开发的图像处理库,纯java实现。


再来试试效果,图片中间部分是二值化后的效果,此时基本能识别出代码的内容。


image.png

先做二值化再识别代码.JPG


3. 识别中文


如果要识别中文字体,需要使用中文的数据包。可以去下面的网站上下载。


https://github.com/tesseract-ocr/tessdata


跟中文相关的数据包有chi_sim.traineddata、chi_tra.traineddata,它们分别表示是简体中文和繁体中文。

tessBaseApi.init(DATA_PATH, lang);


前面的例子都是识别英文的,所以原先的lang值为"eng",现在要识别简体中文的话需要将其值改为"chi_sim"。


image.png

识别中文.JPG


最后



本项目只是demo级别的演示,离生产环境的使用还差的很远。


本项目的github地址:https://github.com/fengzhizi715/Tess-TwoDemo


为何说只是demo级别呢?


  • 数据包很大,特别是中文的大概有50多M,放在移动端的肯定不合适。一般正确的做法,都是放在云端。
  • 识别文字很慢,特别是中文,工程上还有很多优化的空间。
  • 做ocr之前需要做很多预处理的工作,在本例子中只用了二值化,其实还有很多预处理的步骤比如倾斜校正、字符切割等等。
  • 为了提高tess-two的识别率,可以自己训练数据集。
相关文章
|
6月前
|
文字识别 API 数据安全/隐私保护
可以使用阿里云文字识别服务中的个人证照识别功能。
可以使用阿里云文字识别服务中的个人证照识别功能。【1月更文挑战第21天】【1月更文挑战第102篇】
45 1
|
5月前
|
文字识别 算法
印刷文字识别产品使用合集之开通了阿里云发票识别验真功能,其他人可以调用我的这个接口吗
印刷文字识别产品,通常称为OCR(Optical Character Recognition)技术,是一种将图像中的印刷或手写文字转换为机器编码文本的过程。这项技术广泛应用于多个行业和场景中,显著提升文档处理、信息提取和数据录入的效率。以下是印刷文字识别产品的一些典型使用合集。
|
3月前
|
机器学习/深度学习 文字识别 前端开发
基于 Spring Boot 3.3 + OCR 实现图片转文字功能
【8月更文挑战第30天】在当今数字化信息时代,图像中的文字信息越来越重要。无论是文档扫描、名片识别,还是车辆牌照识别,OCR(Optical Character Recognition,光学字符识别)技术都发挥着关键作用。本文将围绕如何使用Spring Boot 3.3结合OCR技术,实现图片转文字的功能,分享工作学习中的技术干货。
166 2
|
4月前
|
文字识别 Java API
印刷文字识别使用问题之发票凭证识别功能是否可以对接ERP系统
印刷文字识别产品,通常称为OCR(Optical Character Recognition)技术,是一种将图像中的印刷或手写文字转换为机器编码文本的过程。这项技术广泛应用于多个行业和场景中,显著提升文档处理、信息提取和数据录入的效率。以下是印刷文字识别产品的一些典型使用合集。
|
4月前
|
文字识别
印刷文字识别使用问题之自定义模板功能在什么地方
印刷文字识别产品,通常称为OCR(Optical Character Recognition)技术,是一种将图像中的印刷或手写文字转换为机器编码文本的过程。这项技术广泛应用于多个行业和场景中,显著提升文档处理、信息提取和数据录入的效率。以下是印刷文字识别产品的一些典型使用合集。
|
5月前
|
文字识别 自然语言处理 开发工具
印刷文字识别产品使用合集之OCR统一识别功能已开通,响应为200但没有content信息,是什么原因
印刷文字识别产品,通常称为OCR(Optical Character Recognition)技术,是一种将图像中的印刷或手写文字转换为机器编码文本的过程。这项技术广泛应用于多个行业和场景中,显著提升文档处理、信息提取和数据录入的效率。以下是印刷文字识别产品的一些典型使用合集。
|
6月前
|
JSON 文字识别 数据可视化
印刷文字识别产品使用合集之有识别二维码并将识别二维码的内容通过接口返回的功能吗
印刷文字识别(Optical Character Recognition, OCR)技术能够将图片、扫描文档或 PDF 中的印刷文字转化为可编辑和可搜索的数据。这项技术广泛应用于多个领域,以提高工作效率、促进信息数字化。以下是一些印刷文字识别产品使用的典型场景合集。
|
6月前
|
文字识别 安全 API
阿里云文字识别OCR的发票凭证识别功能可以通过API接口的形式进行调用
【2月更文挑战第5天】阿里云文字识别OCR的发票凭证识别功能可以通过API接口的形式进行调用
294 5
|
6月前
|
文字识别 API 数据安全/隐私保护
以使用阿里云文字识别服务中的个人证照识别功能
以使用阿里云文字识别服务中的个人证照识别功能【1月更文挑战第24天】【1月更文挑战第118篇】
183 2
|
6月前
|
移动开发 人工智能 文字识别
如何在H5中实现OCR拍照识别身份证功能
如何在H5中实现OCR拍照识别身份证功能
432 0

热门文章

最新文章

  • 1
    【Python】已解决:Python正确安装文字识别库EasyOCR
    373
  • 2
    提升爬虫OCR识别率:解决嘈杂验证码问题
    110
  • 3
    文本,文字识别14,身份证和车牌识别接口
    26
  • 4
    文本,文字识别13,参数校验,实现参数校验,使用@Valid注解
    26
  • 5
    文本,文字识别12,接口返回值和异常封装,一个好的接口,应该包括,错误码,提示信息,返回的数据,应该知道出错,错在哪里,抛出业务异常应该怎样解决?出现业务异常的时候,抛出业务异常,全局异常处理
    36
  • 6
    文本,文识11,解析OCR结果,paddOCR返回的数据,接口返回的数据有code,data,OCR返回是JSON的数据,得到JSON数据先安装依赖,Base64转换工具网站在21.14
    92
  • 7
    文本,文识10,springBoot提供RestTemplate以调用Flask OCR接口,调用flask实现ocr接口,用paddleocr进行图片识别云服务技术,单个paddleocr接口有影响
    86
  • 8
    文本,文识08图片保存()上,最方便在于整体生成代码,serivce及实体类,base64编码保存图片文件,调用flask实现内部ocr接口,通过paddleocr识别,解析结果,base64转图片
    44
  • 9
    文本,文字识别07,SpringBoot服务开发-入参和返回值,编写接口的时候,要注意识别的文字返回的是多行,因此必须是List集合,Bean层,及实体类的搭建
    45
  • 10
    文本,文字识别,Flask实现内部接口开发,OCR外部接口的开发,如何开发一个识别接口,通过post调用,参数是图片的路径,内部调用,直接传图片路径就行
    62