图像文字识别(二):java调用tesseract 识别图片文字

图像文字识别(二):java调用tesseract 识别图片文字

  在JAVA中调用tesseract识别图片的文字内容,主要有两种方式:cmd方式,tess4j方式。在这篇博客中,主要记录一下通过cmd命令行的方式。cmd方式,就是通过在java中调用命令行,来执行tesseract,它的原理就是上篇博客所写的内容。

步骤:

(1)导入两个jar包:jai_imageio-1.1.1.jar 和 swingx-1.6.1.jar

(2)编写ImageIOHelper类,用于创建临时图片文件,防止损坏初始文件

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.Locale;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.ImageOutputStream;

import com.sun.media.imageio.plugins.tiff.TIFFImageWriteParam;
/** 
* 类说明 :创建临时图片文件防止损坏初始文件
*/
public class ImageIOHelper {
	
	    //设置语言
	    private Locale locale=Locale.CHINESE;

	     //自定义语言构造的方法
	    public ImageIOHelper(Locale locale){
	        this.locale=locale;
	    }
	    //默认构造器Locale.CHINESE
	    public ImageIOHelper(){
	    }
	    
	    
	    /**
	     * 创建临时图片文件防止损坏初始文件
	     * @param imageFile
	     * @param imageFormat like png,jps .etc
	     * @return TempFile of Image
	     */
	    public File createImage(File imageFile, String imageFormat) throws IOException {
	    	
	    	//读取图片文件
	        Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName(imageFormat);    
	        ImageReader reader = readers.next();
	        //获取文件流
	        ImageInputStream iis = ImageIO.createImageInputStream(imageFile);
	        reader.setInput(iis);
	        IIOMetadata streamMetadata = reader.getStreamMetadata();   
	        
	        //设置writeParam
	        TIFFImageWriteParam tiffWriteParam = new TIFFImageWriteParam(Locale.CHINESE);    
	        tiffWriteParam.setCompressionMode(ImageWriteParam.MODE_DISABLED); //设置可否压缩 
	        //获得tiffWriter和设置output
	        Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("tiff");    
	        ImageWriter writer = writers.next();    
	        
	        
	        BufferedImage bi = reader.read(0);    
	        IIOImage image = new IIOImage(bi,null,reader.getImageMetadata(0));    
	        File tempFile = tempImageFile(imageFile);    
	        ImageOutputStream ios = ImageIO.createImageOutputStream(tempFile);    
	        
	        writer.setOutput(ios);    
	        writer.write(streamMetadata, image, tiffWriteParam); 
 
	        ios.close();
	        iis.close();
	        writer.dispose();    
	        reader.dispose();    
	        
	        return tempFile;    
	    }    
	    
	    /**
	     * 给tempfile添加后缀
	     * @param imageFile
	     * @throws IOException 
	     */
	    private File tempImageFile(File imageFile) throws IOException {    
	        String path = imageFile.getPath();    
	        StringBuffer strB = new StringBuffer(path);    
	        strB.insert(path.lastIndexOf('.'),"_text_recognize_temp");
	        String s=strB.toString().replaceFirst("(?<=//.)(//w+)$", "tif");
	        Runtime.getRuntime().exec("attrib "+"\""+s+"\""+" +H"); //设置文件隐藏
	        return new File(strB.toString()); 
	    }    
}

(3)创建OCRUtil工具类,用于进行图片文字识别:

import java.io.BufferedReader;    
import java.io.File;    
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;    
import java.util.ArrayList;    
import java.util.List;
import java.util.Locale;

import org.jdesktop.swingx.util.OS;

/** 
* 类说明:OCR工具类
*/
public class OCRUtil {
	private final String LANG_OPTION = "-l";  //英文字母小写l,并非阿拉伯数字1    
    private final String EOL = System.getProperty("line.separator");    
    private String tessPath = "D://Tesseract//Tsseract-OCR//Tesseract-OCR";//ocr的安装路径
    
  
    public OCRUtil(String tessPath,String transFileName){
        this.tessPath=tessPath;
    }
    
    //OCRUtil的构造方法,默认路径是"C://Program Files (x86)//Tesseract-OCR"
    public OCRUtil(){     }
    
    public String getTessPath() {
        return tessPath;
    }
    public void setTessPath(String tessPath) {
        this.tessPath = tessPath;
    }
    public String getLANG_OPTION() {
        return LANG_OPTION;
    }
    public String getEOL() {
        return EOL;
    }
    
    
    /**
     * @param 需要识别的文件
     * @param 文件的格式
     * @return 识别后的文字
     */
    public String recognizeText(File imageFile,String imageFormat)throws Exception{    
        File tempImage = new ImageIOHelper().createImage(imageFile,imageFormat);    
        return ocrImages(tempImage, imageFile);   
    }    
    
    //可以自定义语言
    public String recognizeText(File imageFile,String imageFormat,Locale locale)throws Exception{    
        File tempImage = new ImageIOHelper(locale).createImage(imageFile,imageFormat);
        return ocrImages(tempImage, imageFile);
    }
    
    /**
     * @param 临时文件
     * @param 需要识别的文件
     * @return 识别后的内容
     * @throws IOException
     * @throws InterruptedException
     */
    private String ocrImages(File tempImage,File imageFile) throws IOException, InterruptedException{
       
    	//设置输出文件的保存的文件目录,以及文件名
    	File outputFile = new File(imageFile.getParentFile(),"test");
        StringBuffer strB = new StringBuffer();  
       
        
        //设置命令行内容
        List<String> cmd = new ArrayList<String>();    
        if(OS.isWindowsXP()){    
            cmd.add(tessPath+"//tesseract");    
        }else if(OS.isLinux()){    
            cmd.add("tesseract");    
        }else{    
            cmd.add(tessPath+"//tesseract");    
        }    
        cmd.add("");    
        cmd.add(outputFile.getName());    
        cmd.add(LANG_OPTION);    
        cmd.add("chi_sim");//中文包
        cmd.add("equ");//常用数学公式包
        cmd.add("eng");//英语包
        
        
        //创建操作系统进程
        ProcessBuilder pb = new ProcessBuilder();    
        pb.directory(imageFile.getParentFile());//设置此进程生成器的工作目录   
        cmd.set(1, tempImage.getName());    
        pb.command(cmd);//设置要执行的cmd命令 
        pb.redirectErrorStream(true);//设置后续子进程生成的错误输出都将与标准输出合并   
        
        long startTime = System.currentTimeMillis();
        System.out.println("开始时间:" + startTime);
        
        Process process = pb.start();//开始执行,并返回进程实例 
        //最终执行命令为:tesseract 1.png test -l chi_sim+equ+eng
        
        int w = process.waitFor();    
        tempImage.delete();//删除临时正在工作文件         
        if(w==0){ // 0代表正常退出
            BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(outputFile.getAbsolutePath()+".txt"),"UTF-8"));    
            String str;    
            while((str = in.readLine())!=null){    
                strB.append(str).append(EOL);    
            }    
            in.close();   
            
            long endTime = System.currentTimeMillis();
            System.out.println("结束时间:" + endTime);
            System.out.println("耗时:" + (endTime - startTime) + "毫秒");
            
        }else{    
            String msg;    
            switch(w){    
            case 1:    
                msg = "Errors accessing files.There may be spaces in your image's filename.";    
                break;    
            case 29:    
                msg = "Cannot recongnize the image or its selected region.";    
                break;    
            case 31:    
                msg = "Unsupported image format.";    
                break;    
            default:    
                msg = "Errors occurred.";    
            }    
            tempImage.delete();    
            throw new RuntimeException(msg);    
        }    
        new File(outputFile.getAbsolutePath()+".txt");//.delete();    
        return strB.toString().replaceAll("\\s*", ""); 
    }
}

(4)创建测试类Test:

import java.io.File;
import java.io.IOException;

/** 
* @version 创建时间:2018年4月25日 下午5:09:19 
* 类说明:测试类
*/
public class Test {

    public static void main(String[] args) {

	try {
            //图片文件:此图片是需要被识别的图片路径 
            File file = new File("C://Users//1_20180208150251_x4hzz//1.png");
            //String recognizeText = new OCRHelper().recognizeText(file);
            String recognizeText = new OCRUtil().recognizeText(file, "png");
            System.out.print(recognizeText + "\t");

        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

至此,只要传入需要识别的图片,就可以识别出图片中的文字的内容了。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/114744.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • byte数组截取[通俗易懂]

    byte数组截取[通俗易懂]//原始数组byte[]bytes=ImageUtils.toByteArray(fromPaths[0]);//新数组byte[]b1=newbyte[bytes.length-80];//从原始数组80位置开始截取后面所有System.arraycopy(bytes,80,b1,0,bytes.length-80);BufferData2DbufferDat…

    2022年6月11日
    218
  • oracle dba教程视频_数据库中的DBA

    oracle dba教程视频_数据库中的DBA我机器上只有一部分的版本:http://v.youku.com/v_show/id_XMTk3MTgzMzI=.htmlhttp://www.ixdba.net/article/b3/1317.htmlhttp://itboba.com/taxonomy/term/620http://v.youku.com/v_playlist/f2972170o1p9.html

    2025年7月29日
    4
  • 理解HTTP和TCP

    理解HTTP和TCP TCP协议对应于传输层,而HTTP协议对应于应用层,从本质上来说,二者没有可比性。Http协议是建立在TCP协议基础之上的,当浏览器需要从服务器获取网页数据的时候,会发出一次Http请求。Http会通过TCP建立起一个到服务器的连接通道,当本次请求需要的数据完毕后,Http会立即将TCP连接断开,这个过程是很短的。所以Http连接是一种短连接,是一种无状态的连接。所谓的无状态,是指浏览器每次向服…

    2022年9月14日
    3
  • 欧拉函数求法

    欧拉函数求法欧拉函数是计算在1-n中n的质因数的个数;φ(x)=x*(p1-1)/p1*(p2-1)/p2*(p3-1)/p3…*(pn-1)/pn其中p1,p2,p3…是x的质因数;若x是质数:φ(x)=x-1若x是质数p的k次幂(即x=p^k):φ(x)=p^k-p^(k-1)=(p-1)p^(k-1)积性:φ(n*m)=φ(n)*φ(m)其中m、n互质。具体的证明和其他介绍就不多说了=.

    2022年8月22日
    8
  • 近距离接触品牌与终端

    近距离接触品牌与终端

    2021年8月12日
    51
  • pytest报错_git代码提交流程

    pytest报错_git代码提交流程前言我们每天写完自动化用例后都会提交到git仓库,随着用例的增多,为了保证仓库代码的干净,当有用例新增的时候,我们希望只运行新增的未提交git仓库的用例。pytest-picked插件可以

    2022年7月28日
    8

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号