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

來源:blog.csdn.net/weixin_44671737/article/details/110000864

摘要

近日瀏覽網上一些圖片提取文字的網站,覺得甚是有趣,花費半日也做了個在線圖片識別程序,完成了兩個技術方案的選擇,一是tesseract+python flask的方案實現,二是tesseract+spring web的技術解決方案,並簡作論述,與君共勉。

一、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.找到。

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

  1. 輸入(一張圖片)
  2. 有用信息提取(比如一個圖片上只有一個字,那其他留白的是無用,這個字上每個色素是有效的並且相關)
  3. 找出文字/線條
  4. 字符分類集
  5. 輸入與分類集對比找出最接近的
  6. 輸出識別結果

二、安裝tesseract

第一步下載

下載合適的exe安裝文件:

網址:https://digi.bib.uni-mannheim.de/tesseract/,下載完成後後裝即可

第二步環境變量配置

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

第三步安裝成功檢測

使用tesseract指令,顯示如下:

linux環境下載安裝與上述類似

下載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。

六、實驗測試

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

測試一圖片:

測試一結果:

測試二圖片:

測試二結果:

perfect,識別的很準確,第二個測試全部是英文字符的時候我們採用了中文訓練的數據集,雖然也很好的識別了,但是速度會慢很多。

七、總結

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

上述代碼中基本沒有難點,直接複製即可使用。此外,tesseract作爲一款優秀的開源字符識別軟件,但它也不是萬能的,tesseract只能識別規則的字符,對於一些藝術字,抽象字它是無能爲力的。

近期熱文推薦:

1.1,000+ 道 Java面試題及答案整理(2021最新版)

2.別在再滿屏的 if/ else 了,試試策略模式,真香!!

3.臥槽!Java 中的 xx ≠ null 是什麼新語法?

4.Spring Boot 2.5 重磅發佈,黑暗模式太炸了!

5.《Java開發手冊(嵩山版)》最新發布,速速下載!

覺得不錯,別忘了隨手點贊+轉發哦!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章