Partager via


Prise en main de la reconnaissance de texte (OCR) dans le Kit de développement logiciel (SDK) d’application Windows

Important

Cette fonctionnalité n’est pas encore disponible. Il devrait être fourni dans une prochaine version de canal expérimental du Kit de développement logiciel (SDK) d’application Windows.

Le canal expérimental du SDK d’application Windows comprend des API et des fonctionnalités qui en sont aux premières phases de 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. Elles ne sont pas prises en charge dans les environnements de production et les applications qui utilisent des fonctionnalités expérimentales ne peuvent pas être publiées dans Microsoft Store.

La reconnaissance de texte, également appelée reconnaissance optique de caractères (OCR), sera 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 plus d’informations sur l’API, consultez la référence d’API pour la reconnaissance de texte basée sur l’IA (OCR) dans le Kit de développement logiciel (SDK) d’application Windows.

Conseil

Fournissez des commentaires sur ces API et leurs fonctionnalités en créant un nouveau problème dans le dépôt GitHub du SDK d’application Windows. (Assurez-vous d’inclure l’OCR dans le titre !)

Prérequis

  • Pc CoPilot+ contenant un processeur Snap xeon X Elite d’Instance de Snapend®.

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