Bagikan melalui


Pengenalan Teks di SDK Aplikasi Windows

API pengenalan teks Kecerdasan Buatan (AI) baru yang akan dikirim dengan SDK Aplikasi Windows dapat digunakan untuk mengidentifikasi karakter dalam gambar, mengenali kata, garis, batas poligonal, dan memberikan tingkat keyakinan untuk kecocokan yang dihasilkan.

API SDK Aplikasi Windows baru ini lebih cepat dan lebih akurat daripada API Windows.Media.Ocr.OcrEngine warisan di SDK platform Windows dan mendukung akselerasi perangkat keras di perangkat dengan unit pemrosesan neural (NPU).

Penting

Saluran eksperimental SDK Aplikasi Windows mencakup API dan fitur pada tahap awal pengembangan. Semua API di saluran eksperimental tunduk pada revisi yang luas dan melanggar perubahan dan dapat dihapus dari rilis berikutnya kapan saja. Mereka tidak didukung untuk digunakan di lingkungan produksi, dan aplikasi yang menggunakan fitur eksperimental tidak dapat diterbitkan ke Microsoft Store.

Prasyarat

Apa yang dapat saya lakukan dengan pengenalan teks SDK Aplikasi Windows dan AI?

Gunakan fitur Pengenalan Teks AI baru di SDK Aplikasi Windows untuk mengidentifikasi dan mengenali teks dalam gambar. Anda juga bisa mendapatkan batas teks dan skor keyakinan untuk teks yang dikenali.

Membuat ImageBuffer dari file

Dalam contoh ini kita memanggil LoadImageBufferFromFileAsync fungsi untuk mendapatkan ImageBuffer dari file gambar.

Dalam fungsi LoadImageBufferFromFileAsync, kami menyelesaikan langkah-langkah berikut:

  1. Buat objek StorageFile dari jalur file yang ditentukan.
  2. Buka aliran di StorageFile menggunakan OpenAsync.
  3. Buat BitmapDecoder untuk aliran.
  4. Panggil GetSoftwareBitmapAsync pada dekoder bitmap untuk mendapatkan objek SoftwareBitmap .
  5. Mengembalikan buffer gambar dari 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);
}

Mengenali teks dalam gambar bitmap

Contoh berikut menunjukkan cara mengenali beberapa teks dalam objek SoftwareBitmap sebagai nilai string tunggal:

  1. Buat objek TextRecognizer melalui panggilan ke EnsureModelIsReady fungsi, yang juga mengonfirmasi adanya model bahasa pada sistem.
  2. Menggunakan bitmap yang diperoleh di cuplikan sebelumnya, kami memanggil RecognizeTextFromSoftwareBitmap fungsi .
  3. Panggil CreateBufferAttachedToBitmap pada file gambar untuk mendapatkan objek ImageBuffer .
  4. Panggil RecognizeTextFromImage untuk mendapatkan teks yang dikenali dari ImageBuffer.
  5. Buat objek wstringstream dan muat dengan teks yang dikenali.
  6. Mengembalikan string.

Catatan

Fungsi EnsureModelIsReady ini digunakan untuk memeriksa status kesiapan model pengenalan teks (dan menginstalnya jika perlu).

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

Mendapatkan batas kata dan keyakinan

Di sini kami menunjukkan cara memvisualisasikan BoundingBox dari setiap kata dalam objek SoftwareBitmap sebagai kumpulan poligon berkode warna pada elemen Grid.

Catatan

Untuk contoh ini, kami mengasumsikan objek TextRecognizer telah dibuat dan diteruskan ke fungsi .

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

Sumber Daya Tambahan:

Mengakses file dan folder dengan API SDK Aplikasi Windows dan WinRT