次の方法で共有


Windows アプリ SDKでのテキスト認識 (OCR) の概要

ヒント

Windows アプリ SDK GitHub リポジトリに新しい Issue を作成して、これらの API とその機能に関するフィードバックを提供します。 (タイトルに OCR を含めるようにしてください!)

光学式文字認識 (OCR) とも呼ばれるテキスト認識は、画像内のテキストを検出して抽出し、コンピューターで読み取り可能な文字ストリームに変換できる人工知能 (AI) に基づく API のセットを通じて、Windows アプリ SDKによってサポートされます。

これらの API は、文字、単語、行、多角形のテキスト境界を識別し、一致ごとに信頼度レベルを提供できます。 また、ニューラル処理ユニット (NPU) を搭載したデバイスでのハードウェア アクセラレーションによってのみサポートされ、 Windows プラットフォーム SDKの従来の Windows.Media.Ocr.OcrEngine API よりも高速かつ正確になります。

API の詳細については、Windows アプリ SDKの「API ref for AI-backed Text Recognition (OCR)」を参照してください。

重要

この機能はまだ使用できません。 Windows アプリ SDKの今後の体験チャネルリリースで出荷される予定です。

Windows アプリ SDK の実験的チャネルには、開発の初期段階にある API と機能が含まれています。 実験用チャネル内のすべての API は、広範な変更と破壊的変更の対象となり、今後のリリースからいつでも削除される可能性があります。 これらは運用環境での使用ではサポートされていません。また、実験的機能を使用するアプリを Microsoft Store に公開することはできません。

前提条件

Windows アプリ SDK と AI テキスト認識でできること

Windows アプリ SDK の 新しい AI テキスト認識機能を使用して、画像内のテキストを識別して認識します。 認識されたテキストのテキストの境界と信頼度スコアを取得することもできます。

ファイルから ImageBuffer を作成する

この例では、画像ファイルから ImageBuffer を取得する LoadImageBufferFromFileAsync 関数を呼び出します。

LoadImageBufferFromFileAsync 関数で、次の手順を実行します。

  1. 指定したファイル パスから StorageFile オブジェクトを作成します。
  2. OpenAsync を使用して StorageFile でストリームを開きます。
  3. ストリームの BitmapDecoder を作成します。
  4. ビットマップ デコーダーの GetSoftwareBitmapAsync を呼び出して、SoftwareBitmap オブジェクトを取得します。
  5. CreateBufferAttachedToBitmap からイメージ バッファーを返します。
using Microsoft.Windows.Vision;
using Microsoft.Windows.Imaging;
using Windows.Graphics.Imaging;
using Windows.Storage;
using Windows.Storage.Streams;

public async Task<ImageBuffer> LoadImageBufferFromFileAsync(string filePath)
{
    StorageFile file = await StorageFile.GetFileFromPathAsync(filePath);
    IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read);
    BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);
    SoftwareBitmap bitmap = await decoder.GetSoftwareBitmapAsync();

    if (bitmap == null)
    {
        return null;
    }

    return ImageBuffer.CreateBufferAttachedToBitmap(bitmap);
}
namespace winrt
{
    using namespace Microsoft::Windows::Vision;
    using namespace Microsoft::Windows::Imaging;
    using namespace Windows::Graphics::Imaging;
    using namespace Windows::Storage;
    using namespace Windows::Storage::Streams;
}

winrt::IAsyncOperation<winrt::ImageBuffer> LoadImageBufferFromFileAsync(
    const std::wstring& filePath)
{
    auto file = co_await winrt::StorageFile::GetFileFromPathAsync(filePath);
    auto stream = co_await file.OpenAsync(winrt::FileAccessMode::Read);
    auto decoder = co_await winrt::BitmapDecoder::CreateAsync(stream);
    auto bitmap = co_await decoder.GetSoftwareBitmapAsync();
    if (bitmap == nullptr) {
        co_return nullptr;
    }
    co_return winrt::ImageBuffer::CreateBufferAttachedToBitmap(bitmap);
}

ビットマップ イメージ内のテキストを認識する

次の例は、次の手順に従って、SoftwareBitmap オブジェクト内のテキストを 1 つの文字列値として認識する方法を示します。

  1. EnsureModelIsReady 関数の呼び出しを通じて TextRecognizer オブジェクトを作成します。これにより、システムに言語モデルが存在することも確認されます。
  2. 前のスニペットで取得したビットマップを使用して、RecognizeTextFromSoftwareBitmap 関数を呼び出します。
  3. ImageBuffer オブジェクトを取得するには、画像ファイルの CreateBufferAttachedToBitmap を呼び出します。
  4. ImageBuffer から認識されたテキストを取得するには、RecognizeTextFromImage を呼び出します。
  5. wstringstream オブジェクトを作成して、認識されたテキストと共に読み込みます。
  6. 文字列を返します。

Note

EnsureModelIsReady 関数は、テキスト認識モデルの準備状態をチェック (および必要に応じてインストール) するために使用します。

using Microsoft.Windows.Vision;
using Microsoft.Windows.Imaging;
using Windows.Graphics.Imaging;
using Windows.Storage;
using Windows.Storage.Streams;

public async Task<string> RecognizeTextFromSoftwareBitmap(SoftwareBitmap bitmap)
{
    TextRecognizer textRecognizer = await EnsureModelIsReady();
    ImageBuffer imageBuffer = ImageBuffer.CreateBufferAttachedToBitmap(bitmap);
    RecognizedText recognizedText = textRecognizer.RecognizeTextFromImage(imageBuffer);
    StringBuilder stringBuilder = new StringBuilder();

    foreach (var line in recognizedText.Lines)
    {
        stringBuilder.AppendLine(line.Text);
    }

    return stringBuilder.ToString();
}

public async Task<TextRecognizer> EnsureModelIsReady()
{
    if (!TextRecognizer.IsAvailable())
    {
        var loadResult = await TextRecognizer.MakeAvailableAsync();
        if (loadResult.Status != PackageDeploymentStatus.CompletedSuccess)
        {
            throw new Exception(loadResult.ExtendedError().Message);
        }
    }

    return await TextRecognizer.CreateAsync();
}
namespace winrt
{
    using namespace Microsoft::Windows::Vision;
    using namespace Microsoft::Windows::Imaging;
    using namespace Windows::Graphics::Imaging;
}

winrt::IAsyncOperation<winrt::TextRecognizer> EnsureModelIsReady();

winrt::IAsyncOperation<winrt::hstring> RecognizeTextFromSoftwareBitmap(winrt::SoftwareBitmap const& bitmap)
{
    winrt::TextRecognizer textRecognizer = co_await EnsureModelIsReady();
    winrt::ImageBuffer imageBuffer = winrt::ImageBuffer::CreateBufferAttachedToBitmap(bitmap);
    winrt::RecognizedText recognizedText = textRecognizer.RecognizeTextFromImage(imageBuffer);
    std::wstringstream stringStream;
    for (const auto& line : recognizedText.Lines())
    {
        stringStream << line.Text().c_str() << std::endl;
    }
    co_return winrt::hstring{stringStream.view()};
}

winrt::IAsyncOperation<winrt::TextRecognizer> EnsureModelIsReady()
{
  if (!winrt::TextRecognizer::IsAvailable())
  {
    auto loadResult = co_await winrt::TextRecognizer::MakeAvailableAsync();
    if (loadResult.Status() != winrt::PackageDeploymentStatus::CompletedSuccess)
    {
        throw winrt::hresult_error(loadResult.ExtendedError());
    }
  }

  co_return winrt::TextRecognizer::CreateAsync();
}

ワード境界と信頼度を取得する

ここでは、Grid 要素上の色分けされた多角形のコレクションとして、SoftwareBitmap オブジェクト内の認識された各単語のBoundingBoxを視覚化する方法を示します。

Note

この例では、TextRecognizer が既に作成されて、関数に渡されていることを前提としています。

using Microsoft.Windows.Vision;
using Microsoft.Windows.Imaging;
using Windows.Graphics.Imaging;
using Windows.Storage;
using Windows.Storage.Streams;

public void VisualizeWordBoundariesOnGrid(
    SoftwareBitmap bitmap,
    Grid grid,
    TextRecognizer textRecognizer)
{
    ImageBuffer imageBuffer = ImageBuffer.CreateBufferAttachedToBitmap(bitmap);
    RecognizedText result = textRecognizer.RecognizeTextFromImage(imageBuffer);

    SolidColorBrush greenBrush = new SolidColorBrush(Microsoft.UI.Colors.Green);
    SolidColorBrush yellowBrush = new SolidColorBrush(Microsoft.UI.Colors.Yellow);
    SolidColorBrush redBrush = new SolidColorBrush(Microsoft.UI.Colors.Red);

    foreach (var line in result.Lines)
    {
        foreach (var word in line.Words)
        {
            PointCollection points = new PointCollection();
            var bounds = word.BoundingBox;
            points.Add(bounds.TopLeft);
            points.Add(bounds.TopRight);
            points.Add(bounds.BottomRight);
            points.Add(bounds.BottomLeft);

            Polygon polygon = new Polygon();
            polygon.Points = points;
            polygon.StrokeThickness = 2;

            if (word.Confidence < 0.33)
            {
                polygon.Stroke = redBrush;
            }
            else if (word.Confidence < 0.67)
            {
                polygon.Stroke = yellowBrush;
            }
            else
            {
                polygon.Stroke = greenBrush;
            }

            grid.Children.Add(polygon);
        }
    }
}
namespace winrt
{
    using namespace Microsoft::Windows::Vision;
    using namespace Microsoft::Windows::Imaging;
    using namespace Micrsooft::Windows::UI::Xaml::Controls;
    using namespace Micrsooft::Windows::UI::Xaml::Media;
    using namespace Micrsooft::Windows::UI::Xaml::Shapes;
}

void VisualizeWordBoundariesOnGrid(
    winrt::SoftwareBitmap const& bitmap,
    winrt::Grid const& grid,
    winrt::TextRecognizer const& textRecognizer)
{
    winrt::ImageBuffer imageBuffer = winrt::ImageBuffer::CreateBufferAttachedToBitmap(bitmap);
    
    winrt::RecognizedText result = textRecognizer.RecognizeTextFromImage(imageBuffer);

    auto greenBrush = winrt::SolidColorBrush(winrt::Microsoft::UI::Colors::Green);
    auto yellowBrush = winrt::SolidColorBrush(winrt::Microsoft::UI::Colors::Yellow);
    auto redBrush = winrt::SolidColorBrush(winrt::Microsoft::UI::Colors::Red);
    
    for (const auto& line : recognizedText.Lines())
    {
        for (const auto& word : line.Words())
        {
            winrt::PointCollection points;
            const auto& bounds = word.BoundingBox();
            points.Append(bounds.TopLeft);
            points.Append(bounds.TopRight);
            points.Append(bounds.BottomRight);
            points.Append(bounds.BottomLeft);

            winrt::Polygon polygon;
            polygon.Points(points);
            polygon.StrokeThickness(2);

            if (word.Confidence() < 0.33)
            {
                polygon.Stroke(redBrush);
            }
            else if (word.Confidence() < 0.67)
            {
                polygon.Stroke(yellowBrush);
            }
            else
            {
                polygon.Stroke(greenBrush);
            }

            grid.Children().Add(polygon);
        }
    }
}

その他のリソース

Windows App SDK と WinRT API を使用してファイルとフォルダーにアクセスする