語言
文字辨識,也稱為光學字元辨識(OCR),由一組 Windows AI API 支援,能偵測並擷取影像中的文字,並將其轉換為機器可讀的字元流。
這些 API 可以識別字元、詞語、行、多邊形文字邊界,並為每個匹配項目提供信心水準。 它們僅能在搭載神經處理單元(NPU)的裝置上運行,使其比傳統 Windows 更快且更精確。Media.Ocr.OcrEngine API 在 Windows 平台 SDK。
關於 API 的詳細資訊,請參閱 文字辨識(OCR)API 參考文獻。
AI 開發者畫廊讓你能執行互動式文字辨識範例,檢查其 C# 原始碼,並將範例匯出為 Visual Studio 專案。
探索文字辨識功能
利用文字辨識功能來辨識和辨識影像中的文字。 您也可以取得已辨識文字的文字界限和信賴分數。
注意
難以辨認或尺寸較小的字元可能會產生不準確的結果。
從檔案建立影像緩衝區
在此 WinUI 範例中,我們會呼叫 函 LoadImageBufferFromFileAsync 式,從圖像檔取得 ImageBuffer 。
在 LoadImageBufferFromFileAsync 函式中,我們會完成下列步驟:
- 從指定的檔案路徑建立 StorageFile 物件。
- 使用 OpenAsync 在 StorageFile 上開啟數據流。
- 為該數據流建立 Bitmap解碼器。
- 在點陣圖譯碼器上呼叫 GetSoftwareBitmapAsync 以取得 SoftwareBitmap 物件。
- 從 CreateForSoftwareBitmap 回傳一個影像緩衝區。
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.CreateForSoftwareBitmap(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 物件中的某些文字辨識為單一字串值:
- 透過呼叫 函式建立
EnsureModelIsReady物件,這也會確認系統上有語言模型存在。 - 使用在上一個代碼段中取得的點陣圖,我們呼叫 函式
RecognizeTextFromSoftwareBitmap。 - 在點陣圖上呼叫 CreateForSoftwareBitmap 以取得 ImageBuffer 物件。
- 呼叫 RecognizeTextFromImage 以從 ImageBuffer 取得辨識的文字。
- 建立 wstringstream 物件,並使用已辨識的文字載入它。
- 傳回字串。
注意
該 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.CreateForSoftwareBitmap(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.CreateForSoftwareBitmap(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.MatchConfidence < 0.33)
{
polygon.Stroke = redBrush;
}
else if (word.MatchConfidence < 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);
}
}
}
負責任的人工智慧
我們遵循 Microsoft 負責任 AI 標準 中所述的核心原則與實務,確保這些 API 值得信賴、安全且負責任地建置。 關於如何在應用程式中加入文字辨識的指引,請參閱 Windows 上的負責任生成式 AI 開發。