Delen via


Aan de slag met Tekstherkenning (OCR) in de Windows App SDK

Belangrijk

Deze functie is nog niet beschikbaar. Het wordt verwacht uitgebracht te worden in een binnenkort verwachte release van het experimentele kanaal van de Windows App SDK.

De Windows App SDK experimenteel kanaal bevat API's en functies in vroege ontwikkelingsfasen. Alle API's in het experimentele kanaal zijn onderhevig aan uitgebreide revisies en ingrijpende wijzigingen en kunnen op elk moment uit toekomstige releases worden verwijderd. Ze worden niet ondersteund voor gebruik in productieomgevingen en apps die gebruikmaken van experimentele functies kunnen niet worden gepubliceerd naar de Microsoft Store.

Tekstherkenning, ook wel optische tekenherkenning (OCR) genoemd, wordt ondersteund door de Windows App SDK via een set ai-ondersteunde API's (kunstmatige intelligentie) waarmee tekst in afbeeldingen kan worden gedetecteerd en geëxtraheerd en geconverteerd naar machineleesbare tekenstromen.

Deze API's kunnen tekens, woorden, regels, veelhoekige tekstgrenzen identificeren en betrouwbaarheidsniveaus bieden voor elke overeenkomst. Ze worden ook uitsluitend ondersteund door hardwareversnelling in apparaten met een NPU (neurale verwerkingseenheid), waardoor ze sneller en nauwkeuriger zijn dan de verouderde Windows.Media.Ocr.Ocr.OcrEngine-API's in de Windows-platform-SDK.

Zie voor API-details API-ref voor AI-ondersteunde tekstherkenning (OCR) in de Windows App SDK.

Tip

Geef feedback over deze API's en hun functionaliteit door een nieuw probleem te maken in de GitHub-opslagplaats van de Windows App SDK. (Zorg ervoor dat u OCR- in de titel opneemt!)

Voorwaarden

Wat kan ik doen met de Windows App SDK en AI Text Recognition?

Gebruik de nieuwe AI Text Recognition-functies in de Windows App SDK om tekst in een afbeelding te identificeren en te herkennen. U kunt ook de tekstgrenzen en betrouwbaarheidsscores voor de herkende tekst ophalen.

Een ImageBuffer maken op basis van een bestand

In dit voorbeeld roepen we een LoadImageBufferFromFileAsync-functie aan om een ImageBuffer- op te halen uit een afbeeldingsbestand.

In de functie LoadImageBufferFromFileAsync voeren we de volgende stappen uit:

  1. Maak een StorageFile-object op basis van het opgegeven bestandspad.
  2. Open een stream in het StorageFile met behulp van OpenAsync-.
  3. Maak een BitmapDecoder- voor de stream.
  4. Roep GetSoftwareBitmapAsync- aan op de bitmapdecoder om een SoftwareBitmap--object op te halen.
  5. Retourneert een afbeeldingsbuffer van 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);
}

Tekst herkennen in een bitmapafbeelding

In het volgende voorbeeld ziet u hoe u tekst in een SoftwareBitmap object herkent als één tekenreekswaarde:

  1. Maak een TextRecognizer-object via een aanroep naar de EnsureModelIsReady-functie, waarmee ook wordt bevestigd dat er een taalmodel aanwezig is op het systeem.
  2. Met behulp van de bitmap die u in het vorige fragment hebt verkregen, roepen we de RecognizeTextFromSoftwareBitmap functie aan.
  3. Roep CreateBufferAttachedToBitmap aan in het afbeeldingsbestand om een ImageBuffer--object op te halen.
  4. Roep RecognizeTextFromImage- aan om de herkende tekst op te halen uit de ImageBuffer-.
  5. Maak een wstringstream-object en laad het met de herkende tekst.
  6. Retourneer de tekenreeks.

Notitie

De functie EnsureModelIsReady wordt gebruikt om de gereedheidsstatus van het tekstherkenningsmodel te controleren (en indien nodig te installeren).

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();
}

Woordgrenzen en zekerheidsniveau ophalen

Hier laten we zien hoe u de BoundingBox van elk woord in een SoftwareBitmap-object kunt visualiseren als een verzameling kleurgecodeerde veelhoeken op een Raster-element.

Notitie

In dit voorbeeld wordt ervan uitgegaan dat er al een TextRecognizer--object is gemaakt en doorgegeven aan de functie.

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);
        }
    }
}

Aanvullende informatiebronnen

Toegang tot bestanden en mappen met Windows App SDK en WinRT-API's