文字识别能用(目前好用)

转载出处:http://blog.csdn.net/lidew521/article/details/8589132

国内最专业的OCR软件只有2家,清华TH-OCR和汉王OCR,看了很多的OCR技术发现好多对英文与数字的支持都很好,可惜很多都不支持中文字符。Asprise-OCR,Tesseract 3.0以前的版本,都不支持中文,其实我用了下Asprise-OCR算是速度比较的快了,可惜他鄙视中文,这个没有办法,正好这段时间知名的开源OCR引擎Tesseract 3.0版本发布了,他给我们带来的好消息就是支持中文,相关的下载项目网站是:http://code.google.com/p/tesseract-ocr

虽然速度不是很客观可是毕竟人家开始支持中文也算是不错的,一个英文的语言包大概是1.8M,中文简体的语言包是39.5M,中文繁体的语言包是53M,这样就知道为什么识别中文慢的原因了.

package com.ocr;

import java.awt.Graphics2D;

import java.awt.color.ColorSpace;

import java.awt.geom.AffineTransform;

import java.awt.image.AffineTransformOp;

import java.awt.image.BufferedImage;

import java.awt.image.ColorConvertOp;

import java.awt.image.ColorModel;

import java.awt.image.MemoryImageSource;

import java.awt.image.PixelGrabber;

/**

*

* 图像过滤,增强OCR识别成功率

*

*/

public class ImageFilter {

private BufferedImage image;

private int iw, ih;

private int[] pixels;

public ImageFilter(BufferedImage image) {

this.image = image;

iw = image.getWidth();

ih = image.getHeight();

pixels = new int[iw * ih];

}

/** 图像二值化 */

public BufferedImage changeGrey() {

PixelGrabber pg = new PixelGrabber(image.getSource(), 0, 0, iw, ih, pixels, 0, iw);

try {

pg.grabPixels();

} catch (InterruptedException e) {

e.printStackTrace();

}

// 设定二值化的域值,默认值为100

int grey = 100;

// 对图像进行二值化处理,Alpha值保持不变

ColorModel cm = ColorModel.getRGBdefault();

for (int i = 0; i < iw * ih; i++) {

int red, green, blue;

int alpha = cm.getAlpha(pixels[i]);

if (cm.getRed(pixels[i]) > grey) {

red = 255;

} else {

red = 0;

}

if (cm.getGreen(pixels[i]) > grey) {

green = 255;

} else {

green = 0;

}

if (cm.getBlue(pixels[i]) > grey) {

blue = 255;

} else {

blue = 0;

}

pixels[i] = alpha << 24 | red << 16 | green << 8 | blue;

}

// 将数组中的象素产生一个图像

return ImageIOHelper.imageProducerToBufferedImage(new MemoryImageSource(iw, ih, pixels, 0, iw));

}

/** 提升清晰度,进行锐化 */

public BufferedImage sharp() {

PixelGrabber pg = new PixelGrabber(image.getSource(), 0, 0, iw, ih, pixels, 0, iw);

try {

pg.grabPixels();

} catch (InterruptedException e) {

e.printStackTrace();

}

// 象素的中间变量

int tempPixels[] = new int[iw * ih];

for (int i = 0; i < iw * ih; i++) {

tempPixels[i] = pixels[i];

}

// 对图像进行尖锐化处理,Alpha值保持不变

ColorModel cm = ColorModel.getRGBdefault();

for (int i = 1; i < ih - 1; i++) {

for (int j = 1; j < iw - 1; j++) {

int alpha = cm.getAlpha(pixels[i * iw + j]);

// 对图像进行尖锐化

int red6 = cm.getRed(pixels[i * iw + j + 1]);

int red5 = cm.getRed(pixels[i * iw + j]);

int red8 = cm.getRed(pixels[(i + 1) * iw + j]);

int sharpRed = Math.abs(red6 - red5) + Math.abs(red8 - red5);

int green5 = cm.getGreen(pixels[i * iw + j]);

int green6 = cm.getGreen(pixels[i * iw + j + 1]);

int green8 = cm.getGreen(pixels[(i + 1) * iw + j]);

int sharpGreen = Math.abs(green6 - green5) + Math.abs(green8 - green5);

int blue5 = cm.getBlue(pixels[i * iw + j]);

int blue6 = cm.getBlue(pixels[i * iw + j + 1]);

int blue8 = cm.getBlue(pixels[(i + 1) * iw + j]);

int sharpBlue = Math.abs(blue6 - blue5) + Math.abs(blue8 - blue5);

if (sharpRed > 255) {

sharpRed = 255;

}

if (sharpGreen > 255) {

sharpGreen = 255;

}

if (sharpBlue > 255) {

sharpBlue = 255;

}

tempPixels[i * iw + j] = alpha << 24 | sharpRed << 16 | sharpGreen << 8 | sharpBlue;

}

}

// 将数组中的象素产生一个图像

return ImageIOHelper.imageProducerToBufferedImage(new MemoryImageSource(iw, ih, tempPixels, 0, iw));

}

/** 中值滤波 */

public BufferedImage median() {

PixelGrabber pg = new PixelGrabber(image.getSource(), 0, 0, iw, ih, pixels, 0, iw);

try {

pg.grabPixels();

} catch (InterruptedException e) {

e.printStackTrace();

}

// 对图像进行中值滤波,Alpha值保持不变

ColorModel cm = ColorModel.getRGBdefault();

for (int i = 1; i < ih - 1; i++) {

for (int j = 1; j < iw - 1; j++) {

int red, green, blue;

int alpha = cm.getAlpha(pixels[i * iw + j]);

// int red2 = cm.getRed(pixels[(i - 1) * iw + j]);

int red4 = cm.getRed(pixels[i * iw + j - 1]);

int red5 = cm.getRed(pixels[i * iw + j]);

int red6 = cm.getRed(pixels[i * iw + j + 1]);

// int red8 = cm.getRed(pixels[(i + 1) * iw + j]);

// 水平方向进行中值滤波

if (red4 >= red5) {

if (red5 >= red6) {

red = red5;

} else {

if (red4 >= red6) {

red = red6;

} else {

red = red4;

}

}

} else {

if (red4 > red6) {

red = red4;

} else {

if (red5 > red6) {

red = red6;

} else {

red = red5;

}

}

}

// int green2 = cm.getGreen(pixels[(i - 1) * iw + j]);

int green4 = cm.getGreen(pixels[i * iw + j - 1]);

int green5 = cm.getGreen(pixels[i * iw + j]);

int green6 = cm.getGreen(pixels[i * iw + j + 1]);

// int green8 = cm.getGreen(pixels[(i + 1) * iw + j]);

// 水平方向进行中值滤波

if (green4 >= green5) {

if (green5 >= green6) {

green = green5;

} else {

if (green4 >= green6) {

green = green6;

} else {

green = green4;

}

}

} else {

if (green4 > green6) {

green = green4;

} else {

if (green5 > green6) {

green = green6;

} else {

green = green5;

}

}

}

// int blue2 = cm.getBlue(pixels[(i - 1) * iw + j]);

int blue4 = cm.getBlue(pixels[i * iw + j - 1]);

int blue5 = cm.getBlue(pixels[i * iw + j]);

int blue6 = cm.getBlue(pixels[i * iw + j + 1]);

// int blue8 = cm.getBlue(pixels[(i + 1) * iw + j]);

// 水平方向进行中值滤波

if (blue4 >= blue5) {

if (blue5 >= blue6) {

blue = blue5;

} else {

if (blue4 >= blue6) {

blue = blue6;

} else {

blue = blue4;

}

}

} else {

if (blue4 > blue6) {

blue = blue4;

} else {

if (blue5 > blue6) {

blue = blue6;

} else {

blue = blue5;

}

}

}

pixels[i * iw + j] = alpha << 24 | red << 16 | green << 8 | blue;

}

}

// 将数组中的象素产生一个图像

return ImageIOHelper.imageProducerToBufferedImage(new MemoryImageSource(iw, ih, pixels, 0, iw));

}

/** 线性灰度变换 */

public BufferedImage lineGrey() {

PixelGrabber pg = new PixelGrabber(image.getSource(), 0, 0, iw, ih, pixels, 0, iw);

try {

pg.grabPixels();

} catch (InterruptedException e) {

e.printStackTrace();

}

// 对图像进行进行线性拉伸,Alpha值保持不变

ColorModel cm = ColorModel.getRGBdefault();

for (int i = 0; i < iw * ih; i++) {

int alpha = cm.getAlpha(pixels[i]);

int red = cm.getRed(pixels[i]);

int green = cm.getGreen(pixels[i]);

int blue = cm.getBlue(pixels[i]);

// 增加了图像的亮度

red = (int) (1.1 * red + 30);

green = (int) (1.1 * green + 30);

blue = (int) (1.1 * blue + 30);

if (red >= 255) {

red = 255;

}

if (green >= 255) {

green = 255;

}

if (blue >= 255) {

blue = 255;

}

pixels[i] = alpha << 24 | red << 16 | green << 8 | blue;

}

// 将数组中的象素产生一个图像

return ImageIOHelper.imageProducerToBufferedImage(new MemoryImageSource(iw, ih, pixels, 0, iw));

}

/** 转换为黑白灰度图 */

public BufferedImage grayFilter() {

ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);

ColorConvertOp op = new ColorConvertOp(cs, null);

return op.filter(image, null);

}

/** 平滑缩放 */

public BufferedImage scaling(double s) {

AffineTransform tx = new AffineTransform();

tx.scale(s, s);

AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);

return op.filter(image, null);

}

public BufferedImage scale(Float s) {

int srcW = image.getWidth();

int srcH = image.getHeight();

int newW = Math.round(srcW * s);

int newH = Math.round(srcH * s);

// 先做水平方向上的伸缩变换

BufferedImage tmp=new BufferedImage(newW, newH, image.getType());

Graphics2D g= tmp.createGraphics();

for (int x = 0; x < newW; x++) {

g.setClip(x, 0, 1, srcH);

// 按比例放缩

g.drawImage(image, x - x * srcW / newW, 0, null);

}

// 再做垂直方向上的伸缩变换

BufferedImage dst = new BufferedImage(newW, newH, image.getType());

g = dst.createGraphics();

for (int y = 0; y < newH; y++) {

g.setClip(0, y, newW, 1);

// 按比例放缩

g.drawImage(tmp, 0, y - y * srcH / newH, null);

}

return dst;

}

}

package com.ocr;

import java.awt.Graphics2D;

import java.awt.Image;

import java.awt.Toolkit;

import java.awt.image.BufferedImage;

import java.awt.image.DataBufferByte;

import java.awt.image.ImageProducer;

import java.awt.image.WritableRaster;

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 javax.swing.JOptionPane;

import com.sun.media.imageio.plugins.tiff.TIFFImageWriteParam;

public class ImageIOHelper {

public ImageIOHelper() {

}

public static File createImage(File imageFile, String imageFormat) {

File tempFile = null;

try {

Iterator readers = ImageIO.getImageReadersByFormatName(imageFormat);

ImageReader reader = readers.next();

ImageInputStream iis = ImageIO.createImageInputStream(imageFile);

reader.setInput(iis);

// Read the stream metadata

IIOMetadata streamMetadata = reader.getStreamMetadata();

// Set up the writeParam

TIFFImageWriteParam tiffWriteParam = new TIFFImageWriteParam(Locale.US);

tiffWriteParam.setCompressionMode(ImageWriteParam.MODE_DISABLED);

// Get tif writer and set output to file

Iterator writers = ImageIO.getImageWritersByFormatName("tiff");

ImageWriter writer = writers.next();

BufferedImage bi = reader.read(0);

IIOImage image = new IIOImage(bi, null, reader.getImageMetadata(0));

tempFile = tempImageFile(imageFile);

ImageOutputStream ios = ImageIO.createImageOutputStream(tempFile);

writer.setOutput(ios);

writer.write(streamMetadata, image, tiffWriteParam);

ios.close();

writer.dispose();

reader.dispose();

} catch (Exception exc) {

exc.printStackTrace();

}

return tempFile;

}

public static File createImage(BufferedImage bi) {

File tempFile = null;

try {

tempFile = File.createTempFile("tempImageFile", ".tif");

tempFile.deleteOnExit();

TIFFImageWriteParam tiffWriteParam = new TIFFImageWriteParam(Locale.US);

tiffWriteParam.setCompressionMode(ImageWriteParam.MODE_DISABLED);

// Get tif writer and set output to file

Iterator writers = ImageIO.getImageWritersByFormatName("tiff");

ImageWriter writer = writers.next();

IIOImage image = new IIOImage(bi, null, null);

tempFile = tempImageFile(tempFile);

ImageOutputStream ios = ImageIO.createImageOutputStream(tempFile);

writer.setOutput(ios);

writer.write(null, image, tiffWriteParam);

ios.close();

writer.dispose();

} catch (Exception exc) {

exc.printStackTrace();

}

return tempFile;

}

public static File tempImageFile(File imageFile) {

String path = imageFile.getPath();

StringBuffer strB = new StringBuffer(path);

strB.insert(path.lastIndexOf('.'), 0);

return new File(strB.toString().replaceFirst("(?<=//.)(//w+)$", "tif"));

}

public static BufferedImage getImage(File imageFile) {

BufferedImage al = null;

try {

String imageFileName = imageFile.getName();

String imageFormat = imageFileName.substring(imageFileName.lastIndexOf('.') + 1);

Iterator readers = ImageIO.getImageReadersByFormatName(imageFormat);

ImageReader reader = readers.next();

if (reader == null) {

JOptionPane.showConfirmDialog(null,

"Need to install JAI Image I/O package./nhttps://jai-imageio.dev.java.net");

return null;

}

ImageInputStream iis = ImageIO.createImageInputStream(imageFile);

reader.setInput(iis);

al = reader.read(0);

reader.dispose();

} catch (IOException ioe) {

System.err.println(ioe.getMessage());

} catch (Exception e) {

System.err.println(e.getMessage());

}

return al;

}

public static BufferedImage imageToBufferedImage(Image image) {

BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null),

BufferedImage.TYPE_INT_RGB);

Graphics2D g = bufferedImage.createGraphics();

g.drawImage(image, 0, 0, null);

return bufferedImage;

}

public static BufferedImage imageProducerToBufferedImage(ImageProducer imageProducer) {

return imageToBufferedImage(Toolkit.getDefaultToolkit().createImage(imageProducer));

}

public static byte[] image_byte_data(BufferedImage image) {

WritableRaster raster = image.getRaster();

DataBufferByte buffer = (DataBufferByte) raster.getDataBuffer();

return buffer.getData();

}

}

package com.ocr;

import java.io.BufferedReader;

import java.io.File;

import java.io.FileInputStream;

import java.io.InputStreamReader;

import java.util.ArrayList;

import java.util.List;

import org.jdesktop.swingx.util.OS;

public class OCR {

private final String LANG_OPTION = "-l";

private final String EOL = System.getProperty("line.separator");

private String tessPath = new File("tesseract").getAbsolutePath();

//private String tessPath="C://Program Files (x86)//Tesseract-OCR//";

public String recognizeText(File imageFile, String imageFormat) throws Exception {

File tempImage = ImageIOHelper.createImage(imageFile, imageFormat);

File outputFile = new File(imageFile.getParentFile(), "output");

StringBuffer strB = new StringBuffer();

List cmd = new ArrayList();

if (OS.isWindowsXP()) {

cmd.add(tessPath + "//tesseract");

//cmd.add(tessPath + "//Tesseract-OCR");

} else if (OS.isLinux()) {

cmd.add("tesseract");

} else {

//cmd.add(tessPath + "//Tesseract-OCR")

cmd.add(tessPath + "//tesseract");

}

cmd.add("");

cmd.add(outputFile.getName());

cmd.add(LANG_OPTION);

cmd.add("chi_sim");

cmd.add("eng");

ProcessBuilder pb = new ProcessBuilder();

pb.directory(imageFile.getParentFile());

cmd.set(1, tempImage.getName());

pb.command(cmd);

pb.redirectErrorStream(true);

Process process = pb.start();

//tesseract.exe 1.jpg 1 -l chi_sim

int w = process.waitFor();

// delete temp working files

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 recognize 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();

}

}

package com.ocr;

import java.io.File;

public class Test {

/**

* @param args

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

OCR ocr=new OCR();

try {

String maybe = new OCR().recognizeText(new  File("E://temp//222.jpg"), "jpg");

System.out.println(maybe);

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}


由于可以第三方包加起来有点大,告诉大家一个网站www.findjar.com去里面找你想要的包吧



java 目录结构如上图


效果图:


解析出来的效果

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容