Compartir a través de


Introducción al reconocimiento de texto (OCR) en el SDK de Aplicaciones para Windows

Importante

Esta característica aún no está disponible. Se espera que se envíe en una próxima versión experimental del canal de la SDK de Aplicaciones para Windows.

El canal experimental del SDK de Aplicaciones para Windows incluye API y características que se encuentran en las primeras fases del desarrollo. Todas las API del canal experimental están sujetas a revisiones exhaustivas y cambios importantes y se pueden eliminar de versiones posteriores en cualquier momento. No son compatibles para el uso en entornos de producción, y las aplicaciones que utilizan las características experimentales no se pueden publicar en Microsoft Store.

El reconocimiento de texto, también conocido como reconocimiento óptico de caracteres (OCR), será compatible con el SDK de Aplicaciones para Windows a través de un conjunto de API respaldadas por inteligencia artificial (AI) que pueden detectar y extraer texto dentro de imágenes y convertirlos en secuencias de caracteres legibles por máquina.

Estas API pueden identificar caracteres, palabras, líneas, límites de texto poligonal y proporcionar niveles de confianza para cada coincidencia. También son compatibles exclusivamente con la aceleración de hardware en dispositivos con una unidad de procesamiento neuronal (NPU), lo que las hace más rápidas y precisas que las API de Windows.Media.Ocr.OcrEngine heredadas en el SDK de la plataforma Windows.

Para obtener más información sobre la API, consulte Referencia de API para reconocimiento de texto con respaldo de IA (OCR) en el SDK de Aplicaciones para Windows.

Sugerencia

Proporcione comentarios sobre estas API y su funcionalidad mediante la creación de un nuevo problema en el repositorio de GitHub de SDK de Aplicaciones para Windows. (Asegúrese de incluir OCR en el título).

Requisitos previos

  • Equipos CoPilot+ que contienen un procesador Qualcomm Snap® X Elite.

¿Qué puedo hacer con el SDK de Aplicaciones para Windows y el reconocimiento de texto de IA?

Use las características de reconocimiento de texto de IA en el SDK de Aplicaciones para Windows para identificar y reconocer texto en una imagen. También puede obtener los límites de texto y las puntuaciones de confianza del texto reconocido.

Creación de un elemento ImageBuffer a partir de un archivo

En este ejemplo, llamamos a una función LoadImageBufferFromFileAsync para obtener un elemento ImageBuffer de un archivo de imagen.

En la función LoadImageBufferFromFileAsync, se completan los pasos siguientes:

  1. Cree un objeto StorageFile a partir de la ruta de acceso del archivo especificada.
  2. Abra una secuencia en StorageFile mediante OpenAsync.
  3. Cree un elemento BitmapDecoder de la secuencia.
  4. Llame a GetSoftwareBitmapAsync en el decodificador de mapa de bits para obtener un objeto SoftwareBitmap.
  5. Devuelva un búfer de imagen 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);
}

Reconocimiento de texto en una imagen de mapa de bits

En el siguiente ejemplo se muestra cómo reconocer texto en un objeto SoftwareBitmap como un valor de cadena único:

  1. Cree un objeto TextRecognizer a través de una llamada a la función EnsureModelIsReady, que también confirmará que haya un modelo de lenguaje presente en el sistema.
  2. Con el mapa de bits que ha obtenido en el fragmento de código anterior, llame a la función RecognizeTextFromSoftwareBitmap.
  3. Llame a CreateBufferAttachedToBitmap en el archivo de imagen para obtener un objeto ImageBuffer.
  4. Llame a RecognizeTextFromImage para obtener el texto reconocido de ImageBuffer.
  5. Cree un objeto wstringstream y cárguelo con el texto reconocido.
  6. Devuelva la cadena.

Nota:

La función EnsureModelIsReady se usa para comprobar el estado de preparación del modelo de reconocimiento de texto (e instalarlo si es necesario).

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

Obtención de límites de palabras y confianza

Aquí se muestra cómo visualizar el BoundingBox de cada palabra en un objeto SoftwareBitmap como una colección de polígonos codificados por colores en un elemento Grid.

Nota:

En este ejemplo se supone que ya se ha creado un objeto TextRecognizer y se ha pasado a la función.

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 adicionales

Acceso a archivos y carpetas con SDK de Aplicaciones para Windows y API de WinRT