OCR(광학 문자 인식)으로도 알려진 텍스트 인식은 이미지 내에서 텍스트를 감지 및 추출하고 컴퓨터에서 읽을 수 있는 문자 스트림으로 변환할 수 있는 Windows AI API 집합에서 지원됩니다.
이러한 API는 문자, 단어, 선, 다각형 텍스트 경계를 식별하고 각 일치 항목에 대한 신뢰도 수준을 제공할 수 있습니다. 또한 NPU(신경 처리 장치)가 있는 디바이스의 하드웨어 가속에서만 지원되므로 Windows 플랫폼 SDK의 레거시 Windows.Media.Ocr.OcrEngine API보다 빠르고 정확합니다.
API 세부 정보는OCR(텍스트 인식)에 대한 API ref를 참조하세요.
AI 텍스트 인식으로 무엇을 할 수 있나요?
AI 텍스트 인식 기능을 사용하여 이미지의 텍스트를 식별하고 인식합니다. 인식된 텍스트의 텍스트 경계 및 신뢰도 점수를 가져올 수도 있습니다.
참고
읽을 수 없거나 크기가 작은 문자는 부정확한 결과를 생성할 수 있습니다.
파일에서 ImageBuffer 만들기
이 WinUI 예제에서는 이미지 파일에서 LoadImageBufferFromFileAsync를 가져오는 함수를 호출 합니다.
LoadImageBufferFromFileAsync 함수에서 다음 단계를 완료합니다.
- 지정된 파일 경로에서 StorageFile 개체를 만듭니다.
- OpenAsync를 사용하여 StorageFile에서 스트림을 엽니다.
- 스트림용 BitmapDecoder를 만듭니다.
- 비트맵 디코더에서 GetSoftwareBitmapAsync를 호출하여 SoftwareBitmap 개체를 가져옵니다.
- 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 개체의 일부 텍스트를 단일 문자열 값으로 인식하는 방법을 보여줍니다.
- 함수 호출을 통해 TextRecognizer 개체를
EnsureModelIsReady만듭니다. 이 개체는 시스템에 언어 모델이 있는지도 확인합니다. - 이전 코드 조각에서 가져온 비트맵을 사용하여 함수를 호출합니다
RecognizeTextFromSoftwareBitmap. - 이미지 파일에서 CreateBufferAttachedToBitmap을 호출하여 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.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 개발에 설명된 모범 사례를 검토하는 것이 좋습니다.