首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 整合 Tesseract OCR 3.01 實現高精度中文文字識別(含圖像預處理)

     編輯:Java 相關知識

技術棧與依賴

  • Tesseract OCR 3.01+:支援中文(chi_sim.traineddata),命令行工具。
  • Java 依賴:jai_imageio (TIFF 支援)、swingx (OS 判斷)。
  • Maven:
<dependency>
    <groupId>javax.media.jai</groupId>
    <artifactId>jai_imageio</artifactId>
    <version>1.1</version>
</dependency>
<dependency>
    <groupId>org.swinglabs.swingx</groupId>
    <artifactId>swingx</artifactId>
    <version>1.6.5-1</version>
</dependency>

核心流程

  1. 圖像預處理:轉換為 **TIFF 格式**(Tesseract 3.x 最佳輸入格式),禁用壓縮。
  2. 調用 tesseract.exe 命令行:tesseract input.tif output -l chi_sim。
  3. 讀取生成的 output.txt,返回識別文本。
  4. 清理臨時文件。

關鍵代碼實現

1. 圖像轉 TIFF 工具類

public class ImageIOHelper {
    public static File createImage(File imageFile, String formatName) throws IOException {
        // 1. 獲取對應格式的 ImageReader
        Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName(formatName);
        ImageReader reader = readers.next();
        ImageInputStream iis = ImageIO.createImageInputStream(imageFile);
        reader.setInput(iis);
        
        // 2. 讀取圖像數據
        BufferedImage bi = reader.read(0);
        IIOImage image = new IIOImage(bi, null, reader.getImageMetadata(0));
        
        // 3. 配置 TIFF 寫入參數:無壓縮
        TIFFImageWriteParam tiffParam = new TIFFImageWriteParam(Locale.CHINESE);
        tiffParam.setCompressionMode(ImageWriteParam.MODE_DISABLED);
        
        // 4. 寫入臨時 TIFF 文件
        File tempFile = tempImageFile(imageFile); // 同目錄下 xxx0.tif
        Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("tiff");
        ImageWriter writer = writers.next();
        ImageOutputStream ios = ImageIO.createImageOutputStream(tempFile);
        writer.setOutput(ios);
        writer.write(reader.getStreamMetadata(), image, tiffParam);
        
        // 5. 釋放資源
        ios.close(); writer.dispose(); reader.dispose(); iis.close();
        return tempFile;
    }

    private static File tempImageFile(File original) {
        String path = original.getAbsolutePath();
        return new File(path.substring(0, path.lastIndexOf('.')) + "0.tif");
    }
}

2. OCR 調用封裝類

public class OCR {
    private final String tessPath = "C:/Program Files (x86)/Tesseract-OCR"; // 安裝路徑
    private final String LANG = "chi_sim"; // 中文簡體

    public String recognizeText(File imageFile, String format) throws Exception {
        File tiffFile = ImageIOHelper.createImage(imageFile, format);
        File outputBase = new File(imageFile.getParent(), "ocr_output");
        
        // 構建命令
        List cmd = new ArrayList<>();
        cmd.add(OS.isWindowsXP() ? tessPath + "/tesseract.exe" : "tesseract");
        cmd.add(tiffFile.getName());
        cmd.add(outputBase.getName());
        cmd.add("-l"); cmd.add(LANG);
        
        ProcessBuilder pb = new ProcessBuilder(cmd);
        pb.directory(imageFile.getParentFile());
        pb.redirectErrorStream(true);
        Process process = pb.start();
        int exitCode = process.waitFor();
        
        // 清理臨時 TIFF
        tiffFile.delete();
        
        if (exitCode == 0) {
            File txtFile = new File(outputBase.getAbsolutePath() + ".txt");
            String text = Files.readString(txtFile.toPath(), StandardCharsets.UTF_8);
            txtFile.delete();
            return text.trim();
        } else {
            throw new RuntimeException("Tesseract 執行失敗,退出碼: " + exitCode);
        }
    }
}

3. 測試類

public class OcrTest {
    public static void main(String[] args) {
        File img = new File("C:/temp/OCRcode/4.png"); // 驗證碼圖片
        try {
            String text = new OCR().recognizeText(img, "png");
            System.out.println("識別結果: " + text);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

關鍵技術點解析

環節說明
為何轉 TIFFTesseract 3.x 內部使用 Leptonica 庫,對 TIFF 支援最完善(無損、多頁、條帶/瓦片)
禁用壓縮MODE_DISABLED 避免壓縮伪影影響識別率
語言包chi_sim.traineddata 需放入 tessdata/ 目錄,安裝時勾選或手動下載
進程調用ProcessBuilder 替代 Runtime.exec(),支援工作目錄、環境變量、錯誤流合併
臨時文件清理識別完成後立即刪除 .tif 和 .txt,避免磁盤佔用

現代化升級建議

  1. 升級 Tesseract 4.x/5.x:基於 LSTM 神經網絡,識別率大幅提升,支援 --oem 1 (LSTM only),Java 調用方式相同。
  2. 使用 Tess4J:Tesseract 官方 JNA 綁定庫,無需命令行調用、無需臨時文件、支援 BufferedImage 直接識別。
    ITesseract instance = new Tesseract(); instance.setDatapath("tessdata"); String result = instance.doOCR(bufferedImage);
  3. 圖像預處理增強:二值化、去噪、傾斜校正、字符分割,使用 OpenCV (JavaCV) 顯著提升驗證碼識別率。
  4. 併發處理:Tesseract 非線程安全,使用對象池 (GenericObjectPool) 管理 ITesseract 實例。

總結

本文展示了 Java 調用 Tesseract 3.01 命令行實現中文 OCR 的完整流程:圖像轉 TIFF → 進程調用 → 結果解析。雖然可行,但強烈建議遷移至 Tess4J + Tesseract 4+/5+,獲得更高識別率、更簡潔 API、更好併發支援。驗證碼識別屬於對抗性場景,單純 OCR 難以長期有效,需結合深度學習專用模型(如 CRNN、Transformer)持續迭代。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved