Reconnaissance de texte dans le SDK d'application Windows
Les API de reconnaissance de texte d’intelligence artificielle (IA) qui seront fournies avec le SDK d’application Windows peuvent être utilisées pour identifier des caractères dans une image, reconnaître des mots, des lignes, des délimitations polygonales et fournir des niveaux de confiance pour les correspondances générées.
Ces nouvelles API du SDK d’application Windows sont plus rapides et plus précises que les API Windows.Media.Ocr.OcrEngine héritées dans le SDK de plateforme Windows et prennent en charge l’accélération matérielle dans les appareils avec une unité de traitement neuronale (NPU).
Important
Le canal expérimental du SDK d’application Windows comprend des API et des fonctionnalités qui en sont aux premières phases de développement. Toutes les API du canal expérimental font l’objet de révisions approfondies et de changements cassants et peuvent être supprimées des versions ultérieures à tout moment. Elles ne sont pas prises en charge dans les environnements de production et les applications qui utilisent des fonctionnalités expérimentales ne peuvent pas être publiées dans Microsoft Store.
Prérequis
Que puis-je faire avec le SDK d’application Windows et la reconnaissance de texte d’IA ?
Utilisez les nouvelles fonctionnalités de reconnaissance de texte d’IA fournies avec le SDK d’application Windows pour identifier et reconnaître du texte dans une image. Vous pouvez également obtenir les délimitations du texte et les scores de confiance pour le texte reconnu.
Créer un ImageBuffer à partir d’un fichier
Dans cet exemple, nous appelons une fonction LoadImageBufferFromFileAsync
pour obtenir un ImageBuffer à partir d’un fichier image.
Dans la fonction LoadImageBufferFromFileAsync, nous effectuons les étapes suivantes :
- Créez un objet StorageFile à partir du chemin d’accès de fichier spécifié.
- Ouvrez un flux sur StorageFile à l’aide d’OpenAsync.
- Créez un BitmapDecoder pour le flux.
- Appelez GetSoftwareBitmapAsync sur le décodeur d’image bitmap pour obtenir un objet SoftwareBitmap.
- Renvoyez une mémoire tampon d’image à partir de 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);
}
Reconnaître du texte dans une image bitmap
L’exemple suivant montre comment reconnaître du texte dans un objet SoftwareBitmap en tant que valeur de chaîne unique en procédant comme suit :
- Créez un objet TextRecognizer via un appel à la fonction
EnsureModelIsReady
, qui confirme également qu’un modèle de langage est présent sur le système. - À l’aide de l’image bitmap obtenue dans l’extrait de code précédent, nous appelons la fonction
RecognizeTextFromSoftwareBitmap
. - Appelez CreateBufferAttachedToBitmap sur le fichier image pour obtenir un objet ImageBuffer.
- Appelez RecognizeTextFromImage pour obtenir le texte reconnu à partir d’ImageBuffer.
- Créez un objet wstringstream et chargez-le avec le texte reconnu.
- Retourne la chaîne.
Remarque
La fonction EnsureModelIsReady
est utilisée pour vérifier l’état de préparation du modèle de reconnaissance de texte (et l’installer si nécessaire).
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();
}
Obtenir les limites de mots et la confiance
Ici, nous montrons comment visualiser les BoundingBox de chaque mot dans un objet SoftwareBitmap sous la forme d’une collection de polygones codés en couleur sur un élément Grid.
Remarque
Pour cet exemple, nous supposons qu’un objet TextRecognizer a déjà été créé et transmis à la fonction.
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);
}
}
}
Ressources supplémentaires
Accéder aux fichiers et dossiers avec le SDK d’application Windows et les API WinRT