Riconoscimento del testo in Windows App SDK
Le nuove API di riconoscimento del testo di intelligenza artificiale (AI) che verranno fornite con il SDK per app di Windows possono essere usate per identificare i caratteri in un'immagine, riconoscere parole, linee, limiti poligonali e fornire livelli di attendibilità per le corrispondenze generate.
Queste nuove API SDK per app di Windows sono più veloci e accurate rispetto alle API Windows.Media.Ocr.OcrEngine legacy nell'SDK della piattaforma Windows e supportano l'accelerazione hardware nei dispositivi con un'unità di elaborazione neurale (NPU).
Importante
Il canale sperimentale SDK per app di Windows include API e funzionalità nelle fasi iniziali dello sviluppo. Tutte le API nel canale sperimentale sono soggette a revisioni estese e modifiche di rilievo e possono essere rimosse dalle versioni successive in qualsiasi momento. Non sono supportate per l'uso in ambienti di produzione e le app che usano funzionalità sperimentali non possono essere pubblicate in Microsoft Store.
Prerequisiti
Cosa posso fare con il riconoscimento del testo di SDK per app di Windows e intelligenza artificiale?
Usare le nuove funzionalità di riconoscimento del testo di intelligenza artificiale nel SDK per app di Windows per identificare e riconoscere il testo in un'immagine. È anche possibile ottenere i limiti del testo e i punteggi di attendibilità per il testo riconosciuto.
Creare un oggetto ImageBuffer da un file
In questo esempio viene chiamata una LoadImageBufferFromFileAsync
funzione per ottenere imageBuffer da un file di immagine.
Nella funzione LoadImageBufferFromFileAsync vengono completati i passaggi seguenti:
- Creare un oggetto StorageFile dal percorso del file specificato.
- Aprire un flusso in StorageFile usando OpenAsync.
- Creare un oggetto BitmapDecoder per il flusso.
- Chiama GetSoftwareBitmapAsync nel decodificatore bitmap per ottenere un oggetto SoftwareBitmap .
- Restituisce un buffer di immagini da 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);
}
Riconoscere il testo in un'immagine bitmap
L'esempio seguente illustra come riconoscere un testo in un oggetto SoftwareBitmap come un singolo valore stringa:
- Creare un oggetto TextRecognizer tramite una chiamata alla
EnsureModelIsReady
funzione , che conferma anche che nel sistema è presente un modello linguistico. - Usando la bitmap ottenuta nel frammento precedente, chiamiamo la
RecognizeTextFromSoftwareBitmap
funzione . - Chiama CreateBufferAttachedToBitmap nel file di immagine per ottenere un oggetto ImageBuffer .
- Chiama RecognizeTextFromImage per ottenere il testo riconosciuto da ImageBuffer.
- Creare un oggetto wstringstream e caricarlo con il testo riconosciuto.
- Restituire la stringa.
Nota
La EnsureModelIsReady
funzione viene usata per controllare lo stato di idoneità del modello di riconoscimento del testo (e installarlo, se necessario).
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();
}
Ottenere limiti di parola e confidenza
Qui viene illustrato come visualizzare il BoundingBox di ogni parola in un oggetto SoftwareBitmap come raccolta di poligoni codificati a colori in un elemento Grid.
Nota
Per questo esempio si presuppone che sia già stato creato un oggetto TextRecognizer e passato alla funzione.
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);
}
}
}
Risorse aggiuntive
Accedere a file e cartelle con Windows App SDK e API WinRT