Condividi tramite


Introduzione al riconoscimento del testo (OCR) nel SDK per app di Windows

Suggerimento

Fornire commenti e suggerimenti su queste API e sulle relative funzionalità creando un nuovo problema nel repository GitHub SDK per app di Windows. Assicurarsi di includere OCR nel titolo.

Il riconoscimento del testo, noto anche come riconoscimento ottico dei caratteri (OCR), sarà supportato dal SDK per app di Windows tramite un set di API basate sull'intelligenza artificiale (AI) che possono rilevare ed estrarre testo all'interno delle immagini e convertirlo in flussi di caratteri leggibili dal computer.

Queste API possono identificare caratteri, parole, linee, limiti di testo poligono e fornire livelli di confidenza per ogni corrispondenza. Sono supportate esclusivamente dall'accelerazione hardware nei dispositivi con un'unità di elaborazione neurale (NPU), rendendole più veloci e accurate rispetto alle API Legacy di Windows.Media.Ocr.OcrEngine in Windows Platform SDK.

Per informazioni dettagliate sull'API, vedere Riferimento API per il riconoscimento del testo basato su intelligenza artificiale (OCR) nel SDK per app di Windows.

Importante

Questa funzionalità non è ancora disponibile. È previsto che venga fornito in una prossima versione sperimentale del canale di SDK per app di Windows.

Il canale sperimentale SDK per app di Windows include API e funzionalità nelle fasi iniziali dello sviluppo. Tutte le API nel canale sperimentale sono soggette a revisioni estese e modifiche di rilievo e possono essere rimosse dalle versioni successive in qualsiasi momento. Non sono supportate per l'uso in ambienti di produzione e le app che usano funzionalità sperimentali non possono essere pubblicate in Microsoft Store.

Prerequisiti

  • Pc CoPilot+ contenenti un processore Qualcomm Eseguion® X Elite.

Cosa posso fare con il riconoscimento del testo di SDK per app di Windows e intelligenza artificiale?

Usare le nuove funzionalità di riconoscimento del testo di intelligenza artificiale nel SDK per app di Windows per identificare e riconoscere il testo in un'immagine. È anche possibile ottenere i limiti del testo e i punteggi di attendibilità per il testo riconosciuto.

Creare un oggetto ImageBuffer da un file

In questo esempio viene chiamata una LoadImageBufferFromFileAsync funzione per ottenere imageBuffer da un file di immagine.

Nella funzione LoadImageBufferFromFileAsync vengono completati i passaggi seguenti:

  1. Creare un oggetto StorageFile dal percorso del file specificato.
  2. Aprire un flusso in StorageFile usando OpenAsync.
  3. Creare un oggetto BitmapDecoder per il flusso.
  4. Chiama GetSoftwareBitmapAsync nel decodificatore bitmap per ottenere un oggetto SoftwareBitmap .
  5. Restituisce un buffer di immagini da 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);
}

Riconoscere il testo in un'immagine bitmap

L'esempio seguente illustra come riconoscere un testo in un oggetto SoftwareBitmap come un singolo valore stringa:

  1. Creare un oggetto TextRecognizer tramite una chiamata alla EnsureModelIsReady funzione , che conferma anche che nel sistema è presente un modello linguistico.
  2. Usando la bitmap ottenuta nel frammento precedente, chiamiamo la RecognizeTextFromSoftwareBitmap funzione .
  3. Chiama CreateBufferAttachedToBitmap nel file di immagine per ottenere un oggetto ImageBuffer .
  4. Chiama RecognizeTextFromImage per ottenere il testo riconosciuto da ImageBuffer.
  5. Creare un oggetto wstringstream e caricarlo con il testo riconosciuto.
  6. Restituire la stringa.

Nota

La EnsureModelIsReady funzione viene usata per controllare lo stato di idoneità del modello di riconoscimento del testo (e installarlo, se necessario).

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

Ottenere limiti di parola e confidenza

Qui viene illustrato come visualizzare il BoundingBox di ogni parola in un oggetto SoftwareBitmap come raccolta di poligoni codificati a colori in un elemento Grid.

Nota

Per questo esempio si presuppone che sia già stato creato un oggetto TextRecognizer e passato alla funzione.

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

Risorse aggiuntive

Accedere a file e cartelle con Windows App SDK e API WinRT