【图片识别】java 图片文字识别 ocr (转)
http://www.cnblogs.com/inkflower/p/6642264.html
最近在開發的時候需要識別圖片中的一些文字,網上找了相關資料之后,發現google有一個離線的工具,以下為java使用的demo
在此之前,使用這個工具需要在本地安裝OCR工具:
下面一個是一定要安裝的離線包,建議默認安裝
上面一個是中文的語言包,如果網絡可以FQ的童鞋可以在安裝的時候就選擇語言包在線安裝,有多種語言可供選擇,默認只有英文的
exe安裝好之后,把上面一個文件拷到安裝目錄下tessdata文件夾下
如C:\Program Files (x86)\Tesseract-OCR\tessdata下
然后下面兩個是可選包,如果圖片不做臨時文件處理的話,可以不需要帶的
首先是一個臨時文件生成用的類以防源文件損壞,參考某位博友的例子@Gunner
?
package org.ink.image.textrz;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;/*** user set locale Construct* @param locale*/public ImageIOHelper(Locale locale){this.locale=locale;}/*** default construct using default locale Locale.CHINESE*/public ImageIOHelper(){}/*** create tempFile of Image in order to prevent damaging original file* @param imageFile* @param imageFormat like png,jps .etc* @return TempFile of Image* @throws IOException*/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(); TIFFImageWriteParam tiffWriteParam = new TIFFImageWriteParam(Locale.CHINESE); tiffWriteParam.setCompressionMode(ImageWriteParam.MODE_DISABLED); 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; } /*** add suffix to tempfile* @param imageFile* @return* @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()); } }下面是真正識別的內容:
package org.ink.image.textrz;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; /*** TEXT Recognize Utils* @author ink.Flower**/ public class OCRUtil { private final String LANG_OPTION = "-l"; //英文字母小寫l,并非數字1 private final String EOL = System.getProperty("line.separator"); private String tessPath = "C://Program Files (x86)//Tesseract-OCR";//ocr默認安裝路徑private String transname="chi_sim";//默認中文語言包,識別中文/*** Construct method of OCR ,set Tesseract-OCR install path* @param tessPath Tesseract-OCR install path* @param transFileName traningFile name like eng.traineddata*/public OCRUtil(String tessPath,String transFileName){this.tessPath=tessPath;this.transname=transFileName;}/*** Construct method of OCR,default path is "C://Program Files (x86)//Tesseract-OCR"*/public OCRUtil(){ }public String getTessPath() {return tessPath;}public void setTessPath(String tessPath) {this.tessPath = tessPath;}public String getTransname() {return transname;}public void setTransname(String transname) {this.transname = transname;}public String getLANG_OPTION() {return LANG_OPTION;}public String getEOL() {return EOL;}/*** recognize text in image* @param imageFile* @param imageFormat* @return text recognized in image* @throws Exception*/public String recognizeText(File imageFile,String imageFormat)throws Exception{ File tempImage = new ImageIOHelper().createImage(imageFile,imageFormat); return ocrImages(tempImage, imageFile); } /*** recognize text in image* @param imageFile* @param imageFormat* @param locale* @return text recognized in image* @throws Exception*/public String recognizeText(File imageFile,String imageFormat,Locale locale)throws Exception{ File tempImage = new ImageIOHelper(locale).createImage(imageFile,imageFormat);return ocrImages(tempImage, imageFile);}/*** * @param tempImage* @param imageFile* @return* @throws IOException* @throws InterruptedException*/private String ocrImages(File tempImage,File imageFile) throws IOException, InterruptedException{File outputFile = new File(imageFile.getParentFile(),"output");Runtime.getRuntime().exec("attrib "+"\""+outputFile.getAbsolutePath()+"\""+" +H"); //設置文件隱藏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(transname); ProcessBuilder pb = new ProcessBuilder(); pb.directory(imageFile.getParentFile()); cmd.set(1, tempImage.getName()); pb.command(cmd); pb.redirectErrorStream(true); Process process = pb.start(); int w = process.waitFor(); tempImage.delete();//刪除臨時正在工作文件 if(w==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(); }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(); } }在實驗中發現,如果對有多個文字的大圖進行直接識別的話,效果可能比較差,所以可以參考另一篇切圖的博文,將圖片取一塊之后再識別
http://www.cnblogs.com/inkflower/p/6642089.html???? ←我是鏈接
這樣成功率會提高很多。
以上為離線識別版本,效率因圖而已,具體使用的時候可以總結分析
另外,博主也在網上看到百度也有圖片文字識別的工具
百度OCR企業版
以上這個貌似是付費的,如果要免費的可以網上找找,另外API也可以找找
總結
以上是生活随笔為你收集整理的【图片识别】java 图片文字识别 ocr (转)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 解读我所认知的网络营销根源
- 下一篇: 轻量级的Ajax解决方案——DynAja