Partager via


Premiers pas avec la reconnaissance de texte par intelligence artificielle (OCR) dans le SDK d'application Windows

Important

Disponible dans la dernière version de la chaîne expérimentale du SDK d’applications Windows.

Le canal expérimental du Kit de développement logiciel (SDK) d’application Windows inclut des API et des fonctionnalités au début du développement. Toutes les API du canal expérimental font l’objet de révisions approfondies et de changements cassants et peuvent être supprimées des versions ultérieures à tout moment. Les fonctionnalités expérimentales ne sont pas prises en charge pour une utilisation dans les environnements de production et les applications qui les utilisent ne peuvent pas être publiées dans le Microsoft Store.

  • Les applications non empaquetées ne sont pas prises en charge.

La reconnaissance de texte, également appelée reconnaissance optique de caractères (OCR), est prise en charge par le SDK d’application Windows par le biais d’un ensemble d’API d’intelligence artificielle (IA) qui peuvent détecter et extraire du texte dans des images et les convertir en flux de caractères lisibles par ordinateur.

Ces API peuvent identifier des caractères, des mots, des lignes, des limites de texte polygonal et fournir des niveaux de confiance pour chaque correspondance. Ils sont également pris en charge exclusivement par l’accélération matérielle dans les appareils avec une unité de traitement neuronale (NPU), ce qui les rend plus rapides et plus précis que les API Windows.Media.Ocr.OcrEngine héritées dans le SDK de plateforme Windows.

Pour les détails de l'API , consultez la référence de l'API pour la reconnaissance de texte (OCR) dans le SDK (Kit de développement logiciel) d'application Windows.

Conseil

Fournissez des commentaires sur ces API et leurs fonctionnalités en créant un nouveau problème dans le référentiel GitHub du Kit de développement logiciel (SDK) d’application Windows (inclure ocr dans le titre) ou en répondant à un problème existant.

Prérequis

Que puis-je faire avec le SDK d’application Windows et la reconnaissance de texte d’IA ?

Utilisez les nouvelles fonctionnalités de reconnaissance de texte d’IA fournies avec le SDK d’application Windows pour identifier et reconnaître du texte dans une image. Vous pouvez également obtenir les délimitations du texte et les scores de confiance pour le texte reconnu.

Créer un ImageBuffer à partir d’un fichier

Dans cet exemple, nous appelons une fonction LoadImageBufferFromFileAsync pour obtenir un ImageBuffer à partir d’un fichier image.

Dans la fonction LoadImageBufferFromFileAsync, nous effectuons les étapes suivantes :

  1. Créez un objet StorageFile à partir du chemin d’accès de fichier spécifié.
  2. Ouvrez un flux sur StorageFile à l’aide d’OpenAsync.
  3. Créez un BitmapDecoder pour le flux.
  4. Appelez GetSoftwareBitmapAsync sur le décodeur d’image bitmap pour obtenir un objet SoftwareBitmap.
  5. Renvoyez une mémoire tampon d’image à partir de 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);
}

Reconnaître du texte dans une image bitmap

L’exemple suivant montre comment reconnaître du texte dans un objet SoftwareBitmap en tant que valeur de chaîne unique en procédant comme suit :

  1. Créez un objet TextRecognizer via un appel à la fonction EnsureModelIsReady, qui confirme également qu’un modèle de langage est présent sur le système.
  2. À l’aide de l’image bitmap obtenue dans l’extrait de code précédent, nous appelons la fonction RecognizeTextFromSoftwareBitmap.
  3. Appelez CreateBufferAttachedToBitmap sur le fichier image pour obtenir un objet ImageBuffer.
  4. Appelez RecognizeTextFromImage pour obtenir le texte reconnu à partir d’ImageBuffer.
  5. Créez un objet wstringstream et chargez-le avec le texte reconnu.
  6. Retourne la chaîne.

Remarque

La fonction EnsureModelIsReady est utilisée pour vérifier l’état de préparation du modèle de reconnaissance de texte (et l’installer si nécessaire).

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

Obtenir les limites de mots et la confiance

Ici, nous montrons comment visualiser les BoundingBox de chaque mot dans un objet SoftwareBitmap sous la forme d’une collection de polygones codés en couleur sur un élément Grid.

Remarque

Pour cet exemple, nous supposons qu’un objet TextRecognizer a déjà été créé et transmis à la fonction.

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

Ressources supplémentaires

Accéder aux fichiers et dossiers avec le SDK d’application Windows et les API WinRT