Tesseract のインストール方法
1. Tesseract の github のページ からダウンロードする。

2. tesseract-ocr-w64-setup-5.5.0.20241111.exe を起動する。

3. Language は English を選択する。

4. Addtional script data を開いて Japanese を含むチェックを True にする。Addtional language data も同様。

それに加えて Addtional language data > Math equation module にもチェックした。

5. Do not create shortcuts にチェックを入れる。

6. インストールが完了したら環境変数の Path に C:\Program Files\Tesseract-OCR を追加する。

Tesseract の動作確認
Tesseract がインストールされたか cmd から確認します。
tesseract --vesion と打って、以下のようになればインストールされています。

Tesseract の .dll はインストールされましたが、ヘッダーファイルや .lib ファイルがまだインストールされていない為
以下で vcpkg を導入して開発向けの Teserract をインストールします。
vcpkg を導入する
cmd で以下を実行する。私は cドライブに移動してからコマンドを実行しました。
cd c:\ git clone https://github.com/microsoft/vcpkg cd vcpkg .\bootstrap-vcpkg.bat
これで c:\vcpkg\vcpkg.exe ができる
vcpkg を使って Tesseract をインストール
以下のコマンドで実行できます。
vcpkg install tesseract:x64-windows
スナップショットを取っていないが、私は"vcpkg を使って Tesseract をインストール"を失敗した。
vcpkg を git pull して再度インストールしたら成功した。成功すると緑色の文字で成功したという意のメッセージが表示されたと記憶している。
インストールが完了したら、環境変数の Path に C:\vcpkg\installed\x64-windows\bin を追加してください。

MFC Application(Dialog Based) による Sample Program
1. SampleTesseract という名前で MFC の Dailog Based を作成する。
2. 後はいつも通りです。
ヘッダーの設定、.libフォルダの指定, lib ファイルの指定(tesseract55.lib, leptonica-1.85.0.lib)をしてください。
3. .h, .cpp にのコードを載せておきます。
// SampleTesseractDlg.h : header file // #pragma once #include <tesseract/baseapi.h> #include <leptonica/allheaders.h> // CSampleTesseractDlg dialog class CSampleTesseractDlg : public CDialogEx { // Construction public: CSampleTesseractDlg(CWnd* pParent = nullptr); // standard constructor // Dialog Data #ifdef AFX_DESIGN_TIME enum { IDD = IDD_SAMPLETESSERACT_DIALOG }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support // Implementation protected: HICON m_hIcon; // Generated message map functions virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); DECLARE_MESSAGE_MAP() };
BOOL CSampleTesseractDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != nullptr) { BOOL bNameValid; CString strAboutMenu; bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); ASSERT(bNameValid); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here // OCR対象画像のパス const char* imagePath = "sample.png"; // Leptonicaで画像を読み込む Pix* image = pixRead(imagePath); if (!image) { AfxMessageBox(_T("画像の読み込みに失敗しました")); return FALSE; } // Tesseract OCRエンジンの初期化(英語) //tesseract::TessBaseAPI ocr; tesseract::TessBaseAPI* api = new tesseract::TessBaseAPI(); if (api->Init("C:\\Program Files\\Tesseract-OCR\\tessdata", "eng")) { AfxMessageBox(_T("Failed to initialize Tesseract.")); pixDestroy(&image); return FALSE; } // OCR対象画像を設定 api->SetImage(image); api->Recognize(0); tesseract::ResultIterator* ri = api->GetIterator(); tesseract::PageIteratorLevel level = tesseract::RIL_SYMBOL; if (ri != 0) { do { const char* word = ri->GetUTF8Text(level); float conf = ri->Confidence(level); int x1, y1, x2, y2; ri->BoundingBox(level, &x1, &y1, &x2, &y2); CStringW wstrWord(CA2W(word, CP_UTF8)); // UTF-8 → UTF-16(Unicode) TRACE(_T("word: '%s'; \tconf: %.2f; BoundingBox: %d,%d,%d,%d;\n"), wstrWord.GetString(), conf, x1, y1, x2, y2); } while (ri->Next(level)); } //// テキスト抽出 //char* outText = api->GetUTF8Text(level); // Tesseract が返す char* // 後処理 api->End(); //delete api; // <- ここですら落ちる //delete[] outText; // ✅ Tesseract が malloc した領域を解放 <- これでエラーが発生する api->End() で開放するので pixDestroy(&image); return TRUE; // return TRUE unless you set the focus to a control }
注意
下から2,3行目は敢えてコメントアウトしています。そうしないと自分の環境では落ちたので。
Googleで検索すると delete outText はすべきでないと言われ、Copilot は削除すべきと言ってきます・とりあえず落ちないようにしています。
Tesseract のサンプルコードでも delete outText;していますが、落ちます。delete して落ちる原因がわかる人は是非コメントで教えてください。
私の場合、api はそもそも new しないので delete しないし、outText が仮にメモリリークしたとしても高々文字列なので、アプリの開発に関しては影響ないと考え、本件に関してこれ以上調べるのをやめました。
実際に動かした例

上の画像を上記のコードで動かすと、以下のようなログが出力されます。

私のコードは一文字の場所を調べるコードですが、まとめて文字列を取得することもできます。
Tesseract のサンプルコードが参考になります。