文本识别(也称为光学字符识别(OCR)通过一组人工智能(AI)支持的 API 在 Windows AI Foundry 中受支持,这些 API 可以检测和提取图像中的文本并将其转换为计算机可读字符流。
这些 API 可以标识字符、字词、行、多边形文本边界,并为每个匹配提供置信度。 它们还由带有神经处理单元 (NPU) 的硬件加速设备独家支持,使其比 Windows 平台 SDK中的旧版 Windows.Media.Ocr.OcrEngine API 更快、更准确。
有关 API 详细信息,请参阅文本识别 API 参考(OCR)。
重要
下面是 Windows AI 功能和当前支持的 Windows 应用 SDK 版本列表。
版本 1.8 实验版(1.8.0-experimental1) - 对象擦除, Phi Silica, LoRA 微调 Phi Silica, 对话摘要(文本智能)
个人预览版 - 语义搜索
版本 1.7.1 (1.7.250401001) - 所有其他 API
这些 API 仅在已收到 5 月 7 日更新的 Windows 预览体验计划预览版(WIP)设备上正常运行。 5 月 28 日至 29 日,可选更新将发布到非 WIP 设备,随后将进行 6 月 10 日的更新。 此更新将附带 Windows AI API 正常运行所需的 AI 模型。 这些更新还要求任何使用 Windows AI API 的应用在运行时获得包身份之前,无法使用这些 API。
如何使用 AI 文本识别?
使用 AI 文本识别功能来识别和识别图像中的文本。 还可以获取已识别文本的文本边界及置信度分数。
从文件中创建 ImageBuffer
在此 WinUI 示例中,我们调用一个 LoadImageBufferFromFileAsync
函数来从图像文件获取 ImageBuffer 。
在 LoadImageBufferFromFileAsync 函数中,我们会完成以下步骤:
- 从指定的文件路径创建 StorageFile 对象。
- 使用 OpenAsync 在 StorageFile 上打开流。
- 为流创建 BitmapDecoder。
- 调用位图解码器上的 GetSoftwareBitmapAsync,以获取 SoftwareBitmap 对象。
- 从 CreateBufferAttachedToBitmap 返回图像缓冲区。
using Microsoft.Windows.Vision;
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 对象中的某些文本识别为单个字符串值:
- 通过调用 函数创建
EnsureModelIsReady
对象,该函数还会确认系统上存在语言模型。 - 使用在之前的代码片段中获取的位图,我们可调用
RecognizeTextFromSoftwareBitmap
函数。 - 调用图像文件上的 CreateBufferAttachedToBitmap,以获取 ImageBuffer 对象。
- 调用 RecognizeTextFromImage 从 ImageBuffer 获取已识别的文本。
- 创建 wstringstream 对象,并使用已识别的文本进行加载。
- 返回字符串。
注意
EnsureModelIsReady
函数用于检查文本识别模型的就绪状态(并在必要时进行安装)。
using Microsoft.Windows.Vision;
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.EnsureNeeded)
{
var loadResult = await TextRecognizer.EnsureReadyAsync();
if (loadResult.Status != PackageDeploymentStatus.CompletedSuccess)
{
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.Vision;
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 开发中描述的最佳做法。