天天看點

Java 幾行代碼提取圖檔文字,過個厲害了。

一、tesseract-ocr介紹

ocr含義是Optical Character Recognition,含義即視覺字元識别。而tesseract是該領域特别優秀開源的作品。

官方的tesseract定義:

OCR engine - libtesseract and a command line program - tesseract.

即tesseract包括一個視覺字元識别引擎libtesseract和指令行程式tesseract。

目前最新穩定版本是4.x.x基于LSTM,源碼可從找到tesseract的GitHub: tesseract.找到。

Java 幾行代碼提取圖檔文字,過個厲害了。

關于tesseract的工作模式如上圖所示。假設現在有一個圖檔輸入,整個執行流程為:

輸入(一張圖檔)

有用資訊提取(比如一個圖檔上隻有一個字,那其他留白的是無用,這個字上每個色素是有效的并且相關)

找出文字/線條

字元分類集

輸入與分類集對比找出最接近的

輸出識别結果

二、安裝tesseract

第一步下載下傳

下載下傳合适的exe安裝檔案:

網址:

https://digi.bib.uni-mannheim.de/tesseract/ ,下載下傳完成後後裝即可
Java 幾行代碼提取圖檔文字,過個厲害了。

第二步環境變量配置

在path變量中加入tesseract-ocr的安裝路徑

Java 幾行代碼提取圖檔文字,過個厲害了。

第三步安裝成功檢測

使用tesseract指令,顯示如下:

Java 幾行代碼提取圖檔文字,過個厲害了。
linux環境下載下傳安裝與上述類似
Java 幾行代碼提取圖檔文字,過個厲害了。

下載下傳leptonica 和 tesseract兩個包,解壓安裝,配置環境變量即可。網上很容易找到該安裝包。

三、使用指令行

1.tesseract + 圖檔路徑 + 儲存結果名 + -l 語言集

示列: tesseract 1606150081.png 1606150081 -l chi_sim

2.tesseract + 圖檔路徑 +stdout -l +語言集

示列: tesseract D:\company\ruigushop\spring-2s\test.png stdout -l chi_sim

有了上述之後就可以完成web圖檔識别程式的開發啦,廢話不多說,直接上代碼。

四、程式實作(Python)

程式設計思路:

上傳圖檔 -> 儲存 ->對上傳的圖檔執行tesseract指令->擷取識别結果

隻有二十多行代碼就實作了,so easy,以後網上看到圖檔識别程式再也不會感覺神奇了吧!

# coding=utf-8
from flask import Flask, request
import os
import datetime
import time

app = Flask(__name__)

def get_time_stamp():
    times = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    array = time.strptime(times, "%Y-%m-%d %H:%M:%S")
    time_stamp = int(time.mktime(array))
    return time_stamp

@app.route('/image/extract', methods=['POST'])
def pure_rec():
    file = request.files.get('file')
    ts = str(get_time_stamp())
    up_path = os.path.join(ts + file.filename)
    file.save(up_path)
    cmd = "tesseract "+up_path+" " + ts + " -l chi_sim"
    print(cmd)
    os.system(cmd)
    with open(ts+".txt", 'r+', encoding="utf-8") as f:
        result = f.read()
        return result

if __name__ == '__main__':
    app.run(debug=True)      

五、程式實作(Java)

不需要任何引入第三方jar包,搭建一個簡單的springboot web項目就可以了,沒有其他額外的依賴。

Spring Boot 基礎就不介紹了,推薦下這個實戰教程:

https://www.javastack.cn/categories/Spring-Boot/

Controller:

package com.lbh.web.controller;

/*
 * Copyright@[email protected]
 * Author:liubinhao
 * Date:2020/11/23
 * ++++ ______ @author       liubinhao   ______             ______
 * +++/     /|                         /     /|           /     /|
 * +/_____/  |                       /_____/  |         /_____/  |
 * |     |   |                      |     |   |        |     |   |
 * |     |   |                      |     |   |________|     |   |
 * |     |   |                      |     |  /         |     |   |
 * |     |   |                      |     |/___________|     |   |
 * |     |   |___________________   |     |____________|     |   |
 * |     |  /                  / |  |     |   |        |     |   |
 * |     |/ _________________/  /   |     |  /         |     |  /
 * |_________________________|/b    |_____|/           |_____|/
 */
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;

@RestController
public class LiteralExtractController {

    @PostMapping("/image/extract")
    public String reg(@RequestParam("file")MultipartFile file) throws IOException {
        String result = "";
        String filename = file.getOriginalFilename();
        File save = new File(System.getProperty("user.dir")+"\\"+filename);
        if (!save.exists()){
            save.createNewFile();
        }
        file.transferTo(save);
        String cmd = String.format("tesseract %s stdout -l %s",System.getProperty("user.dir")+"\\"+filename,"chi_sim");
        result = cmd(cmd);
        return result;
    }

    public static String cmd(String cmd) {
        BufferedReader br = null;
        try {
            Process p = Runtime.getRuntime().exec(cmd);
            br = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String line = null;
            StringBuilder sb = new StringBuilder();
            while ((line = br.readLine()) != null) {
                sb.append(line + "\n");
            }
            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        finally
        {
            if (br != null)
            {
                try {
                    br.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}      

哈哈哈,還有帥氣的程式logo。

六、實驗測試

很簡單二十多行代碼就完成了,看看效果怎麼樣吧。

測試一圖檔:

Java 幾行代碼提取圖檔文字,過個厲害了。

測試一結果:

Java 幾行代碼提取圖檔文字,過個厲害了。

測試二圖檔:

Java 幾行代碼提取圖檔文字,過個厲害了。

測試二結果:

Java 幾行代碼提取圖檔文字,過個厲害了。

perfect,識别的很準确,第二個測試全部是英文字元的時候我們采用了中文訓練的資料集,雖然也很好的識别了,但是速度會慢很多。

七、總結

圖檔識别在當今網絡技術領域是非常熱門的一塊,而這次完成的這個程式完全是依賴别人開源架構來完成了這個技術實作,在應用層面這是成功的,但是本質上并沒有實際算法,技術核心上的東西,如果隻關心應用層開發上述解決了我們計算機在規則字元識别上的問題。

上述代碼中基本沒有難點,直接複制即可使用。此外,tesseract作為一款優秀的開源字元識别軟體,但它也不是萬能的,tesseract隻能識别規則的字元,對于一些藝術字,抽象字它是無能為力的。