Pages

2023年5月4日 星期四

Java使用Tesseract進行OCR辨識的一些心得

最近有個專案想抓取PDF的檔案內容,進行檔案rename的動作,因此才開始瞭解Tesseract相關的用法,以下是使用的一些心得。

1. Windows上安裝Tesseract 5.0後,如果想轉移到其他台Windows PC,該PC要先安裝 Visual Studio 2015 的 Visual C++ 可轉散發套件,再將Tesseract安裝的目錄整個zip起來後,在其他台Windows PC上解壓縮後,設定Tesseract相關windows環境變數路徑後,Java程式就可以直接使用。


2. Tesseract程式中辨識資料的路徑與繁體中文語言設定如下:

tesseract.setDatapath("D:\\Tesseract-OCR\\tessdata\\");
tesseract.setLanguage("chi_tra");


3. 不要透過抓取PDF文字後再辨識,因為會抓不到PDF內容文字,要先轉成圖檔(TIFF)後,在進行圖片辨識文字,會比較不會出錯,下面是範例的Code。

private boolean pdfToTiffConverter(String inputPdf, String outputTiff) {
  int dpi = 300; // the resolution of the output image in DPI
  boolean result = false;
  PDDocument document = null;
  PDFRenderer pdfRenderer = null;
  BufferedImage image = null;
  try {
  	File pdfFile = new File(inputPdf);
  	Thread.sleep(100); // wait 100ms for loading pdf to memory to avoid NullPointException 
  	document = PDDocument.load(pdfFile);
    pdfRenderer = new PDFRenderer(document);
    image = pdfRenderer.renderImageWithDPI(0, dpi); // render the first page of the PDF document
    ImageIO.write(image, "TIFF", new File(outputTiff)); // write the image to a TIFF file
    result = true;
    document.close();
  } catch (IOException e) {
  	logger.error(e.getStackTrace());
  	result = false;
  } catch (InterruptedException e) {
  	logger.error(e.getStackTrace());
  } finally {
  }
  return result;
}

private String tiffOcr(String outputTiff) {
  String tiffPath = outputTiff;
  Tesseract tesseract = new Tesseract();
  String result = "";
  try {
    tesseract.setDatapath("D:\\Tesseract-OCR\\tessdata\\"); // set the path to the Tesseract data directory
    tesseract.setLanguage("chi_tra");
    result = tesseract.doOCR(new File(tiffPath));
  } catch (TesseractException e) {
    logger.error(e.getStackTrace());
  } finally {
    File imageFile = new File(outputTiff);
    if(imageFile.exists()) imageFile.delete();
  }
  return result;
}

4. import的套件很多,可以參考下面圖片的套件版本。


5. 在Eclipse上運行正常,但匯出成可運行的JAR後,辨識時會出現以下錯誤。

javax.imageio.spi.ImageOutputStreamSpi: Provider com.sun.media.imageioimpl.stream.ChannelImageOutputStreamSpi could not be instantiated

解決方式:Eclipse匯出方式需要變更為【copy required libraries into sub-folder....】。


可運行的JAR在執行前,要先把sub-folder的目錄跟可運行的JAR放在同一層執行,這樣才能順利運行。

這個問題花了我5個小時才解決掉,希望對大家有助。




0 意見: