vcpkg+Qt5+tesseract+Visual Studio 2022 でのOCR読取
意外とすんなりできたので記事にします。
今回の目標
OCR読取をオープンソースライブラリで記述してみる
事前準備
tesseractデータを取得すること
git clone https://github.com/tesseract-ocr/tessdata
サンプルコード
CMakeList.txt
# CMakeList.txt : CMakeSample の CMake プロジェクト。ソースを含めて、次を定義します:
# プロジェクト専用ロジックはこちらです。
#
cmake_minimum_required(VERSION 3.10)
# Vcpkg toolchain file
set(CMAKE_TOOLCHAIN_FILE "${CMAKE_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake" CACHE STRING "Vcpkg toolchain file")
# C++標準の設定
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Qt5パッケージの検索
find_package(Qt5 COMPONENTS Core Widgets REQUIRED)
find_package(Tesseract CONFIG REQUIRED)
# ソースファイルの追加
set(SOURCES
CMakeSample.cpp
CMakeSample.h
)
# ソースをこのプロジェクトの実行可能ファイルに追加します。
add_executable (CMakeSample ${SOURCES})
# Qt5ライブラリのリンク
target_link_libraries(CMakeSample PRIVATE Qt5::Core Qt5::Widgets Tesseract::libtesseract)
if (CMAKE_VERSION VERSION_GREATER 3.12)
set_property(TARGET CMakeSample PROPERTY CXX_STANDARD 20)
endif()
# TODO: テストを追加し、必要な場合は、ターゲットをインストールします。
ソースコード
// CMakeSample.cpp : アプリケーションのエントリ ポイントを定義します。
//
//
#include "CMakeSample.h"
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QLabel>
#include <QVBoxLayout>
#include <QFileDialog>
#include <QImage>
#include <QPixmap>
#include <tesseract/baseapi.h>
#include <leptonica/allheaders.h>
#ifdef _WIN32
#define setenv(var, value, overwrite) _putenv_s(var, value)
#endif
void performOCR(const QString& imagePath, QLabel* resultLabel) {
tesseract::TessBaseAPI tess;
if (tess.Init(nullptr, "eng")) {
resultLabel->setText("Tesseractの初期化に失敗しました");
return;
}
Pix* image = pixRead(imagePath.toStdString().c_str());
tess.SetImage(image);
char* outText = tess.GetUTF8Text();
resultLabel->setText(outText);
tess.End();
pixDestroy(&image);
}
int main(int argc, char* argv[]) {
QApplication app(argc, argv);
// 環境変数を設定
#ifdef _WIN32
std::string currentPath = std::filesystem::current_path().string() + "\\..\\..\\..\\..\\tessdata\\";
#else
std::string currentPath = std::filesystem::current_path().string() + "/tessdata/";
#endif
setenv("TESSDATA_PREFIX", currentPath.c_str(), 1);
QWidget window;
window.setWindowTitle("OCR Sample");
window.setFixedSize(400, 300);
QVBoxLayout* layout = new QVBoxLayout(&window);
QLabel* imageLabel = new QLabel(&window);
imageLabel->setFixedSize(200, 200);
layout->addWidget(imageLabel);
QPushButton* button = new QPushButton("画像を選択", &window);
layout->addWidget(button);
QLabel* resultLabel = new QLabel(&window);
layout->addWidget(resultLabel);
QObject::connect(button, &QPushButton::clicked, [&]() {
QString imagePath = QFileDialog::getOpenFileName(&window, "画像を選択", "", "画像ファイル (*.png *.jpg *.bmp)");
if (!imagePath.isEmpty()) {
QImage image(imagePath);
imageLabel->setPixmap(QPixmap::fromImage(image).scaled(imageLabel->size(), Qt::KeepAspectRatio));
performOCR(imagePath, resultLabel);
}
});
window.show();
return app.exec();
}
注意点
ファイル選択時のパスに日本語があると文字変換に失敗して読み取れないこと