0
4

More than 1 year has passed since last update.

Tesseract OCRをvcpkgでインストールしてdllをRustで使う

Last updated at Posted at 2023-01-12

Rust から Tesseract OCR(のライブラリ)を呼び出そうと色々やっていました。
ひとまず動くようになったので備忘録としてあげておきます。
vcpkg でインストールした DLL を Rust で使う、という場合にも使えると思います。

vcpkg をインストールする

GitHubの説明に則ってインストールします。
https://github.com/microsoft/vcpkg

Tesseract OCRライブラリをインストールする

以下コマンドでインストールします。
アニメ一本分くらいは時間かかります。
./vcpkg install tesseract:x64-windows

依存関係のあるパッケージも一緒にインストールしてくれますが、足りない場合は以下を実行してみてください。

./vcpkg install leptonica:x64-windows

Rust プロジェクトで読み込む

tesseract クレートを利用しました。
https://crates.io/crates/tesseract

Cargo.toml に以下を追記してビルドします。
tesseract = "0.12.0"

main.rs は最低限の記述にします。

main.rs
let text = tesseract::ocr("test.png", "jpn").unwrap();
println!("Tesseract: {}", text);

lib をプロジェクトのルートに設置する

vcpkg でインストールした .lib ファイルを Rust プロジェクトのルートフォルダに配置します。
lib ファイルは vcpkg\installed\x64-windows\lib 以下にあります。
tesseract のビルドに必要なファイルは以下のようです。

  • leptonica-1.82.0.lib
  • libcrypto.lib
  • libcurl.lib
  • tesseract52.lib

設置したらビルドしてみます。

> cargo build

エラーが出なければひとまずOKです。
ただし、ビルドは通っても cargo run すると DLL が足らないと怒られます。
error: process didn't exit successfully: target\debug\tesseract_rust.exe (exit code: 0xc0000135, STATUS_DLL_NOT_FOUND)

実行に必要な DLL を設置する

DLL はプロジェクトのルートではなく、exe と同じパスに設置する必要があります。
target\debug\ 以下に DLL を設置します。

lib ファイルとは違い、関連する DLL が全て必要です。
vcpkg\installed\x64-windows\tools\tesseract\ 以下にある DLL を全て target\debug\ 以下にコピーします。

動かしてみます。

> cargo run

言語ファイルが無いと言われます。
GitHub から jpn.traineddata を DL してプロジェクトのルートフォルダに設置します。
https://github.com/tesseract-ocr/tessdata

これで動作するようになりました。

build.rs でビルドを自動化する

ビルドや実行の度に関連ファイルを設置するのは面倒なので、build.rs を書いて自動化してみました。

build.rs
fn main() {
    let project_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
    println!("cargo:rustc-link-search=native={}\\lib", project_dir);

    let target_path = std::path::Path::new(&project_dir).join("target");

    if target_path.exists() {
        let debug_path = target_path.join("debug");
        let release_path = target_path.join("release");
        let dll_files = std::fs::read_dir(std::path::Path::new(&(project_dir + "\\dll"))).unwrap()
            .map(|res| res.map(|e| e.path()))
            .collect::<Result<Vec<_>, std::io::Error>>().unwrap();
        
        for path in dll_files {
            if debug_path.exists() {
                std::fs::copy(&path, debug_path.join(&path.file_name().unwrap())).unwrap();
            }
            if release_path.exists() {
                std::fs::copy(&path, release_path.join(&path.file_name().unwrap())).unwrap();
            }
        }
    }
}

今回は cargo:rustc-link-search=native= を指定して、プロジェクトルート以下の lib フォルダを参照するように設定しています。
vcpkg\installed\x64-windows\lib をフルパスで指定しても問題ないと思います。

更に、targetフォルダがある場合に dll フォルダ以下の DLL ファイルを全て debug、release フォルダにコピーするように設定しています。
こちらも、DLLフォルダはフルパスで vcpkd 以下を指定してもいいと思います。

GitHub にプロジェクトがありますので、必要な方はどうぞ。
https://github.com/sou1ka/tesseract_rust

Rustのビルド時にC++のソースも一緒にビルドしてFFIする方法もできるとは思いますが、Tesseract の構成が中々重たいので今回はvcpkg経由で試してみました。

参考

0
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
4