欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2023-12-17 20:22:10
接着上一篇ocr所说的,上一篇给大家介绍了tesseract 在命令行的简单用法,当然了要继承到我们的程序中,还是需要代码实现的,下面给大家分享下java实现的例子。...

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

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

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

下面是核心代码:

package com.zhy.test; 
 
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 ocrhelper 
{ 
 private final string lang_option = "-l"; 
 private final string eol = system.getproperty("line.separator"); 
 /** 
  * 文件位置我防止在,项目同一路径 
  */ 
 private string tesspath = new file("tesseract").getabsolutepath(); 
 
 /** 
  * @param imagefile 
  *   传入的图像文件 
  * @param imageformat 
  *   传入的图像格式 
  * @return 识别后的字符串 
  */ 
 public string recognizetext(file imagefile) throws exception 
 { 
  /** 
   * 设置输出文件的保存的文件目录 
   */ 
  file outputfile = new file(imagefile.getparentfile(), "output"); 
 
  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("chi_sim"); 
  cmd.add("eng"); 
 
  processbuilder pb = new processbuilder(); 
  /** 
   *sets this process builder's working directory. 
   */ 
  pb.directory(imagefile.getparentfile()); 
  cmd.set(1, imagefile.getname()); 
  pb.command(cmd); 
  pb.redirecterrorstream(true); 
  process process = pb.start(); 
  // tesseract.exe 1.jpg 1 -l chi_sim 
  // runtime.getruntime().exec("tesseract.exe 1.jpg 1 -l chi_sim"); 
  /** 
   * the exit value of the process. by convention, 0 indicates normal 
   * termination. 
   */ 
//  system.out.println(cmd.tostring()); 
  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*", ""); 
 } 
} 

代码很简单,中间那部分processbuilder其实就类似runtime.getruntime().exec("tesseract.exe 1.jpg 1 -l chi_sim"),大家不习惯的可以使用runtime。

测试代码:

package com.zhy.test; 
 
import java.io.file; 
 
public class test 
{ 
 public static void main(string[] args) 
 { 
  try 
  { 
    
   file testdatadir = new file("testdata"); 
   system.out.println(testdatadir.listfiles().length); 
   int i = 0 ; 
   for(file file :testdatadir.listfiles()) 
   { 
    i++ ; 
    string recognizetext = new ocrhelper().recognizetext(file); 
    system.out.print(recognizetext+"\t"); 
 
    if( i % 5 == 0 ) 
    { 
     system.out.println(); 
    } 
   } 
    
  } catch (exception e) 
  { 
   e.printstacktrace(); 
  } 
 
 } 
} 

输出结果:

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

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

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

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

来张特写:

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

一个类,不依赖任何jar,把图像中的干扰线消灭了,是不是很给力,然后再拿这样的图片去识别,会不会效果更好呢,嘿嘿,大家自己实验~

代码:

package com.zhy.test; 
 
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("testdata"); 
  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; 
 } 
} 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。 

上一篇:

下一篇: