java實現(xiàn)圖片文字識別ocr
最近在開發(fā)的時候需要識別圖片中的一些文字,網(wǎng)上找了相關資料之后,發(fā)現(xiàn)google有一個離線的工具,以下為java使用的demo
在此之前,使用這個工具需要在本地安裝OCR工具:

下面一個是一定要安裝的離線包,建議默認安裝
上面一個是中文的語言包,如果網(wǎng)絡可以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());
}
}
下面是真正識別的內(nèi)容:
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,并非數(shù)字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+"http://tesseract");
}else if(OS.isLinux()){
cmd.add("tesseract");
}else{
cmd.add(tessPath+"http://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();
}
}
在實驗中發(fā)現(xiàn),如果對有多個文字的大圖進行直接識別的話,效果可能比較差,所以可以參考另一篇切圖的博文,將圖片取一塊之后再識別
http://www.dbjr.com.cn/article/121231.htm ←我是鏈接
這樣成功率會提高很多。
以上為離線識別版本,效率因圖而已,具體使用的時候可以總結分析,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Spring Boot @Async 異步任務執(zhí)行方法
本篇文章主要介紹了Spring Boot @Async 異步任務執(zhí)行方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-05-05
Springboot 整合 Java DL4J 實現(xiàn)農(nóng)產(chǎn)品質(zhì)量檢測系統(tǒng)(推薦)
本文詳細介紹了系統(tǒng)的搭建過程,包括技術選型、數(shù)據(jù)處理、模型訓練和評估等關鍵步驟,系統(tǒng)采用卷積神經(jīng)網(wǎng)絡,對水果成熟度和缺陷進行識別,有效解決了傳統(tǒng)方法成本高、效率低的問題,有助于提升農(nóng)產(chǎn)品檢測的科技含量和自動化水平2024-10-10
詳解Spring-Boot集成Spring session并存入redis
這篇文章主要介紹了詳解Spring-Boot集成Spring session并存入redis,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-05-05
詳解SpringBoot通過restTemplate實現(xiàn)消費服務
本篇文章主要介紹了詳解使用RestTemplate消費spring boot的Restful服務,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-01-01
JDK9的新特性之String壓縮和字符編碼的實現(xiàn)方法
這篇文章主要介紹了JDK9的新特性之String壓縮和字符編碼的實現(xiàn)方法,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05

