Java OCR tesseract 映像智能字元識別技術 Java代碼實現

來源:互聯網
上載者:User

標籤:介紹   讀寫   enter   使用   buffer   file   des   bool   byte   

接著上一篇OCR所說的。上一篇給大家介紹了tesseract 在命令列的簡單使用方法,當然了要繼承到我們的程式中,還是須要代碼實現的。以下給大家分享下java實現的範例。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbG1qNjIzNTY1Nzkx/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" />

拿代碼掃描上面的圖片,然後輸出結果。

主要思想就是利用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*", "");}}
代碼非常easy,中間那部分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();}}}

輸出結果:


對照第一張圖片,是不是非常完美~哈哈 ,當然了假設你僅僅須要實現驗證碼的讀寫。那麼上面就足夠了。以下繼續普及影像處理的知識。



-------------------------------------------------------------------我的切割線--------------------------------------------------------------------

當然了。有時候圖片被扭曲或者模糊的非常厲害。非常不easy識別,所以以下我給大家介紹一個去噪的輔助類,絕對碉堡了,先看下。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbG1qNjIzNTY1Nzkx/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" />

來張特寫:


一個類,不依賴不論什麼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 histogramfor (int x = 0; x < w; x++){for (int y = 0; y < h; y++){int red = 0xFF & gray[x][y];histData[red]++;}}// Total number of pixelsint 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 Backgroundif (wB == 0)continue;wF = total - wB; // Weight Foregroundif (wF == 0)break;sumB += (float) (t * histData[t]);float mB = sumB / wB; // Mean Backgroundfloat mF = (sum - sumB) / wF; // Mean Foreground// Calculate Between Class Variancefloat varBetween = (float) wB * (float) wF * (mB - mF) * (mB - mF);// Check if new maximum foundif (varBetween > varMax){varMax = varBetween;threshold = t;}}return threshold;}}


好了,就到這裡。假設這篇文章對你實用,贊一個吧~





Java OCR tesseract 映像智能字元識別技術 Java代碼實現

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.