共用方式為


開始使用 AI 文字辨識 (OCR)

文字辨識,也稱為光學字元辨識(OCR),由一組 Windows AI API 支援,能偵測並擷取影像中的文字,並將其轉換為機器可讀的字元流。

這些 API 可以識別字元、詞語、行、多邊形文字邊界,並為每個匹配項目提供信心水準。 它們也僅受具有神經處理單元 (NPU) 的裝置硬體加速的支援,使其比 Windows 平台 SDK 中的舊版 Windows.Media.Ocr.OcrEngine API 更快、更準確。

如需 API 詳細數據,請參閱文字辨識的 API 參考 (OCR)。

如何使用 AI 文字辨識?

使用 AI 文字辨識功能來識別和辨識影像中的文字。 您也可以取得已辨識文字的文字界限和信賴分數。

注意

難以辨認或尺寸較小的字元可能會產生不準確的結果。

從檔案建立影像緩衝區

在此 WinUI 範例中,我們會呼叫 函 LoadImageBufferFromFileAsync 式,從圖像檔取得 ImageBuffer

在 LoadImageBufferFromFileAsync 函式中,我們會完成下列步驟:

  1. 從指定的檔案路徑建立 StorageFile 物件。
  2. 使用 OpenAsync 在 StorageFile 上開啟數據流。
  3. 為該數據流建立 Bitmap解碼器
  4. 在點陣圖譯碼器上呼叫 GetSoftwareBitmapAsync 以取得 SoftwareBitmap 物件。
  5. CreateBufferAttachedToBitmap 傳回影像緩衝區。
using Microsoft.Windows.AI.Imaging;
using Microsoft.Graphics.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);
}
#include <iostream>
#include <sstream>
#include <winrt/Microsoft.Windows.AI.Imaging.h>
#include <winrt/Windows.Graphics.Imaging.h>
#include <winrt/Microsoft.Graphics.Imaging.h>
#include <winrt/Microsoft.UI.Xaml.Controls.h>
#include<winrt/Microsoft.UI.Xaml.Media.h>
#include<winrt/Microsoft.UI.Xaml.Shapes.h>

using namespace winrt;
using namespace Microsoft::UI::Xaml;
using namespace Microsoft::Windows::AI;
using namespace Microsoft::Windows::AI::Imaging;
using namespace winrt::Microsoft::UI::Xaml::Controls;
using namespace winrt::Microsoft::UI::Xaml::Media;


winrt::Windows::Foundation::IAsyncOperation<winrt::hstring> 
    MainWindow::RecognizeTextFromSoftwareBitmap(
        Windows::Graphics::Imaging::SoftwareBitmap const& bitmap)
{
    winrt::Microsoft::Windows::AI::Imaging::TextRecognizer textRecognizer = 
        EnsureModelIsReady().get();
    Microsoft::Graphics::Imaging::ImageBuffer imageBuffer = 
        Microsoft::Graphics::Imaging::ImageBuffer::CreateForSoftwareBitmap(bitmap);
    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.str()};
}

辨識位圖影像中的文字

下列範例示範如何將 SoftwareBitmap 物件中的某些文字辨識為單一字串值:

  1. 透過呼叫 函式建立 EnsureModelIsReady 物件,這也會確認系統上有語言模型存在。
  2. 使用在上一個代碼段中取得的點陣圖,我們呼叫 函式 RecognizeTextFromSoftwareBitmap
  3. 在圖像檔上呼叫 CreateBufferAttachedToBitmap 以取得 ImageBuffer 物件。
  4. 呼叫 RecognizeTextFromImage 以從 ImageBuffer 取得辨識的文字。
  5. 建立 wstringstream 物件,並使用已辨識的文字載入它。
  6. 傳回字串。

注意

EnsureModelIsReady 式可用來檢查文字辨識模型的整備狀態(並視需要安裝)。

using Microsoft.Windows.AI.Imaging;
using Microsoft.Windows.AI;
using Microsoft.Graphics.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.GetReadyState() == AIFeatureReadyState.NotReady)
    {
        var loadResult = await TextRecognizer.EnsureReadyAsync();
        if (loadResult.Status != AIFeatureReadyResultState.Success)
        {
            throw new Exception(loadResult.ExtendedError().Message);
        }
    }

    return await TextRecognizer.CreateAsync();
}
winrt::Windows::Foundation::IAsyncOperation<winrt::Microsoft::Windows::AI::Imaging::TextRecognizer> MainWindow::EnsureModelIsReady()
{
    if (winrt::Microsoft::Windows::AI::Imaging::TextRecognizer::GetReadyState() == AIFeatureReadyState::NotReady)
    {
        auto loadResult = TextRecognizer::EnsureReadyAsync().get();
           
        if (loadResult.Status() != AIFeatureReadyResultState::Success)
        {
            throw winrt::hresult_error(loadResult.ExtendedError());
        }
    }

    return winrt::Microsoft::Windows::AI::Imaging::TextRecognizer::CreateAsync();
}

取得詞界限和置信度

我們在這裡示範如何將SoftwareBitmap物件中每個單字的BoundingBox可視化,做為 Grid 元素上色彩編碼多邊形的集合。

注意

在此範例中,我們假設 TextRecognizer 物件已建立並傳入函式。

using Microsoft.Windows.AI.Imaging;
using Microsoft.Graphics.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);
        }
    }
}
void MainWindow::VisualizeWordBoundariesOnGrid(
    Windows::Graphics::Imaging::SoftwareBitmap const& bitmap,
    Grid const& grid,
    TextRecognizer const& textRecognizer)
{
    Microsoft::Graphics::Imaging::ImageBuffer imageBuffer = 
        Microsoft::Graphics::Imaging::ImageBuffer::CreateForSoftwareBitmap(bitmap);

    RecognizedText result = textRecognizer.RecognizeTextFromImage(imageBuffer);

    auto greenBrush = SolidColorBrush(winrt::Microsoft::UI::Colors::Green());
    auto yellowBrush = SolidColorBrush(winrt::Microsoft::UI::Colors::Yellow());
    auto redBrush = SolidColorBrush(winrt::Microsoft::UI::Colors::Red());
    for (const auto& line : result.Lines())
    {
        for (const auto& word : line.Words())
        {
            PointCollection points;
            const auto& bounds = word.BoundingBox();
            points.Append(bounds.TopLeft);
            points.Append(bounds.TopRight);
            points.Append(bounds.BottomRight);
            points.Append(bounds.BottomLeft);

            winrt::Microsoft::UI::Xaml::Shapes::Polygon polygon{};
            polygon.Points(points);
            polygon.StrokeThickness(2);
            if (word.MatchConfidence() < 0.33)
            {
                polygon.Stroke(redBrush);
            }
            else if (word.MatchConfidence() < 0.67)
            {
                polygon.Stroke(yellowBrush);
            }
            else
            {
                polygon.Stroke(greenBrush);
            }

            grid.Children().Append(polygon);
        }
    }
}

負責任的人工智慧

我們已使用下列步驟的組合,以確保這些映像 API 值得信任、安全且負責任地建置。 建議您檢閱在應用程式中實作 AI 功能時,在 Windows 上負責任產生 AI 開發 中所述的最佳做法。

另請參閱