基於Tesseract實現圖片文字識別
一.簡介
Tesseract是一個開源的文字識別【OCR】引擎,可通過Apache 2.0許可獲得。它可以直接使用,或者使用API從影象中提取列印的文字,支援多種語言。該軟體包包含一個ORC引擎【libtesseract】和一個命令列程式【tesseract】。Tesseract4添加了一個新的基於LSTM的OCR引擎,該引擎專注於行識別,但仍支援Tesseract 3的傳統Tesseract OCR引擎,該引擎通過識別字符模式進行工作。通過使用傳統OCR引擎模式【--oem 0】,可以與Tesseract 3相容。它還需要訓練好的資料檔案對舊引擎進行支援,例如tessdata目錄下的資料檔案。
特點:
1.具有Unicode【UTF-8】支援,並且可以“開箱即用”地識別100多種語言。
2.支援各種輸出格式,純文字,hOCR【HTML】,PDF,僅不可見文字的PDF,TSV。Master分支還對ALTO【XML】輸出提供實驗性支援。
3.在許多情況下,要想獲得更好的OCR結果,需要提高提供給Tesseract的影象的質量。
二.在python環境中安裝pytesseract
安裝成功!
三.在Windows系統下安裝Tesseract
配置環境變數:
備註:最新的為4.1.0,建議安裝4.x版本,根據一可知,版本4有重大升級,系統性能顯著提升,特別是在對中文的識別上更是明顯!
四.python程式碼實現
1 # -*- coding: utf-8 -*- 2 """ 3 Spyder Editor 4 5 This is a temporary script file. 6 """ 7 8 import pytesseract 9 from PIL import Image 10 11 #開啟驗證碼圖片 12 image = Image.open('E:\\testData\\tess\\1.png') 13 #載入一下圖片防止報錯,此處可以省略 14 #image.load() 15 #呼叫show來展示圖片,除錯用此處可以省略 16 #image.show() 17 text = pytesseract.image_to_string(image,lang='chi_sim') 18 print(text)
五.Python環境執行結果【無資料清洗】
20 a 志 口 吳 吊 5 達 吊 園 康 阮 隨 阮 隨 隨 阮 隆 隨 阮 阮 龐 應 阮 院 阮 阮 際 阮 阮 院 院 阮 龐 宇 B B B B B B B B B B E 胡 胡 胡 胡 胡 胡 胡 胡 胡 胡 脫 醫 劇 澈 剖 剖 亨 亨 定 亨 宣 河 宇 B B B B E E E E E E 振 產 蓮 主 主 主 主 主 主 主 主 主 主 生 交 E E E E E E E E E E E35653 職 職 職 職 職 職 職 職 職 職 E E E E E E E E E E E 093View Code
部分示例:
可知對中文的識別一塌糊塗,因此建議還是使用版本4進行識別!
六.使用Java程式呼叫ImageIO進行資料預處理
1 package zhen; 2 import java.awt.Color; 3 import java.awt.image.BufferedImage; 4 import java.io.File; 5 import java.io.FileInputStream; 6 import java.io.IOException; 7 8 import javax.imageio.ImageIO; 9 10 11 public class LineMark{ 12 public static void clean(String fromPath,String toPath) throws IOException{ 13 File file1 = new File(fromPath); 14 BufferedImage image = ImageIO.read(file1); 15 16 BufferedImage sourceImg =ImageIO.read(new FileInputStream(file1)); // 獲取圖片的長寬 17 int width = sourceImg.getWidth(); 18 int height = sourceImg.getHeight(); 19 20 /** 21 * 建立3維陣列用於儲存圖片rgb資料 22 */ 23 int[][][] array = new int[width][height][3]; 24 for(int i=0;i<width;i++){ // 獲取圖片中所有畫素點的rgb 25 for(int j=0;j<height;j++){ 26 int pixel = image.getRGB(i, j); //獲得座標(i,j)的畫素 27 int red = (pixel & 0xff0000) >> 16; 28 int green = (pixel & 0xff00) >> 8; 29 int blue = (pixel & 0xff); //通過座標(i,j)的畫素值獲得r,g,b的值 30 array[i][j][0] = red; 31 array[i][j][1] = green; 32 array[i][j][2] = blue; 33 } 34 } 35 36 /** 37 * 清除表格線: 38 * 豎線:絕大多數點的x值都為255 39 */ 40 for(int i=0;i<width;i++){ 41 int nums = 0; 42 for(int j=0;j<height;j++){ 43 if(array[i][j][0]<128 && array[i][j][1]<128 && array[i][j][2]<128){ 44 nums += 1; 45 } 46 } 47 if(nums > height * 0.8){ 48 for(int n=0;n<height;n++){ 49 array[i][n][0] = 255; 50 array[i][n][1] = 255; 51 array[i][n][2] = 255; 52 } 53 } 54 } 55 /** 56 * 清除表格線: 57 * 橫線:絕大多數點的y值都為255 58 */ 59 for(int j=0;j<height;j++){ 60 int nums = 0; 61 for(int i=0;i<width;i++){ 62 if(array[i][j][0]<128 && array[i][j][1]<128 && array[i][j][2]<128){ 63 nums += 1; 64 } 65 } 66 if(nums > height * 0.8){ 67 for(int n=0;n<width;n++){ 68 array[n][j][0] = 255; 69 array[n][j][1] = 255; 70 array[n][j][2] = 255; 71 } 72 } 73 } 74 /** 75 * 大點 76 */ 77 for(int i=0;i<width;i++){ 78 for(int j=0;j<height;j++){ 79 int cover = new Color(array[i][j][0],array[i][j][1],array[i][j][2]).getRGB(); 80 image.setRGB(i,j,cover); 81 } 82 } 83 File file2 = new File(toPath); 84 ImageIO.write(image, "png", file2); 85 } 86 87 /** 88 * 測試 89 * @param args 90 */ 91 public static void main(String[] args){ 92 String fromPath = "E:\\testData\\tess\\111.png"; 93 String toPath = "E:\\testData\\tess\\112.png"; 94 try { 95 LineMark.clean(fromPath,toPath); 96 } catch (IOException e) { 97 e.printStackTrace(); 98 } 99 } 100 }
七.執行結果
處理之前:
處理之後:
八.使用Tesseract 4 API進行文字識別
1 package zhen; 2 import java.awt.Rectangle; 3 import java.awt.image.BufferedImage; 4 import java.io.File; 5 import java.io.FileInputStream; 6 import java.io.FileOutputStream; 7 import java.io.IOException; 8 import javax.imageio.ImageIO; 9 import net.sourceforge.tess4j.*; 10 import org.apache.poi.xssf.usermodel.*; 11 12 public class RP { 13 private String a0=""; 14 15 public void toExcel(int i,XSSFWorkbook wb,XSSFSheet sheet,int len) //將文字資訊做成表格 16 { 17 for(int j=0;j<len;j++){ 18 String[] array = this.a0.split("\n"); // 分行 19 for(int k=0;k<array.length;k++){ 20 XSSFRow row = sheet.createRow(k); // 建立一行 21 String[] array2 = array[k].split(" "); 22 for(int m=0;m<array2.length;m++){ 23 row.createCell(m).setCellValue(array2[m]); 24 } 25 } 26 } 27 } 28 public static void main(String[] args) throws IOException { 29 RP rp = new RP(); 30 int num = 1; 31 32 File root = new File("E:\\testData\\tess2");//存放處理後的圖片,imgs資料夾 33 File res = new File("E:\\testData\\tess");//源圖片位置,res資料夾下 34 35 ITesseract instance = new Tesseract(); 36 instance.setLanguage("chi_sim"); //使用訓練好中文字型檔識別 37 38 XSSFWorkbook wb = new XSSFWorkbook(); 39 XSSFSheet sheet = wb.createSheet("資訊彙總"); 40 try { 41 File[] ress = res.listFiles(); 42 int i=0; 43 for(File file : ress){ 44 i++; 45 LineMark.clean(file.getAbsolutePath(),"E:\\testData\\tess2\\"+i+".png"); 46 } //去除源圖片表格線,處理後的圖片放到img資料夾 47 48 File[] files = root.listFiles(); 49 for (File file : files) { //對去除水印後的圖片逐個處理 50 BufferedImage sourceImg =ImageIO.read(new FileInputStream(file)); // 獲取圖片的長寬 51 int width = sourceImg.getWidth(); 52 int height = sourceImg.getHeight(); 53 Rectangle ret = new Rectangle(0,0,width,height); //識別全部資料 54 55 String result = instance.doOCR(file, ret); //開始採用doOCR(file)效率很低,因為圖片內容太多 56 int len = 0; 57 if(result != null){ 58 len = result.split(" ").length; 59 rp.a0 = result; 60 } 61 System.out.print(result); 62 rp.toExcel(num,wb,sheet,len); //呼叫toExcel函式,將提取到的資訊寫入 63 num++; 64 } 65 } catch (TesseractException e) { 66 System.err.println(e.getMessage()); 67 } 68 69 try { 70 FileOutputStream fout = new FileOutputStream("D:\\software\\company.xlsx"); 71 wb.write(fout); 72 fout.close(); 73 } catch (IOException e) { 74 e.printStackTrace(); 75 } //把寫好資訊的表輸出 76 } 77 78 }
九.不資料清洗執行結果
十.資料清洗執行結果
經過對比可以明顯看出,表格線對識別的影響很大【其它形式的干擾也同樣如此,例如:驗證碼上的干擾線、圖案等】,因此,資料清洗必不可少!
十一.分析
從上面的執行結果可知,在使用Tesseract 4時,在資料儘可能的清晰的情況下,大部分漢字還是能識別出來的,只是在【數字0】和【標點符號。】,【英語g】和【數字9】等外形相識的地方識別不清楚!當然,模型還有提升的空間,下一步將提升對存在格式傾斜或拍照的圖片進行識別的能