Help us understand the problem. What is going on with this article?

Windows Native C++でWinRTのOCR APIを使う方法

はじめに

こんにちは。Daddy's Officeの市川です。

私が10年以上開発を続けているWindowsPCを監視カメラシステムにする「LiveCapture3」。
先日、このソフトにOCR機能を追加して、カメラ映像内の数値を検出できるようにしました。
(この機能により、サーマルカメラを使用した自動温度計測&通知システムの構築が可能です)

「LiveCapture3」のコア機能はC++で実装しているので、C++でOCR機能を実装する必要がありました。
C++でのOCRといえば、「Tesseract」が有名ですが、今回は画像内の数値のみ検出すればよく、そこまで大掛かりにしたくありませんでした。

そこでWindowsのAPIを調べたところ、ありました!
Windows.Media.Ocr

しかし、よくよく見てみると、これはWinRTっぽい感じ。
つまり、UWPアプリやストアアプリであれば使えるのですが、デスクトップアプリから使うにはちょっと細工が必要そうです。

ということで

  • WinRTのWindows.Media.Ocrを.NetFrameworkのC#で使えるようにする
  • 上記のC# .NetFrameworkモジュールをC++から使えるようにする

という2段階で実装しました。

WinRTのWindows.Media.Ocrを.NetFrameworkで使う

言語としてはどちらもC#なので、参照を追加できれば基本はOKです。

まず、.NetFrameworkのクラスライブラリとしてプロジェクトを生成します。

OCRを使用する為には、下記のUWPライブラリが必要です。

  • Windows.Media.Ocr
  • Windows.Storage.Streams
  • Windows.Graphics.Imaging

これらを使えるようにするために、プロジェクトの参照で、直接ライブラリを追加します。
参照.jpg

追加するのは下記の2つです。

名前 パス
Windows.Foundation.UniversalApiContract C:\Program Files (x86)\Windows Kits\10\References\10.0.18362.0\Windows.Foundation.UniversalApiContract\8.0.0.0\Windows.Foundation.UniversalApiContract.winmd
Windows.Foundation.FoundationContract C:\Program Files (x86)\Windows Kits\10\References\10.0.18362.0\Windows.Foundation.FoundationContract\3.0.0.0\Windows.Foundation.FoundationContract.winmd

これで、準備はできました。

OCRエンジンの使い方は非常に簡単で、画像を渡すと認識結果の文字列が返却されるというものです。

using Windows.Graphics.Imaging;
using Windows.Media.Ocr;
using Windows.Storage.Streams;

async Task<OcrResult> detect(SoftwareBitmap bitmap)
{
     var ocrEngine = OcrEngine.TryCreateFromUserProfileLanguages();
     var ocrResult = await ocrEngine.RecognizeAsync(bitmap);
     return ocrResult;
}

ただ、面倒くさいのが

  • 引数の画像はSoftwareBitmap(WinRT)を使う必要がある
  • WinRTのAsyncは、デスクトップのasync/awaitとは違う形式になっている

というところを解決しないといけません。

色々調べた結果、以下に素晴らしい説明がありました!

Microsoft OCR をデスクトップのWFPアプリで動かす方法

参照追加の方法がちょっと違いますが、実装コードはこのまま行けました!

.NetFrameworkライブラリをC++からコールする

これは、以前私が投稿した下記のやり方で行います。

既存のC++ネイティブプロジェクトでC#マネージドコードを使う

これで、Native C++からWinRT用のOCR APIをコールしてOCR機能を実現することができました!

ソースコード

ソースコード一式(VisualStudio2019)はこちらに置いておきます。

ソースコード一式

参考

Microsoft OCR をデスクトップのWFPアプリで動かす方法
既存のC++ネイティブプロジェクトでC#マネージドコードを使う

Yukio-Ichikawa
Daddy's Office代表 Windowsアプリケーション、クラウドアプリケーション、スマホアプリケーション開発を行っています。
https://lc3.daddysoffice.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした