Compartilhar via


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

Importante

Esse recurso ainda não está disponível. Espera-se que ele seja enviado em uma próxima versão de canal experimental do SDK do Aplicativo Windows.

O canal experimental do SDK do Aplicativo Windows 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 interruptivas, podendo ser removidas de versões subsequentes a qualquer momento. Elas não são compatíveis com o uso em ambientes de produção e os aplicativos que usam os recursos experimentais não podem ser publicados na Microsoft Store.

O reconhecimento de texto, também conhecido como OCR (reconhecimento óptico de caracteres), será compatível com o SDK do Aplicativo Windows por meio de um conjunto de APIs com suporte de IA (inteligência artificial) que podem detectar 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 poligonais 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 NPU (unidade de processamento neural), tornando-os mais rápidos e precisos do que as APIs Windows.Media.Ocr.OcrEngine herdadas no SDK da plataforma Windows.

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

Dica

Forneça comentários sobre essas APIs e sua funcionalidade criando um novo Problema no repositório GitHub SDK do Aplicativo Windows. (Certifique-se de incluir OCR no título!)

Pré-requisitos

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

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

Use os novos recursos de Reconhecimento de Texto de IA do SDK do Aplicativo Windows para identificar e reconhecer texto em uma imagem. Você também pode obter os limites de 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 a partir do fluxo.
  4. Chame GetSoftwareBitmapAsync no decodificador de bitmap para obter um objeto SoftwareBitmap.
  5. Retornar um buffer de imagem 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 de bitmap

O seguinte exemplo mostra como reconhecer texto em um objeto SoftwareBitmap como um valor de sequência único:

  1. Crie um objeto TextRecognizer por meio de uma chamada à função EnsureModelIsReady, que também confirma que há um modelo de linguagem presente no sistema.
  2. Usando o bitmap obtido no trecho anterior, chamamos a função RecognizeTextFromSoftwareBitmap.
  3. Chame CreateBufferAttachedToBitmap no arquivo de imagem para obter um objeto ImageBuffer.
  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();
}

Obter confiança e limites de palavras

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

Observação

Para este exemplo, suponhamos que um objeto TextRecognizer já tenha sido 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 APIs do WinRT e o SDK do Aplicativo Windows