Partilhar via


Introdução ao Reconhecimento de Texto (OCR) no SDK de Aplicativos Windows

Importante

Esta funcionalidade ainda não está disponível. Espera-se que seja lançado em uma próxima versão do canal experimental do SDK de Aplicações do Windows.

O SDK de Aplicativos Windows canal experimental inclui APIs e recursos em estágios iniciais de desenvolvimento. Todas as APIs no canal experimental estão sujeitas a extensas revisões e alterações significativas e podem ser removidas de versões subsequentes a qualquer momento. Eles não são suportados para uso em ambientes de produção e os aplicativos que usam recursos experimentais não podem ser publicados na Microsoft Store.

O reconhecimento de texto, também conhecido como reconhecimento ótico de caracteres (OCR), será suportado pelo do SDK de aplicativos Windows por meio de um conjunto de APIs apoiadas por inteligência artificial (IA) que podem detetar e extrair texto em imagens e convertê-lo em fluxos de caracteres legíveis por máquina.

Essas APIs podem identificar caracteres, palavras, linhas, limites de texto poligonal e fornecer níveis de confiança para cada correspondência. Eles também são suportados exclusivamente pela aceleração de hardware em dispositivos com uma unidade de processamento neural (NPU), tornando-os mais rápidos e precisos do que as APIs herdadas do Windows.Media.Ocr.OcrEngine no SDK da plataforma Windows .

Para obter detalhes da API, consulte referência da API para Reconhecimento de Texto com suporte de IA (OCR) no Windows App SDK.

Dica

Forneça feedback sobre estas APIs e suas funcionalidades, criando uma nova questão de no repositório GitHub do Windows App SDK. (Certifique-se de incluir OCR no título!)

Pré-requisitos

  • CoPilot+ PCs contendo um processador Qualcomm Snapdragon® X Elite.

O que posso fazer com o SDK de Aplicativos Windows e o Reconhecimento de Texto de IA?

Use os novos recursos de Reconhecimento de Texto do AI no SDK do Aplicativo Windows para identificar e reconhecer texto em uma imagem. Você também pode obter os limites do texto e as pontuações de confiança para o texto reconhecido.

Criar um ImageBuffer a partir de um arquivo

Neste exemplo, chamamos uma função LoadImageBufferFromFileAsync para obter um ImageBuffer de um arquivo de imagem.

Na função LoadImageBufferFromFileAsync, concluímos as seguintes etapas:

  1. Crie um objeto StorageFile a partir do caminho de arquivo especificado.
  2. Abra um fluxo no StorageFile usando OpenAsync.
  3. Crie um BitmapDecoder para o fluxo.
  4. Chame GetSoftwareBitmapAsync no decodificador de bitmap para obter um SoftwareBitmap objeto.
  5. Retorne um buffer de imagem a 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);
}

Reconhecer texto em uma imagem bitmap

O exemplo a seguir mostra como reconhecer algum texto em um objeto SoftwareBitmap como um único valor de cadeia de caracteres:

  1. Crie um objeto TextRecognizer através de uma chamada para a função EnsureModelIsReady, que também confirma que existe um modelo de linguagem presente no sistema.
  2. Usando o bitmap obtido no trecho anterior, chamamos a função RecognizeTextFromSoftwareBitmap.
  3. Invoque CreateBufferAttachedToBitmap no ficheiro de imagem para obter um ImageBuffer objeto.
  4. Chame RecognizeTextFromImage para obter o texto reconhecido do ImageBuffer.
  5. Crie um objeto wstringstream e carregue-o com o texto reconhecido.
  6. Retorne a cadeia de caracteres.

Observação

A função EnsureModelIsReady é usada para verificar o estado de prontidão do modelo de reconhecimento de texto (e instalá-lo, se necessário).

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

Obtenha limites de palavras e níveis de confiança

Aqui mostramos como visualizar o BoundingBox de cada palavra em um objeto SoftwareBitmap como uma coleção de polígonos codificados por cores em um elemento Grid .

Observação

Neste exemplo, assumimos que um objeto TextRecognizer já foi criado e passado para a função.

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

Recursos adicionais

acessar arquivos e pastas com o SDK do Windows App e APIs do WinRT