最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java OCR tesseract 圖像智能文字字符識(shí)別技術(shù)實(shí)例代碼

 更新時(shí)間:2017年06月20日 14:43:00   作者:鴻洋_  
這篇文章主要介紹了Java OCR tesseract 圖像智能文字字符識(shí)別技術(shù)實(shí)例代碼,非常具有實(shí)用價(jià)值,需要的朋友可以參考下

接著上一篇OCR所說(shuō)的,上一篇給大家介紹了tesseract 在命令行的簡(jiǎn)單用法,當(dāng)然了要繼承到我們的程序中,還是需要代碼實(shí)現(xiàn)的,下面給大家分享下Java實(shí)現(xiàn)的例子。

拿代碼掃描上面的圖片,然后輸出結(jié)果。主要思想就是利用Java調(diào)用系統(tǒng)任務(wù)。

下面是核心代碼:

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"); 
 /** 
  * 文件位置我防止在,項(xiàng)目同一路徑 
  */ 
 private String tessPath = new File("tesseract").getAbsolutePath(); 
 
 /** 
  * @param imageFile 
  *   傳入的圖像文件 
  * @param imageFormat 
  *   傳入的圖像格式 
  * @return 識(shí)別后的字符串 
  */ 
 public String recognizeText(File imageFile) throws Exception 
 { 
  /** 
   * 設(shè)置輸出文件的保存的文件目錄 
   */ 
  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*", ""); 
 } 
} 

代碼很簡(jiǎn)單,中間那部分ProcessBuilder其實(shí)就類(lèi)似Runtime.getRuntime().exec("tesseract.exe 1.jpg 1 -l chi_sim"),大家不習(xí)慣的可以使用Runtime。

測(cè)試代碼:

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

輸出結(jié)果:

對(duì)比第一張圖片,是不是很完美~哈哈 ,當(dāng)然了如果你只需要實(shí)現(xiàn)驗(yàn)證碼的讀寫(xiě),那么上面就足夠了。下面繼續(xù)普及圖像處理的知識(shí)。

當(dāng)然了,有時(shí)候圖片被扭曲或者模糊的很厲害,很不容易識(shí)別,所以下面我給大家介紹一個(gè)去噪的輔助類(lèi),絕對(duì)碉堡了,先看下效果圖。

 

來(lái)張?zhí)貙?xiě):

一個(gè)類(lèi),不依賴(lài)任何jar,把圖像中的干擾線消滅了,是不是很給力,然后再拿這樣的圖片去識(shí)別,會(huì)不會(huì)效果更好呢,嘿嘿,大家自己實(shí)驗(yàn)~

代碼:

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); 
    // 圖像加亮(調(diào)整亮度識(shí)別率非常高) 
    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; 
 } 
} 

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。 

相關(guān)文章

  • java中Javers?比較兩個(gè)類(lèi)的差異

    java中Javers?比較兩個(gè)類(lèi)的差異

    本文主要介紹了Javers?比較兩個(gè)類(lèi)的差異,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • Java Socket實(shí)現(xiàn)文件傳輸示例代碼

    Java Socket實(shí)現(xiàn)文件傳輸示例代碼

    這篇文章主要介紹了Java Socket實(shí)現(xiàn)文件傳輸示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-01-01
  • SpringBoot整合Spring Batch示例代碼

    SpringBoot整合Spring Batch示例代碼

    這篇文章主要來(lái)和大家一起探討一下SpringBoot如何整合Spring Batch,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-10-10
  • 本真的REST架構(gòu)風(fēng)格理解

    本真的REST架構(gòu)風(fēng)格理解

    這篇文章主要為大家介紹了本真的REST架構(gòu)風(fēng)格的深入理解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-03-03
  • JAVA字符串類(lèi)型switch的底層原理詳析

    JAVA字符串類(lèi)型switch的底層原理詳析

    這篇文章主要給大家介紹了關(guān)于JAVA字符串類(lèi)型switch的底層原理的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用JAVA具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Spring Boot 和 Spring 到底有啥區(qū)別你知道嗎

    Spring Boot 和 Spring 到底有啥區(qū)別你知道嗎

    Spring Boot框架的核心就是自動(dòng)配置,只要存在相應(yīng)的jar包,Spring就幫我們自動(dòng)配置。接下來(lái)通過(guò)本文給大家介紹Spring與Spring boot的區(qū)別介紹,非常不錯(cuò),需要的朋友參考下吧
    2021-08-08
  • 如何解決Idea斷點(diǎn)調(diào)試亂跳的問(wèn)題

    如何解決Idea斷點(diǎn)調(diào)試亂跳的問(wèn)題

    這篇文章主要介紹了如何解決Idea斷點(diǎn)調(diào)試亂跳的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • JDK動(dòng)態(tài)代理步驟詳解(源碼分析)

    JDK動(dòng)態(tài)代理步驟詳解(源碼分析)

    這篇文章主要介紹了JDK動(dòng)態(tài)代理步驟詳解,首先需要?jiǎng)?chuàng)建一個(gè)實(shí)現(xiàn)接口InvocationHandler的類(lèi),它必須實(shí)現(xiàn)invoke方法 ,最后通過(guò)Proxy的靜態(tài)方法實(shí)現(xiàn)此操作,需要的朋友可以參考下
    2021-06-06
  • 基于Spring Web Jackson對(duì)RequestBody反序列化失敗的解決

    基于Spring Web Jackson對(duì)RequestBody反序列化失敗的解決

    這篇文章主要介紹了基于Spring Web Jackson對(duì)RequestBody反序列化失敗的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-09-09
  • 詳解Spring中Bean后置處理器(BeanPostProcessor)的使用

    詳解Spring中Bean后置處理器(BeanPostProcessor)的使用

    BeanPostProcessor 接口也被稱(chēng)為Bean后置處理器,通過(guò)該接口可以自定義調(diào)用初始化前后執(zhí)行的操作方法。本文將詳細(xì)講講它的使用,需要的可以參考一下
    2022-06-06

最新評(píng)論

北票市| 武定县| 丰镇市| 宣化县| 三河市| 扎兰屯市| 日喀则市| 涞水县| 饶河县| 双辽市| 东乡族自治县| 双柏县| 威远县| 若尔盖县| 怀集县| 新建县| 玉田县| 望谟县| 铜梁县| 宜君县| 盐源县| 万年县| 法库县| 新建县| 甘谷县| 梅河口市| 达日县| 宜君县| 陇南市| 东海县| 丰原市| 孝昌县| 娱乐| 辰溪县| 正镶白旗| 东至县| 电白县| 田东县| 额尔古纳市| 绥芬河市| 夏邑县|