java程序集成Tesseract-OCR识别图片信息
来源:互联网 发布:雄霸九州辅助软件 编辑:程序博客网 时间:2024/06/05 05:31
java程序集成Tesseract-OCR识别图片信息
最近老大说是要实现一个识别图片中的信息,然后与数据库中的相关信息匹配的一个功能,然后给了我说了个OCR技术,叫我去看看。没搞过啊,只能赶紧网上搜索资料,资料还挺多。OCR(Optical Character Recognition,光学字符识别),比较常用的是谷歌的一个ocr引擎Tesseract-OCR,然后去网上下载下载下来解压,通过cmd命令测试,定位到文件夹下,然后通过命令tesseract 001.jpg 123 -l chi_sim测试效果还不错,tesseract-ocr 3.0可以支持中文,然后就想用程序来调用命令。
- cmd测试效果图
执行ocr命令:
需要解析的图片:
解析识别出来的文字:
保证图片的分辨率还是挺准确的。
然后是通过java程序来执行命令,这个也是比较简单的,但是也是遇到了两个问题:
- 问题1
tesseract-ocr 不支持pdf格式的解析,对tif格式图片解析也不是很好的支持,我要实现的是对pdf进行解析,这就难免要进行图片的转换,pdf具有文档形式和图片形式(扫描版)而且具有很多版本,本以为很简单的事情,但是尝试了很多方法各种扩展jar包都不能全面兼容,最后终于找到了pdfbox-app-2.0.7.jar+jbig2-imageio-1.6.5.jar解决掉 - 问题2
tesseract-ocr解析效率特别慢,解析一张a4纸大小的图片,需要
花费二三十秒,简直无法忍受。但是tesseract-ocr这东西毕竟太高深没法碰,只能从图片入手,之前测试的一行字的小图片解析只需要一秒钟,所以就以这种形式,将自己需要的图片信息截取下来,然后通过多线程调用tesseract-ocr进行解析,效果还不错,下面附源代码:
OcrEngine.java
package com.jj.test2;import java.awt.image.BufferedImage;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.util.Map;import java.util.Set;import java.util.UUID;import java.util.Vector;import javax.imageio.ImageIO;import org.apache.pdfbox.pdmodel.PDDocument;import org.apache.pdfbox.pdmodel.encryption.InvalidPasswordException;import org.apache.pdfbox.rendering.ImageType;import org.apache.pdfbox.rendering.PDFRenderer;public class OcrEngine{ /** * 日志 */ private static String tesspath ; //ocr路径 private static String tempath ; //临时文件路径 private static String TYPE_PDF = "pdf";//定义处理图片的类型 private static String TYPE_JPG = "jpg"; /** * 解析文件 * @param context * @param file * @throws TxnException */ public static void main(String args[]){ try { Map<String,String> result = parseFile(new File("d:\\testdata\\001.pdf")); for(Map.Entry<String,String> entry : result.entrySet()){ System.out.print("Key = "+entry.getKey()+",value="+entry.getValue()); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static Map<String,String> parseFile(File file) throws Exception{ Long start = System.currentTimeMillis(); tempath = "d:\\temp\\"; tesspath = "d:\\application\\Tesseract-OCR\\"; try{ if(!new File(tempath).exists()){ new File(tempath).mkdir(); } if(!new File(tesspath+File.separator+"tesseract.exe").exists()){ throw new RuntimeException("OCR异常-不存在OCR引擎"); } if(!file.exists()){ throw new RuntimeException("OCR异常-图片文件不存在"); } String filetype = file.getName().substring(file.getName().lastIndexOf(".")+1); System.out.println("=========>runtime1:"+(System.currentTimeMillis()-start)); if(TYPE_PDF.equals(filetype)){//可以自行添加图片格式 file = pdf2Jpg(file); }else{ throw new RuntimeException("OCR异常-不支持的文件格式"); } System.out.println("=========>runtime3:"+(System.currentTimeMillis()-start)); Vector<Thread> threads = new Vector<Thread>(); OcrOperate oop = new OcrOperate(file, tempath); for (int i = 0; i < 4; i++) { Thread iThread = new Thread(oop); threads.add(iThread); iThread.start(); } for (Thread iThread : threads) { try { // 等待所有线程执行完毕 iThread.join(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("=========>runtime4:"+(System.currentTimeMillis()-start)); return oop.getResult(); } catch (Exception e){ throw new RuntimeException("OCR异常-解析文件错误",e); } } /** * 将pdf文件转换成jpg文件 * @param infile * @return * @throws InvalidPasswordException * @throws IOException */ private static File pdf2Jpg(File infile) throws InvalidPasswordException, IOException { Long start = System.currentTimeMillis(); File outfile = null; PDDocument document = null; PDFRenderer renderer = null; try { document = PDDocument.load(infile, (String)null); outfile = new File(tempath+File.separator+UUID.randomUUID()+".jpg");//输出文件 ImageIO.scanForPlugins(); renderer = new PDFRenderer(document); System.out.println("=========>runtime1.1:"+(System.currentTimeMillis()-start)); BufferedImage image = renderer.renderImageWithDPI(0,300,ImageType.RGB);//控转换那种图片以及图片的像素 System.out.println("=========>runtime1.2:"+(System.currentTimeMillis()-start)); FileOutputStream out = new FileOutputStream(outfile); ImageIO.write(image, TYPE_JPG, out); out.close(); System.out.println("=========>runtime1.3:"+(System.currentTimeMillis()-start)); return outfile; } finally{ if(document!=null){ document.close(); } } }}
OcrOperate.java
package com.jj.test2;import java.awt.Rectangle;import java.awt.image.BufferedImage;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.HashMap;import java.util.LinkedList;import java.util.List;import java.util.Map;import java.util.UUID;import javax.imageio.ImageIO;import javax.imageio.ImageReadParam;import javax.imageio.ImageReader;import javax.imageio.stream.ImageInputStream;import org.jdesktop.swingx.util.OS;public class OcrOperate implements Runnable{ /** * 日志 */ private String tesspath ; //ocr路径 private String tempath ; //临时文件路径 private File file; //操作的文件 private String TYPE_JPG = "jpg"; //文件类型 private Map<String, String> result = new HashMap<String, String>(); //返回的结果集 private LinkedList<int[]> list = new LinkedList<int[]>(); public OcrOperate(File file,String tempath){ this.file = file; this.tempath = tempath; this.tesspath = "d:\\application\\Tesseract-OCR\\"; for(int i=0;i<4;i++){//自行设置图片位置(需要自己测试调整,要保证所有图片大小一直) this.list.add(new int[]{230,950+i*130,1800,120}); } } @Override public void run() { try { if(list.size()>0){ recognizeText(cutImage(file,list.removeFirst())); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public Map<String, String> getResult(){ return result; } /** * 截取图片获取有效数据-----提高解析速率 * @param file * @return * @throws IOException */ private File cutImage(File file,int[] arr)throws IOException { FileInputStream is = null ; ImageInputStream iis = null ; Rectangle rect = null; File outFile = null; try { ImageReader reader = ImageIO.getImageReadersByFormatName(TYPE_JPG).next(); is = new FileInputStream(file); iis = ImageIO.createImageInputStream(is); reader.setInput(iis, true ) ; ImageReadParam param = reader.getDefaultReadParam(); rect = new Rectangle(arr[0],arr[1],arr[2],arr[3]); param.setSourceRegion(rect); BufferedImage bi=reader.read(0,param); outFile = new File(tempath+File.separator+UUID.randomUUID()+".jpg"); ImageIO.write(bi,TYPE_JPG,outFile); } finally{ if (is != null ) is.close() ; if (iis != null ) iis.close(); //file.delete(); } return outFile; } /** * 调用OCR引擎解析图片 * @param file * @return * @throws TxnErrorException * @throws IOException */ private void recognizeText(File file) throws IOException{ Process process = null; BufferedReader br = null; //设置输出文件的保存的文件目录 File outfile = new File(tempath,UUID.randomUUID()+""); List<String> cmd = new ArrayList<String>(); if (OS.isWindowsXP()){ cmd.add(tesspath + "\\tesseract"); } else if (OS.isLinux()){ cmd.add(tesspath+File.separator+"tesseract"); } else{ cmd.add(tesspath + "\\tesseract"); } cmd.add(""); cmd.add(outfile.getName()); cmd.add("-l"); cmd.add("CHI_SIM"); // cmd.add("ENG"); try { ProcessBuilder pb = new ProcessBuilder(); //设置线程的工作路径 pb.directory(file.getParentFile()); cmd.set(1, file.getName()); pb.command(cmd); pb.redirectErrorStream(true); process = pb.start(); //Runtime.getRuntime().exec("D:\\application\\Tesseract-OCR\\tesseract d:\\testdata\\002.jpg d:\\testdata\\output -l chi_sim"); System.out.println("=========>cmd:"+cmd.toString()); //设置一个解析时间阈值,超过该值解析停止 int i = 120; outfile = new File(outfile.getAbsoluteFile()+".txt"); while(!(outfile.exists()) && i-->0){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } if (outfile.exists()){ br = new BufferedReader(new InputStreamReader( new FileInputStream(outfile), "UTF-8")); String str = null; while ((str = br.readLine()) != null){ str = str.replaceAll("\\s*\\p{Punct}*", "");//去掉空白符号和标点符号 System.out.println("=======>str:"+str); if(str.contains("问题一")){//根据结果集自行调整 截取位置 result.put("question1", str.substring(7,str.indexOf("发文序号"))); result.put("question11", str.substring(str.indexOf("发文序号")+4)); }else if(str.contains("问题二")){ result.put("question2", str.substring(8)); }else if(str.contains("问题三")){ result.put("question3", str.substring(6)); }else if(str.contains("问题四")){ result.put("question4", str); } } } else{ throw new RuntimeException("OCR异常-解析超时,未识别出文本文件"); } } finally { if(process!=null){ process.destroy(); } if(br!=null){ try { br.close(); } catch (IOException e) { e.printStackTrace(); } } //file.delete(); //outfile.delete(); //清空临时文件数据 /*for(File file2 : new File(tempath).listFiles()){ file2.delete(); }*/ } }}
OcrEngine.java是主方法,包括图片的转换和线程的起掉,OcrOperate.java实现图片的切割和ocr解析图片。感觉还是很弱智,后面再改善,另外ocr的解析时间是变短了,但是pdf转jpg的时间还是很长,这个主要是转的时候要求的分辨率太高了,可以自行调整,或者寻找另一种效率更快兼容性更好的扩展jar包来转换pdf。
阅读全文
1 0
- java程序集成Tesseract-OCR识别图片信息
- tesseract-ocr图片识别
- java 调用tesseract-ocr识别图片
- Android集成Tesseract OCR实现图片文字识别
- Tesseract-ocr-图片文字识别
- java 利用Tesseract-OCR识别图片验证码
- Java OCR tesseract 图片识别技术(一)
- Java OCR tesseract 图片识别技术(二)
- tesseract-ocr 识别中文扫描图片
- tesseract-ocr 识别图片中的数字
- tesseract-ocr 实现图片识别功能
- 使用Tesseract OCR Engine识别图片文字
- tesseract-ocr 实现图片识别功能
- tesseract-ocr 实现图片识别功能
- tesseract-OCR识别图片中的数字
- Tesseract-OCR识别图片验证码
- tesseract-ocr 实现图片识别功能
- Java中文图像识别tesseract-ocr || tif
- JAVA基础知识总结
- 距离度量以及python实现(一)
- 笔试题:geohash编码
- Harry Potter and the Hide Story HDU
- 又一国庆放假前的下午
- java程序集成Tesseract-OCR识别图片信息
- Navicat/MySQL Front 操作 MySQL 1577 报错 解决方法
- C语言 java 斐波那契数列
- shell递归遍历某路径下所有的文件
- 子窗口(child window)应用实战
- MongoDB 与 SQL 语句映射关系(持续更新中)
- 时间管理办法,如何对项目进行规划提高效率?
- 无法进行网络认证问题
- AndroidStudio实用技巧总结