【Java程序】tesseract_orc java上的一种实现方法
今天想着把以前做过的一个Android的文字检测识别应用好好的回顾一下,因为以前写java程序,目的就是能用就行,不会仔细看每一个部分代码,也不会记他们的用法,不回会去查API,借鉴别人的例程,用过就忘了,现在想着要改变,于是就回顾了一番。
之前检测用到的是Tesseract_OCR,之所以能在Android的上运行,是因为黑暗伯爵大神已经把tess-two(为android写的tesseract-tools)编译好了,然后我直接用的。我还是小白,完全不懂编译那些,如果让我自己搞.... 反正最后编译成so文件(这个是linux平台下的动态链接库,可以类比dll),然后我用编译好的so文件,以及jar包导入到工程,照葫芦画瓢把文字识别部分和自己之前看论文写的文字检测部分合到一起,然后百度了怎么调用摄像头,然后写了一个摄像头拍照,然后检测文字所在区域,处理,然后识别的应用。以后有时间会详细的重新把应用梳理一遍,然后记录,当然这不是今天的重点。如果对Android上如何做OCR感兴趣,可以参考 这里 。
回到正题,前几天同学问我以前做的文字识别是咋搞得,他想用用,我于是就想把程序移回来到java上,结果我百度才发现原来还有另外一种思路,那就是执行exe进程。先在pc上安装好tesseract_orc,然后jvm运行命令行跑识别程序,完成识别后结果写入txt,最后读取txt把内容返回到java程序中。这么想想也行,于是便试了试。(PS:我是后来才发现也有Java的API tess4j,参考 这里)
然后就是讲自己具体怎么实现:
工程也就两部分,一部分是GUI,反正我现在对于Java的基础知识薄弱,然后常用类也用的不多,所以借此机会正好熟悉。
GUI主要用到javax.swing包和java.awt包,swing主要写组件,awt是事件(其实awt也可以写组件),但是说swing是对awt中组建的优化,所以现在常用swing。GUI里面比较重要的概念还是容器,组件必须放到容器里面才能显示,常用frame和dialog。我这次写GUI用到jframe,jbutton,filedialog,JLabel,imageicon这几个类
界面如下
- 其中的按钮用的JButton:"push" 按钮的实现,可以设置监听器。
- 按钮设置了监听器,“打开图片”弹出Filedoalog,选择图片文件,“识别”新建文字识别类,进行识别返回结果:
FileDialog
类显示一个对话框窗口,用户可以从中选择文件。 - 图片显示和文字显示用的JLabel:
JLabel
对象可以显示文本、图像或同时显示二者。可以通过设置垂直和水平对齐方式,指定标签显示区中标签内容在何处对齐。默认情况下,标签在其显示区内垂直居中对齐。默认情况下,只显示文本的标签是开始边对齐;而只显示图像的标签则水平居中对齐。 - Jframe建立整个容器
- Imageicon用来加载图像。Imageicon:一个 Icon 接口的实现,它根据 Image 绘制 Icon。可使用 MediaTracker 预载根据 URL、文件名或字节数组创建的图像,以监视该图像的加载状态。
界面的具体代码我就不贴上来了,值得注意的是图片压缩显示有一个小trick。
imagePath = new String(dirPath+fileName);
imageico = new ImageIcon(imagePath);
int w = imageico.getIconWidth();
int h = imageico.getIconHeight();
double ratio = (double)w/(double)h;
if(ratio>4/3){
h = (int)(640*h/w);
w = 640;
}else{
w = (int)(480*w/h);
h = 480;
}
imageico.setImage(imageico.getImage().getScaledInstance(w,h,imageico.getImage().SCALE_DEFAULT));
另外,就是文字识别的部分,主要还是一个执行进程的过程,那么首先得下载安装Tesseract_OCR:
安装下载的工作参考 这里
那么这边主要的挑战就是使用java执行进程和做文件io,主要分一下几点:
1.java操作命令行主要用到processbuilder & process 类,出自java.lang
一般都是ProcessBuilder.start() 和 Runtime.exec(ArrayList<String>) 方法创建一个本机进程,并返回 Process 子类的一个实例,该实例可用来控制进程并获得相关信息。Process 类提供了执行从进程输入、执行输出到进程、等待进程完成、检查进程的退出状态以及销毁(杀掉)进程的方法。
Runtime.getRuntime.exec(ArrayList<String> cmd)
processbuilder pb; pb.command(ArrayList<String> cmd);
这里就是用的processbuilder pb,新建一个实例,并且把运行参数保存到字符串表单cmd里,然后pb.command(ArrayList<String> cmd)执行,结果保存到指定txt中;
2.表示文件的类file类 出自java.io
它是文件和目录路径名的抽象表示形式。
主要方法getName(),getPath(),getParentPath();
在执行命令行时,表示输入的图片,表示输出txt都可以用到file类。
3.读取字节流过程 出自java.io
FileInputStream 从文件系统中的某个文件中获得输入字节。哪些文件可用取决于主机环境,这里可以读取图片。
new FileInputStream(outputFile.getAbsolutePath()) 新建一个文件输入字节流
new InputStreamReader(new FileInputStream(outputFile.getAbsolutePath()),"UTF-8")。文件输入字节流变成文件输入字符流
BufferedReader从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
主要是两种用法还可以这么使用
BufferedReader in = new BufferedReader(new FileReader("foo.in"));
或者
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream("foo.in"),"UTF-8"));
前者不能指定编码,而后者可以。
在最后把txt中文本读取到java程序,进而显示在GUI中用到
识别的代码如下
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List; public class textRecognizer{ private String textResult;
/**
* 输出的结果
*/
private final String EOL = System.getProperty("line.separator");
//回车
private String tessPath = "D:\\Tesseract-OCR";
//tessocr程序所在目录
public textRecognizer(String path)
{
try
{
File imagefile = new File(path);
textResult = this.recognizeText(imagefile);
} catch (Exception e)
{
e.printStackTrace();
}
} public String getResult(){
return textResult;
} private String recognizeText(File imageFile) throws Exception
{
/**
* 设置输出文件的保存的文件目录
*/
File outputFile = new File(imageFile.getParentFile(),"output");
StringBuffer strB = new StringBuffer(); //设置cmd命令行字符串形式
List<String> cmd = new ArrayList<String>();
cmd.add(tessPath + "\\tesseract");
cmd.add(imageFile.getName());
cmd.add(outputFile.getName());
cmd.add("-l");
cmd.add("eng"); //启动exe进程
ProcessBuilder pb = new ProcessBuilder();
pb.directory(imageFile.getParentFile());
pb.command(cmd);
pb.redirectErrorStream(true);
Process process = pb.start();
//等待此进程完成
int w = process.waitFor();
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();
} 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 recognize the image or its selected region.";
break;
case 31:
msg = "Unsupported image format.";
break;
default:
msg = "Errors occurred.";
}
throw new RuntimeException(msg);
}
new File(outputFile.getAbsolutePath()+ ".txt").delete();
/**
* 如果做验证码
* return strB.toString().replaceAll("\\s*", "");
*/
return strB.toString();
}
}
可惜的是最后检测的结果一般。
今天写程序期间还有其他的有意思的地方我也有记录。
- java foreach 遍历,for(File file :testDataDir.listFiles()),jdk1.6后支持。
- private final String EOL = System.getProperty("line.separator"); 回车换行的字符串表示
【Java程序】tesseract_orc java上的一种实现方法的更多相关文章
- 我的第一个Java程序和Java简介
public calss HelloWorld{ public static void main(String[] args){ System.out.println("Hello Worl ...
- 执行Asp.net应用程序在Linux上的3种托管方式
执行Asp.net应用程序在Linux上的3种托管方式 想要执行Asp.net应用程序在Linux上.我们有3种选择: 1.使用Apache作为Webserver.使用mod_mono:http:// ...
- Java 微信公众号上传永久素材的方法
Java 微信公众号上传永久素材的方法 学习了:http://blog.csdn.net/u013791374/article/details/53258275 膜拜一下,源码如下: @Request ...
- redis(Springboot中封装整合redis,java程序如何操作redis的5种基本数据类型)
平常测试redis操作命令,可能用的是cmd窗口 操作redis,记录一下 java程序操作reids, 操作redis的方法 可以用Jedis ,在springboot 提供了两种 方法操作 Red ...
- 将Java程序作成exe文件的几种方法【转载】
看到网上有同志的介绍将Java程序作成exe文件的方法,写的不错,但是也许是这篇文章完成的时间比较早,许多内容已经不合适了.我在这里补充几条: 一.exe4j 说明:exe4j可以将Jar文件制作成e ...
- java 程序从linux 上接收不可见字符
近期在写一个简单的小java程序,希望在运行java 程序时,从shell 中接收参数,并且参数的内容为不可见字符. 开始时还觉得可以使用"\"之类的转义符来写,后来发现java程 ...
- java程序在一个电脑上只启动一次,只开一个进程
方案1: 单进程程序可以用端口绑定.程序启动的时候可以尝试看该端口是否已经被占用,如果占用则程序已经启动. 方案2:你可以在java程序中创建一个隐藏文件,程序退出的时候删除这个文件.这样在程序启动的 ...
- 第一个java程序以及java的运行机制
课堂要点: 编写第一个java程序以及理解java的运行机制. 1.基本命令介绍: javac命令: 编译java文件得到.class字节码文件 -encoding 参数:指定编译的编码 java命令 ...
- Java程序在Linux上运行虚拟内存耗用很大
突然集群的2个节点挂了,通过top查看, 虚拟内存22G, 通过 pmap -x 8 | grep anon 一大堆64M Linux下glibc的内存管理机制用了一个很奇妙的东西,叫arena.在g ...
随机推荐
- Tab选项卡 自动切换效果js实现
try.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> < ...
- FreeBSD虚拟机——小折腾
最近,突然想起来Linux了,因为前段时间接触了DOS命令,提高了自己的工作效率,这会想再温习下Linux的CLI,无奈windows下unix命令,水土不服,因此想尝试虚拟机,虚拟机软件无非vmwa ...
- Codeforces 499C:Crazy Town(计算几何)
题目链接 给出点A(x1,y1),B(x2,y2),和n条直线(ai,bi,ci,aix + biy + ci = 0),求A到B穿过多少条直线 枚举每条直线判断A.B是否在该直线两侧即可 #incl ...
- vscode workspace 地址重置
换了新电脑,做了vscode的迁移,workspace的物理地址换了,一直找不到修 正的地方 可以直接用文本编辑器打开 SourceDevelop.code-workspace类似这个workspac ...
- Pasha and Tea
Pasha and Tea time limit per test 1 second memory limit per test 256 megabytes input standard input ...
- 01 【零基础入门】html学习笔记(1)
之前学习了前端的一些基础知识,现在想深入地.精通地学习前端,往前端和全栈工程师方向发展. 之前学习前端主要是通过看视频,结合动手练习.现在认为看书+视频+实践,应该是最高效的学习方法.对于html.c ...
- (转)超详细java中的ClassLoader详解
转:https://blog.csdn.net/briblue/article/details/54973413 ClassLoader翻译过来就是类加载器,普通的java开发者其实用到的不多,但对于 ...
- 四两拨千斤,ARM是如何运作、靠什么赚钱的
在智能手机.平板大行其道的今天,ARM这个名字我们几乎每天都要见到或者听到几次,作为编辑的我更是如此,每天涉及到的新闻总是或多或少跟ARM扯上关系,它还与Intel.AMD.NVIDA等公司有说不清道 ...
- QString的arg方法
第一个参数是要填充的数字,第二个参数为最小宽度,第三个参数为进制,第四个参数为当原始数字长度不足最小宽度时用于填充的字符,如 QString name=QString("R%1C%2&quo ...
- webpack 中vue文件使用scss需要注意的地方
需要使用npm添加node_sass和sass_loader 并且在配置文件中添加规则: { test: /\.scss$/, use: ["style-loader", &quo ...