首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Tesseract ocr文字识别

Tesseract ocr文字识别

作者头像
bear_fish
发布2018-09-19 11:31:14
16.3K0
发布2018-09-19 11:31:14
举报

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://cloud.tencent.com/developer/article/1342655

前面很早做了图片的文字识别主要用到了开源框架Tesseract,当然做OCR之前先要定位图片文字。先上个图:

工作中项目组一般使用java因此代码,下面贴出java代码,最简单的图片识别:

package com.recognition;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.text.DecimalFormat;

import net.sourceforge.tess4j.*;
import org.bytedeco.javacpp.opencv_core.Mat;
import org.bytedeco.javacpp.opencv_core.Rect;

import static cv.skindetect.CvConvertHelper.matToImg;

/**
 * Created by DW_xiongyu on 2016/11/21.
 */
public class TesseractExample {

    public static String getRectWord(BufferedImage img, Rect rect) throws TesseractException {

        ITesseract instance = new Tesseract();  // JNA Interface Mapping
        String fontPath = "E:/char_recongition/Tesseract-OCR/tessdata";
        instance.setDatapath(fontPath);
        instance.setLanguage("chi_sim");

        long start = System.currentTimeMillis();
        Rectangle rectangle = new Rectangle(rect.x(), rect.y(), rect.width(), rect.height());
        String result = instance.doOCR(img, rectangle);
        long end = System.currentTimeMillis();


        DecimalFormat form = new DecimalFormat("0.00");
        //float xRatio = (float)rect.width() / img.getWidth();
        //float yRatio = (float)rect.height() / img.getHeight();
        //String strRatio = " xRatio " + form.format(xRatio) + " yRatio :" + form.format(yRatio);

        System.out.println(" result: " + result+" time consume :"+(float)(end-start)/1000 + "S");

        return result;
    }

    public static void main(String[] args) {
        String path = "F:/img_test/online_sample_img/10.jpg";


        File imageFile = new File(path);
        ITesseract instance = new Tesseract();  // JNA Interface Mapping

        try {
            String fontPath = "E:/char_recongition/Tesseract-OCR/tessdata";
            instance.setDatapath(fontPath);

            instance.setLanguage("chi_sim");

            long start = System.currentTimeMillis();
            String result = instance.doOCR(imageFile);
            long end = System.currentTimeMillis();
            System.out.println("Tesseract time consume :"+(float)(end-start)/1000 + "S");
            System.out.println(result);
        } catch (TesseractException e) {
            System.err.println(e.getMessage());
        }
    }
}

图片文字提取,原理相信会opencv的大致要看下结合上面的截图应该看得明白:

package cv.wordExtract;

import com.recognition.TesseractExample;
import com.thrift.ocrimg.DetectLetter;
import net.sourceforge.tess4j.TesseractException;
import org.apache.commons.collections.CollectionUtils;
import org.bytedeco.javacpp.opencv_core.Point;
import org.bytedeco.javacpp.opencv_core.Scalar;
import org.bytedeco.javacpp.opencv_core.MatVector;
import org.bytedeco.javacpp.opencv_core.Size;
import org.bytedeco.javacpp.opencv_core.Mat;
import org.bytedeco.javacpp.opencv_core.Rect;
import org.junit.Test;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

import static cv.skindetect.CvConvertHelper.imgToMat;
import static cv.skindetect.CvConvertHelper.matToImg;
import static org.bytedeco.javacpp.opencv_core.putText;
import static org.bytedeco.javacpp.opencv_core.FONT_HERSHEY_PLAIN;
import static org.bytedeco.javacpp.opencv_core.rectangle;
import static org.bytedeco.javacpp.opencv_highgui.*;
import static org.bytedeco.javacpp.opencv_imgproc.*;

/**
 * Created by DW_xiongyu on 2016/11/29.
 */
public class DetectLetters {

    //the minimum width and height of detected rect
    private final static int MIN_WH = 20;
    private final static int MINIMUM_AREA = 1000;
    private final static float HW_RATIO = 2.85F;
    //private final static double MINIMUM_AREA = 400;
    private final static int DETECT_COUNT_THREAD = 12;
    private final static boolean DEBUG = true;
    //private final static boolean DEBUG = false;
    private final static boolean SAVE = true;


    public List<Rect> getLetterRectLst(Mat srcMat, int i) throws IOException {
        List<Rect> rectList = new LinkedList<Rect>();

        Mat matGray = new Mat();
        cvtColor(srcMat, matGray, COLOR_RGB2GRAY);

        if (DEBUG) {
            imshow("matGray", matGray);
        }

        Mat matSobel = new Mat();
        Sobel(matGray, matSobel, 0, 1, 0, 3, 1, 0, BORDER_DEFAULT);
        if (DEBUG) {
            imshow("matSobel", matSobel);
        }


        Mat matThreshold = new Mat();
        threshold(matSobel, matThreshold, 0, 255, CV_THRESH_OTSU + CV_THRESH_BINARY);
        if (DEBUG) {
            imshow("matSobel2matThreshold", matThreshold);
        }

        Mat exElement = getStructuringElement(MORPH_RECT, new Size(17, 3));

        morphologyEx(matThreshold, matThreshold, CV_MOP_CLOSE, exElement);

        if(i > 0 && SAVE){
            String savePath = "F:/img_test/online_sample_img/extract_tmp/tmp/"+i+"mor.jpg";
            mat2ImgFile(matThreshold, savePath);
        }

        if (DEBUG) {
            imshow("matThreshold2morphologyEx", matThreshold);
        }
        //waitKey(0);

        MatVector matVector = new MatVector();
        findContours(matThreshold, matVector, RETR_EXTERNAL, CHAIN_APPROX_NONE);
        //findContours(matThreshold, matVector, RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);

        MatVector matVectorCopy = new MatVector(matVector.size());
        int len = (int) matVector.size();
        Mat matTmp;
        for ( i = 0; i < len; i++) {
            matTmp = matVector.get(i);
            approxPolyDP(matTmp, matVectorCopy.get(i), 3, true);
            Rect appRect = boundingRect(matVectorCopy.get(i));
            if (isWordRect(appRect)) {
                rectList.add(appRect);
                //System.out.println("nomal area: "+ appRect.area());
                //System.out.println("min area: "+ minAreaRect(matVectorCopy.get(i)).boundingRect().area());
            }
        }

        return rectList;
    }

    public void mat2ImgFile(Mat mat, String path) throws IOException {
        BufferedImage image  = matToImg(mat);
        ImageIO.write(image, "jpg", new File(path));
    }


    public void doExtract(String path) throws TesseractException, IOException {

        Mat imgMat = imread(path);
        System.out.println(" width: " + imgMat.cols() + " height: " + imgMat.rows());
        BufferedImage img = matToImg(imgMat);
        System.out.println(" width: " + img.getWidth()+ " height: " + img.getHeight());

        List<Rect> lstRect = getLetterRectLst(imgMat, -1);
        if (CollectionUtils.isNotEmpty(lstRect)){
            int count = 1;
            StringBuffer stringBuf = new StringBuffer();
            for (Rect rect:lstRect){
                rectangle(imgMat, rect, new Scalar(0, 255, 0, 0),  3, 8, 0);
                putText(imgMat, String.valueOf(count), new Point(rect.x(), rect.y()), FONT_HERSHEY_PLAIN, 2.8, new Scalar(0,0,0, 0));
                System.out.print("num: " + String.valueOf(count++) + " ");
                String str = TesseractExample.getRectWord(img, rect);
                stringBuf.append(str);
            }
            System.out.print("recognition result: " + stringBuf.toString().replaceAll("\n", ""));
        }

        imshow("imgMat", imgMat);
        waitKey(0);
        destroyAllWindows();
    }


    public static void main(String[] args) throws TesseractException, IOException {
        DetectLetters detectLetters = new DetectLetters();

        String path = "F:/huaya.jpg";
        path = "F:/img_test/online_sample_img/53.jpg";
        detectLetters.doExtract(path);
    }
}

代码在个人github

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017年09月01日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
文字识别
文字识别(Optical Character Recognition,OCR)基于腾讯优图实验室的深度学习技术,将图片上的文字内容,智能识别成为可编辑的文本。OCR 支持身份证、名片等卡证类和票据类的印刷体识别,也支持运单等手写体识别,支持提供定制化服务,可以有效地代替人工录入信息。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档