Java OCR tesseract 图像智能字符识别技术 Java代码实现

接着上一篇OCR所说的,上一篇给大家介绍了tesseract 在命令行的简单用法,当然了要继承到我们的程序中,还是需要代码实现的,下面给大家分享下java实现的例子。

拿代码扫描上面的图片,然后输出结果。主要思想就是利用Java调用系统任务。

下面是核心代码:

/**
*
*/
package cn.jorcen.dropins.tesseract; import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.LinkedList;
import java.util.List; import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger; /**
*
*
* @author mjorcen
* @email mjorcen@gmail.com
* @dateTime Jun 19, 2014 3:42:16 PM
* @version 1
*/
public class TesseractOCRUtil {
static Logger logger = Logger.getLogger(TesseractOCRUtil.class);
static String path = "E:/data/Users/Administrator/Desktop/ocr/spelling"; public static void main(String[] args) throws Exception { File file = new File(path);
String[] strs = file.list();
for (String string : strs) {
File iFile = new File(path, string);
if (iFile.isFile()) {
parseImage(new File(file.getAbsolutePath(), string), new File(
path + "/tmp", iFile.getName()));
}
}
System.exit(); } public static String parseImage(File file, File targetFile)
throws Exception { ClearImageUtil.cleanImage(file, targetFile);
return parseImageOnNoClear(targetFile);
} public static String parseImageOnNoClear(File file) throws Exception {
try {
logger.debug("image is " + file.getAbsolutePath()); // ClearImageHelper.cleanImage(file, filename);
// 构造命令
// List<String> cmd = new LinkedList<String>();
// cmd.add("tesseract");
// cmd.add(file.getAbsolutePath());
// cmd.add(file.getAbsolutePath());
// cmd.add(" ");
// cmd.add("-l");
// cmd.add(" ");
// cmd.add("normal");
// logger.debug(cmd);
// System.out.println(cmd);
// ProcessBuilder pb = new ProcessBuilder(cmd);
// pb.redirectErrorStream(true);
// pb.directory(new File(path));
// Process p = pb.start();
Runtime run = Runtime.getRuntime();
Process p = run.exec("cmd.exe /c tesseract "
+ file.getAbsolutePath() + " " + file.getAbsolutePath()
+ " -l normal"); getConsole(p);
String sb = getResult(new File(file.getAbsolutePath() + ".txt"));
return sb.toString();
} catch (Exception e) {
logger.error(e);
return null;
} finally {
}
} private static String getResult(File file) throws FileNotFoundException,
UnsupportedEncodingException, IOException { StringBuilder sb = new StringBuilder();
// 取得结果的输出流
InputStream resultIs = new FileInputStream(file);
// 用一个读输出流类去读
InputStreamReader resultIsr = new InputStreamReader(resultIs, "utf-8");
// 用缓冲器读行
BufferedReader resultBr = new BufferedReader(resultIsr);
String line;
// 直到读完为止
while ((line = resultBr.readLine()) != null) {
logger.debug(line);
sb.append(line);
}
return sb.toString();
} private static void getConsole(Process p)
throws UnsupportedEncodingException, IOException {
// 取得命令结果的输出流
InputStream fis = p.getInputStream();
// 用一个读输出流类去读
InputStreamReader isr = new InputStreamReader(fis, "utf-8");
// 用缓冲器读行
BufferedReader br = new BufferedReader(isr);
String line = null;
// 直到读完为止
while ((line = br.readLine()) != null) {
// System.out.println(line);
}
} public static void test() {
try {
List<String> cmd = new LinkedList<String>();
cmd.add("javac");
cmd.add("PB.java");
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectErrorStream(true);
pb.directory(new File("E:/test"));
Process p = pb.start(); // 取得命令结果的输出流
InputStream fis = p.getInputStream();
// 用一个读输出流类去读
InputStreamReader isr = new InputStreamReader(fis, "utf-8");
// 用缓冲器读行
BufferedReader br = new BufferedReader(isr);
String line = null;
// 直到读完为止
while ((line = br.readLine()) != null) {
logger.debug(line);
}
} catch (Exception e) {
logger.error(e); }
}
}

结果如下:

uHx7,IXQO,\1ZYP,ZVBO,3237,5SYQ~,,87YF,\8KDN,CGPC,\c\IG\N,F\Z TA,J 9pc,Lpza,NBGC,N QW8,onwz,ox XJ,\P9FM,P PR鈥楿,QRG\I\,,RAZ v\,504i,VGPH,VPCI,\\I\M I,鈥楳J1,Y6H9\,Y OGP,

对比第一张图片, 不是很完美~哈哈 ,当然了如果你只需要实现验证码的读写,那么上面就足够了。下面继续普及图像处理的知识。

-------------------------------------------------------------------我的分割线--------------------------------------------------------------------

当然了,有时候图片被扭曲或者模糊的很厉害,很不容易识别,所以下面我给大家介绍一个去噪的辅助类, 能稍做优化,先看下效果图。

package cn.c.test3;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException; import javax.imageio.ImageIO; public class ClearImageHelper { public static void main(String[] args) throws IOException { File testDataDir = new File("E:\\test\\code");
final String destDir = testDataDir.getAbsolutePath() + "/tmp";
for (File file : testDataDir.listFiles()) {
cleanImage(file, destDir);
} } /**
*
* @param sfile
* 需要去噪的图像
* @param destDir
* 去噪后的图像保存地址
* @throws IOException
*/
public static void cleanImage(File sfile, String destDir)
throws IOException {
File destF = new File(destDir);
if (!destF.exists()) {
destF.mkdirs();
} BufferedImage bufferedImage = ImageIO.read(sfile);
int h = bufferedImage.getHeight();
int w = bufferedImage.getWidth(); // 灰度化
int[][] gray = new int[w][h];
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
int argb = bufferedImage.getRGB(x, y);
// 图像加亮(调整亮度识别率非常高)
int r = (int) (((argb >> 16) & 0xFF) * 1.1 + 30);
int g = (int) (((argb >> 8) & 0xFF) * 1.1 + 30);
int b = (int) (((argb >> 0) & 0xFF) * 1.1 + 30);
if (r >= 255) {
r = 255;
}
if (g >= 255) {
g = 255;
}
if (b >= 255) {
b = 255;
}
gray[x][y] = (int) Math
.pow((Math.pow(r, 2.2) * 0.2973 + Math.pow(g, 2.2)
* 0.6274 + Math.pow(b, 2.2) * 0.0753), 1 / 2.2);
}
} // 二值化
int threshold = ostu(gray, w, h);
BufferedImage binaryBufferedImage = new BufferedImage(w, h,
BufferedImage.TYPE_BYTE_BINARY);
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
if (gray[x][y] > threshold) {
gray[x][y] |= 0x00FFFF;
} else {
gray[x][y] &= 0xFF0000;
}
binaryBufferedImage.setRGB(x, y, gray[x][y]);
}
} // 矩阵打印
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
if (isBlack(binaryBufferedImage.getRGB(x, y))) {
System.out.print("*");
} else {
System.out.print(" ");
}
}
System.out.println();
} ImageIO.write(binaryBufferedImage, "jpg",
new File(destDir, sfile.getName()));
} public static boolean isBlack(int colorInt) {
Color color = new Color(colorInt);
if (color.getRed() + color.getGreen() + color.getBlue() <= 300) {
return true;
}
return false;
} public static boolean isWhite(int colorInt) {
Color color = new Color(colorInt);
if (color.getRed() + color.getGreen() + color.getBlue() > 300) {
return true;
}
return false;
} public static int isBlackOrWhite(int colorInt) {
if (getColorBright(colorInt) < 30 || getColorBright(colorInt) > 730) {
return 1;
}
return 0;
} public static int getColorBright(int colorInt) {
Color color = new Color(colorInt);
return color.getRed() + color.getGreen() + color.getBlue();
} public static int ostu(int[][] gray, int w, int h) {
int[] histData = new int[w * h];
// Calculate histogram
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
int red = 0xFF & gray[x][y];
histData[red]++;
}
} // Total number of pixels
int total = w * h; float sum = 0;
for (int t = 0; t < 256; t++)
sum += t * histData[t]; float sumB = 0;
int wB = 0;
int wF = 0; float varMax = 0;
int threshold = 0; for (int t = 0; t < 256; t++) {
wB += histData[t]; // Weight Background
if (wB == 0)
continue; wF = total - wB; // Weight Foreground
if (wF == 0)
break; sumB += (float) (t * histData[t]); float mB = sumB / wB; // Mean Background
float mF = (sum - sumB) / wF; // Mean Foreground // Calculate Between Class Variance
float varBetween = (float) wB * (float) wF * (mB - mF) * (mB - mF); // Check if new maximum found
if (varBetween > varMax) {
varMax = varBetween;
threshold = t;
}
} return threshold;
}
}

Java OCR tesseract 图像智能字符识别技术 Java实现的更多相关文章

  1. Java OCR tesseract 图像智能字符识别技术 Java代码实现

    接着上一篇OCR所说的,上一篇给大家介绍了tesseract 在命令行的简单用法,当然了要继承到我们的程序中,还是需要代码实现的,下面给大家分享下java实现的例子. 拿代码扫描上面的图片,然后输出结 ...

  2. Java OCR tesseract 图像智能字符识别技术

    公司有需求啊,所以就得研究哈,最近公司需要读验证码,于是就研究起了图像识别,应该就是传说中的(OCR:光学字符识别OCR),下面把今天的收获整理一个给大家做个分享. 本人程序用的tesseract,官 ...

  3. java整理软件--- Java OCR 图像智能字符识别技术,可识别中文,但是验证码不可以识别...已测识别中文效果很好

    国内最专业的OCR软件只有2家,清华TH-OCR和汉王OCR,看了很多的OCR技术 发现好多对英文与数字的支持都很好,可惜很多都不支持中文字符.Asprise-OCR,Tesseract 3.0以前的 ...

  4. Java OCR 图像智能字符识别技术,可识别中文

    http://www.open-open.com/lib/view/open1363156299203.html

  5. 【OCR系列之一】字符识别技术总览

    最近入坑研究OCR,看了比较多关于OCR的资料,对OCR的前世今生也有了一个比较清晰的了解.所以想写一篇关于OCR技术的综述,对OCR相关的知识点都好好总结一遍,以加深个人理解. 什么是OCR? OC ...

  6. 【OCR技术系列之一】字符识别技术总览

    最近入坑研究OCR,看了比较多关于OCR的资料,对OCR的前世今生也有了一个比较清晰的了解.所以想写一篇关于OCR技术的综述,对OCR相关的知识点都好好总结一遍,以加深个人理解. 什么是OCR? OC ...

  7. JAVA OCR图片识别

    今天闲来无聊,尝试了一下OCR识别,尝试了以下三种方案: 1.直接使用业界使用最广泛的Tesseract-OCR. Tesseract项目最初由惠普实验室支持,1996年被移植到Windows上,19 ...

  8. 【OCR技术系列一】光学字符识别技术介绍

    注:此篇内容主要是综合整理了光学字符识别 和OCR技术系列之一]字符识别技术总览,详情见文末参考文献 什么是 OCR? OCR(Optical Character Recognition,光学字符识别 ...

  9. Java中导入导出Excel -- POI技术

    一.介绍: 当前B/S模式已成为应用开发的主流,而在企业办公系统中,常常有客户这样子要求:你要把我们的报表直接用Excel打开(电信系统.银行系统).或者是:我们已经习惯用Excel打印.这样在我们实 ...

随机推荐

  1. centos find

    首先你要确定你的软件是什么方式安装?如果不确定,你可知道你的软件名字,用find查找一下在哪个目录find / -name softname

  2. 去除ActionBar的方法

    今天做一个播放器项目,由于要去除ActionBar,纠结好久,原来这么简单 记录一下 只需要修改AndroidManifest.xml文件中的主题即可 <application android: ...

  3. (原创)鸟哥linux学习script shell相关笔记

    在使用鸟哥linux进行script shell学习的过程中碰到一些不太明白的知识点,在这里进行一些记录 1. [root@www scripts]# vi sh03.sh #!/bin/bash # ...

  4. JAXB - Hello World

    We'll stick with the tradition and use a sort of "Hello World" XML document to illustrate ...

  5. 【JQuery基础教程(第三版)图灵】笔记

    第1章 jQuery入门 1.jQuery官方网站:http://jquery.com   2.开发工具:Firebug         第2章 选择元素 1.属性选择符:属性选择符通过HTML元素的 ...

  6. HashMap使用

    /* * 测试HashMap的应用,判断 */ import java.util.HashMap; public class HuaWeiTest { private static final Int ...

  7. ###C中的extern-static-const关键词

    #@date: 2014-06-14 #@author: gerui #@email: forgerui@gmail.com Contents extern的作用一般是用来声音一个外部变量和函数.一般 ...

  8. StrHelper

    public class StrHelper { private static string passWord; //加密字符串 /// <summary> /// 判断输入是否数字 // ...

  9. JavaScript中的apply与call与arguments对象

    (一) call方法 语法:presentObj.call(thisObj,arg1,arg2,arg3...) 参数thisObj :将被用作当前对象presentObj的对象. 当thisObj无 ...

  10. TextView实现跑马灯效果

    网上有很多跑马灯的介绍,有很多跑马灯的代码.或许我的不是最好的,但是应该很容易明白的. 我们先来介绍一个跑马灯的代码 <LinearLayout xmlns:android="http ...