Biblioteca de clientes do Azure Reconhecimento de Formulários para .NET – versão 4.1.0

Observação: em julho de 2023, o serviço de Reconhecimento de Formulários dos Serviços Cognitivos do Azure foi renomeado para Inteligência de Documentos de IA do Azure. Todas as menções a Reconhecimento de Formulários ou Ao Document Intelligence na documentação referem-se ao mesmo serviço do Azure.

O Document Intelligence de IA do Azure é um serviço de nuvem que usa o aprendizado de máquina para analisar texto e dados estruturados de seus documentos. Ele inclui os seguintes recursos de main:

  • Layout – extraia texto, marcas de seleção, estruturas de tabela, estilos e parágrafos, juntamente com suas coordenadas de região delimitador de documentos.
  • Documento geral – analise pares chave-valor além do layout geral de documentos.
  • Leitura – Leia informações sobre elementos textuais, como palavras de página e linhas, além de informações de idioma de texto.
  • Predefinido – analise dados de determinados tipos de documentos comuns usando modelos predefinidos. Os documentos com suporte incluem recibos, faturas, cartões de visita, documentos de identidade, formulários fiscais W2 dos EUA e muito mais.
  • Análise personalizada – crie modelos de documento personalizados para analisar texto, valores de campo, marcas de seleção, estruturas de tabela, estilos e parágrafos de documentos. Modelos personalizados são criados com seus próprios dados, portanto, eles são adaptados aos seus documentos.
  • Classificação personalizada – crie modelos de classificador personalizados que combinam recursos de layout e idioma para detectar e identificar com precisão os documentos que você processa em seu aplicativo.

Código-fonte | Pacote (NuGet) | Documentação | de referência da APIDocumentação do produto | Amostras

Introdução

Instalar o pacote

Instale a biblioteca de clientes do Reconhecimento de Formulários do Azure para .NET com o NuGet:

dotnet add package Azure.AI.FormRecognizer

Observação: essa versão da biblioteca de clientes usa como padrão a 2023-07-31 versão do serviço.

Esta tabela mostra a relação entre as versões do SDK e as versões de API com suporte do serviço:

Versão do SDK Versão da API do serviço com suporte
4.1.0 2.0, 2.1, 2022-08-31, 2023-07-31
4.0.0 2.0, 2.1, 2022-08-31
3.1.X 2.0, 2.1
3.0.X 2,0

Observação: a partir da versão 4.0.0, um novo conjunto de clientes foi introduzido para aproveitar os recursos mais recentes do serviço de Inteligência de Documentos. Consulte o Guia de Migração para obter instruções detalhadas sobre como atualizar o código do aplicativo da versão 3.1.X da biblioteca de clientes ou inferior à versão mais recente. Além disso, consulte o Log de alterações para obter informações mais detalhadas. A tabela a seguir descreve a relação de cada cliente e suas versões de API com suporte:

Versão da API Clientes com suporte
2023-07-31 DocumentAnalysisClient e DocumentModelAdministrationClient
2022-08-31 DocumentAnalysisClient e DocumentModelAdministrationClient
2.1 FormRecognizerClient e FormTrainingClient
2,0 FormRecognizerClient e FormTrainingClient

Pré-requisitos

Criar um recurso de serviços cognitivos ou Reconhecimento de Formulários

O Document Intelligence dá suporte ao acesso de vários serviços e de serviço único. Crie um recurso dos Serviços Cognitivos se você planeja acessar vários serviços cognitivos em um só ponto de extremidade/chave. Somente para acesso ao Document Intelligence, crie um recurso Reconhecimento de Formulários. Observe que você precisará de um recurso de serviço único se pretender usar a autenticação do Azure Active Directory.

Você pode criar qualquer recurso usando:

Veja abaixo um exemplo de como você pode criar um recurso de Reconhecimento de Formulários usando a CLI:

# Create a new resource group to hold the Form Recognizer resource
# If using an existing resource group, skip this step
az group create --name <your-resource-name> --location <location>
# Create the Form Recognizer resource
az cognitiveservices account create \
    --name <resource-name> \
    --resource-group <resource-group-name> \
    --kind FormRecognizer \
    --sku <sku> \
    --location <location> \
    --yes

Para obter mais informações sobre como criar o recurso ou como obter o local e as informações de SKU, consulte aqui.

Autenticar o cliente

Para interagir com o serviço de Inteligência de Documentos, você precisará criar uma instância da DocumentAnalysisClient classe . Um ponto de extremidade e uma credencial são necessários para instanciar o objeto cliente.

Obter o ponto de extremidade

Você pode encontrar o ponto de extremidade do recurso Reconhecimento de Formulários usando o Portal do Azure ou a CLI do Azure:

# Get the endpoint for the Form Recognizer resource
az cognitiveservices account show --name "<resource-name>" --resource-group "<resource-group-name>" --query "properties.endpoint"

Um ponto de extremidade regional ou um subdomínio personalizado pode ser usado para autenticação. Elas são formatadas da seguinte maneira:

Regional endpoint: https://<region>.api.cognitive.microsoft.com/
Custom subdomain: https://<resource-name>.cognitiveservices.azure.com/

Um ponto de extremidade regional é o mesmo para cada recurso em uma região. Uma lista completa de pontos de extremidade regionais com suporte pode ser consultada aqui. Observe que os pontos de extremidade regionais não dão suporte à autenticação do AAD.

Um subdomínio personalizado, por outro lado, é um nome exclusivo para o recurso Reconhecimento de Formulários. Eles só podem ser usados por recursos de serviço único.

Obter a chave de API

A chave de API pode ser encontrada no Portal do Azure ou executando o seguinte comando da CLI do Azure:

az cognitiveservices account keys list --name "<resource-name>" --resource-group "<resource-group-name>"

Criar DocumentAnalysisClient com AzureKeyCredential

Depois de ter o valor da chave de API, crie um AzureKeyCredential. Com o ponto de extremidade e a credencial de chave, você pode criar o DocumentAnalysisClient:

string endpoint = "<endpoint>";
string apiKey = "<apiKey>";
var credential = new AzureKeyCredential(apiKey);
var client = new DocumentAnalysisClient(new Uri(endpoint), credential);

Criar DocumentAnalysisClient com a Credencial do Azure Active Directory

AzureKeyCredential A autenticação é usada nos exemplos deste guia de introdução, mas você também pode autenticar com o Azure Active Directory usando a biblioteca de identidade do Azure. Observe que os pontos de extremidade regionais não dão suporte à autenticação do AAD. Crie um subdomínio personalizado para o recurso para usar esse tipo de autenticação.

Para usar o provedor DefaultAzureCredential mostrado abaixo ou outros provedores de credenciais fornecidos com o SDK do Azure, instale o Azure.Identity pacote:

dotnet add package Azure.Identity

Você também precisará registrar um novo aplicativo do AAD e conceder acesso ao Document Intelligence atribuindo a "Cognitive Services User" função à entidade de serviço.

Defina os valores da ID do cliente, da ID do locatário e do segredo do cliente do aplicativo AAD como variáveis de ambiente: AZURE_CLIENT_ID, AZURE_TENANT_ID AZURE_CLIENT_SECRET.

string endpoint = "<endpoint>";
var client = new DocumentAnalysisClient(new Uri(endpoint), new DefaultAzureCredential());

Principais conceitos

DocumentAnalysisClient

DocumentAnalysisClient fornece operações para:

  • Analisar documentos de entrada usando modelos predefinidos e personalizados por meio das AnalyzeDocument APIs e AnalyzeDocumentFromUri .
  • Detectando e identificando documentos de entrada personalizados com as ClassifyDocument APIs e ClassifyDocumentFromUri .

Snippets de código de exemplo são fornecidos para ilustrar o uso de um DocumentAnalysisClient aqui. Mais informações sobre como analisar documentos, incluindo recursos com suporte, localidades e tipos de documentos, podem ser encontradas na documentação do serviço.

DocumentModelAdministrationClient

DocumentModelAdministrationClient fornece operações para:

  • Criando modelos personalizados para analisar campos específicos especificados rotulando seus documentos personalizados. Uma DocumentModelDetails instância é retornada indicando os tipos de documento que o modelo pode analisar, os campos que ele pode analisar para cada tipo de documento, bem como a confiança estimada para cada campo. Confira a documentação do serviço para obter uma explicação mais detalhada.
  • Redigir um modelo de uma coleção de modelos existentes.
  • Gerenciar modelos criados em sua conta.
  • Copiar um modelo personalizado de um recurso de Reconhecimento de Formulários para outro.
  • Listar operações de build ou obter operações específicas criadas nas últimas 24 horas.
  • Criar e gerenciar modelos de classificação de documentos para detectar e identificar com precisão os documentos que você processa em seu aplicativo.

Veja exemplos para Criar um modelo personalizado, gerenciar modelos e criar um classificador de documento.

Observe que modelos e classificadores também podem ser criados usando uma interface gráfica do usuário, como o Document Intelligence Studio.

Operações de Long-Running

Como a análise de documentos e a criação de modelos levam tempo, essas operações são implementadas como operações de execução prolongada. As operações de execução prolongada consistem em uma solicitação inicial enviada ao serviço para iniciar uma operação, seguida por sondar o serviço em intervalos para determinar se a operação foi concluída ou falhou e, se foi bem-sucedida, para obter o resultado.

Para operações de execução prolongada no SDK do Azure, o cliente expõe um método que retorna um Operation<T> objeto . Você pode definir seu parâmetro waitUntil como WaitUntil.Completed para aguardar a conclusão da operação e obter seu resultado; ou defina-o como WaitUntil.Started se você quiser apenas iniciar a operação e consumir o resultado posteriormente. Um snippet de código de exemplo é fornecido para ilustrar o uso de operações de execução prolongada abaixo.

Acesso thread-safe

Garantimos que todos os métodos de instância do cliente sejam thread-safe e independentes uns dos outros (diretriz). Isso garante que a recomendação de reutilize instâncias de cliente seja sempre segura, mesmo entre threads.

Conceitos adicionais

Opções | do clienteAcessando a resposta | Tratamento de falhas | Diagnostics | Zombando | Tempo de vida do cliente

Exemplos

A seção a seguir fornece vários snippets de código ilustrando padrões comuns usados na API do .NET Reconhecimento de Formulários. A maioria dos snippets abaixo usa chamadas de serviço assíncronas, mas tenha em mente que o pacote Azure.AI.FormRecognizer dá suporte a APIs síncronas e assíncronas.

Exemplos assíncronos

Exemplos de sincronização

Observe que esses exemplos usam a versão 4.1.0do SDK. Para versões 3.1.1 ou inferiores, consulte Exemplos de Reconhecimento de Formulários para V3.1.X.

Extrair Layout

Extraia texto, marcas de seleção, estruturas de tabela, estilos e parágrafos, juntamente com suas coordenadas de região delimitador de documentos.

Uri fileUri = new Uri("<fileUri>");

AnalyzeDocumentOperation operation = await client.AnalyzeDocumentFromUriAsync(WaitUntil.Completed, "prebuilt-layout", fileUri);
AnalyzeResult result = operation.Value;

foreach (DocumentPage page in result.Pages)
{
    Console.WriteLine($"Document Page {page.PageNumber} has {page.Lines.Count} line(s), {page.Words.Count} word(s),");
    Console.WriteLine($"and {page.SelectionMarks.Count} selection mark(s).");

    for (int i = 0; i < page.Lines.Count; i++)
    {
        DocumentLine line = page.Lines[i];
        Console.WriteLine($"  Line {i} has content: '{line.Content}'.");

        Console.WriteLine($"    Its bounding polygon (points ordered clockwise):");

        for (int j = 0; j < line.BoundingPolygon.Count; j++)
        {
            Console.WriteLine($"      Point {j} => X: {line.BoundingPolygon[j].X}, Y: {line.BoundingPolygon[j].Y}");
        }
    }

    for (int i = 0; i < page.SelectionMarks.Count; i++)
    {
        DocumentSelectionMark selectionMark = page.SelectionMarks[i];

        Console.WriteLine($"  Selection Mark {i} is {selectionMark.State}.");
        Console.WriteLine($"    Its bounding polygon (points ordered clockwise):");

        for (int j = 0; j < selectionMark.BoundingPolygon.Count; j++)
        {
            Console.WriteLine($"      Point {j} => X: {selectionMark.BoundingPolygon[j].X}, Y: {selectionMark.BoundingPolygon[j].Y}");
        }
    }
}

Console.WriteLine("Paragraphs:");

foreach (DocumentParagraph paragraph in result.Paragraphs)
{
    Console.WriteLine($"  Paragraph content: {paragraph.Content}");

    if (paragraph.Role != null)
    {
        Console.WriteLine($"    Role: {paragraph.Role}");
    }
}

foreach (DocumentStyle style in result.Styles)
{
    // Check the style and style confidence to see if text is handwritten.
    // Note that value '0.8' is used as an example.

    bool isHandwritten = style.IsHandwritten.HasValue && style.IsHandwritten == true;

    if (isHandwritten && style.Confidence > 0.8)
    {
        Console.WriteLine($"Handwritten content found:");

        foreach (DocumentSpan span in style.Spans)
        {
            Console.WriteLine($"  Content: {result.Content.Substring(span.Index, span.Length)}");
        }
    }
}

Console.WriteLine("The following tables were extracted:");

for (int i = 0; i < result.Tables.Count; i++)
{
    DocumentTable table = result.Tables[i];
    Console.WriteLine($"  Table {i} has {table.RowCount} rows and {table.ColumnCount} columns.");

    foreach (DocumentTableCell cell in table.Cells)
    {
        Console.WriteLine($"    Cell ({cell.RowIndex}, {cell.ColumnIndex}) has kind '{cell.Kind}' and content: '{cell.Content}'.");
    }
}

Para obter mais informações e exemplos, consulte aqui.

Usar o modelo de documento geral predefinido

Analise texto, marcas de seleção, estruturas de tabela, estilos, parágrafos e pares chave-valor de documentos usando o modelo de documento geral predefinido.

Uri fileUri = new Uri("<fileUri>");

AnalyzeDocumentOperation operation = await client.AnalyzeDocumentFromUriAsync(WaitUntil.Completed, "prebuilt-document", fileUri);
AnalyzeResult result = operation.Value;

Console.WriteLine("Detected key-value pairs:");

foreach (DocumentKeyValuePair kvp in result.KeyValuePairs)
{
    if (kvp.Value == null)
    {
        Console.WriteLine($"  Found key with no value: '{kvp.Key.Content}'");
    }
    else
    {
        Console.WriteLine($"  Found key-value pair: '{kvp.Key.Content}' and '{kvp.Value.Content}'");
    }
}

foreach (DocumentPage page in result.Pages)
{
    Console.WriteLine($"Document Page {page.PageNumber} has {page.Lines.Count} line(s), {page.Words.Count} word(s),");
    Console.WriteLine($"and {page.SelectionMarks.Count} selection mark(s).");

    for (int i = 0; i < page.Lines.Count; i++)
    {
        DocumentLine line = page.Lines[i];
        Console.WriteLine($"  Line {i} has content: '{line.Content}'.");

        Console.WriteLine($"    Its bounding polygon (points ordered clockwise):");

        for (int j = 0; j < line.BoundingPolygon.Count; j++)
        {
            Console.WriteLine($"      Point {j} => X: {line.BoundingPolygon[j].X}, Y: {line.BoundingPolygon[j].Y}");
        }
    }

    for (int i = 0; i < page.SelectionMarks.Count; i++)
    {
        DocumentSelectionMark selectionMark = page.SelectionMarks[i];

        Console.WriteLine($"  Selection Mark {i} is {selectionMark.State}.");
        Console.WriteLine($"    Its bounding polygon (points ordered clockwise):");

        for (int j = 0; j < selectionMark.BoundingPolygon.Count; j++)
        {
            Console.WriteLine($"      Point {j} => X: {selectionMark.BoundingPolygon[j].X}, Y: {selectionMark.BoundingPolygon[j].Y}");
        }
    }
}

foreach (DocumentStyle style in result.Styles)
{
    // Check the style and style confidence to see if text is handwritten.
    // Note that value '0.8' is used as an example.

    bool isHandwritten = style.IsHandwritten.HasValue && style.IsHandwritten == true;

    if (isHandwritten && style.Confidence > 0.8)
    {
        Console.WriteLine($"Handwritten content found:");

        foreach (DocumentSpan span in style.Spans)
        {
            Console.WriteLine($"  Content: {result.Content.Substring(span.Index, span.Length)}");
        }
    }
}

Console.WriteLine("The following tables were extracted:");

for (int i = 0; i < result.Tables.Count; i++)
{
    DocumentTable table = result.Tables[i];
    Console.WriteLine($"  Table {i} has {table.RowCount} rows and {table.ColumnCount} columns.");

    foreach (DocumentTableCell cell in table.Cells)
    {
        Console.WriteLine($"    Cell ({cell.RowIndex}, {cell.ColumnIndex}) has kind '{cell.Kind}' and content: '{cell.Content}'.");
    }
}

Para obter mais informações e exemplos, consulte aqui.

Usar o modelo de leitura predefinido

Analise elementos textuais, como palavras de página e linhas, estilos, parágrafos e informações de linguagem de texto de documentos usando o modelo de leitura predefinido.

Uri fileUri = new Uri("<fileUri>");

AnalyzeDocumentOperation operation = await client.AnalyzeDocumentFromUriAsync(WaitUntil.Completed, "prebuilt-read", fileUri);
AnalyzeResult result = operation.Value;

Console.WriteLine("Detected languages:");

foreach (DocumentLanguage language in result.Languages)
{
    Console.WriteLine($"  Found language with locale '{language.Locale}' and confidence {language.Confidence}.");
}

foreach (DocumentPage page in result.Pages)
{
    Console.WriteLine($"Document Page {page.PageNumber} has {page.Lines.Count} line(s), {page.Words.Count} word(s),");
    Console.WriteLine($"and {page.SelectionMarks.Count} selection mark(s).");

    for (int i = 0; i < page.Lines.Count; i++)
    {
        DocumentLine line = page.Lines[i];
        Console.WriteLine($"  Line {i} has content: '{line.Content}'.");

        Console.WriteLine($"    Its bounding polygon (points ordered clockwise):");

        for (int j = 0; j < line.BoundingPolygon.Count; j++)
        {
            Console.WriteLine($"      Point {j} => X: {line.BoundingPolygon[j].X}, Y: {line.BoundingPolygon[j].Y}");
        }
    }
}

foreach (DocumentStyle style in result.Styles)
{
    // Check the style and style confidence to see if text is handwritten.
    // Note that value '0.8' is used as an example.

    bool isHandwritten = style.IsHandwritten.HasValue && style.IsHandwritten == true;

    if (isHandwritten && style.Confidence > 0.8)
    {
        Console.WriteLine($"Handwritten content found:");

        foreach (DocumentSpan span in style.Spans)
        {
            Console.WriteLine($"  Content: {result.Content.Substring(span.Index, span.Length)}");
        }
    }
}

Para obter mais informações e exemplos, consulte aqui.

Usar modelos predefinidos

Analise dados de determinados tipos de documentos comuns usando modelos predefinidos fornecidos pelo serviço de Inteligência de Documentos.

Por exemplo, para analisar campos de uma fatura, use o modelo de Fatura predefinido fornecido passando a ID do prebuilt-invoice modelo para o AnalyzeDocumentAsync método :

string filePath = "<filePath>";

using var stream = new FileStream(filePath, FileMode.Open);

AnalyzeDocumentOperation operation = await client.AnalyzeDocumentAsync(WaitUntil.Completed, "prebuilt-invoice", stream);
AnalyzeResult result = operation.Value;

// To see the list of all the supported fields returned by service and its corresponding types for the
// prebuilt-invoice model, consult:
// https://aka.ms/azsdk/formrecognizer/invoicefieldschema

for (int i = 0; i < result.Documents.Count; i++)
{
    Console.WriteLine($"Document {i}:");

    AnalyzedDocument document = result.Documents[i];

    if (document.Fields.TryGetValue("VendorName", out DocumentField vendorNameField))
    {
        if (vendorNameField.FieldType == DocumentFieldType.String)
        {
            string vendorName = vendorNameField.Value.AsString();
            Console.WriteLine($"Vendor Name: '{vendorName}', with confidence {vendorNameField.Confidence}");
        }
    }

    if (document.Fields.TryGetValue("CustomerName", out DocumentField customerNameField))
    {
        if (customerNameField.FieldType == DocumentFieldType.String)
        {
            string customerName = customerNameField.Value.AsString();
            Console.WriteLine($"Customer Name: '{customerName}', with confidence {customerNameField.Confidence}");
        }
    }

    if (document.Fields.TryGetValue("Items", out DocumentField itemsField))
    {
        if (itemsField.FieldType == DocumentFieldType.List)
        {
            foreach (DocumentField itemField in itemsField.Value.AsList())
            {
                Console.WriteLine("Item:");

                if (itemField.FieldType == DocumentFieldType.Dictionary)
                {
                    IReadOnlyDictionary<string, DocumentField> itemFields = itemField.Value.AsDictionary();

                    if (itemFields.TryGetValue("Description", out DocumentField itemDescriptionField))
                    {
                        if (itemDescriptionField.FieldType == DocumentFieldType.String)
                        {
                            string itemDescription = itemDescriptionField.Value.AsString();

                            Console.WriteLine($"  Description: '{itemDescription}', with confidence {itemDescriptionField.Confidence}");
                        }
                    }

                    if (itemFields.TryGetValue("Amount", out DocumentField itemAmountField))
                    {
                        if (itemAmountField.FieldType == DocumentFieldType.Currency)
                        {
                            CurrencyValue itemAmount = itemAmountField.Value.AsCurrency();

                            Console.WriteLine($"  Amount: '{itemAmount.Symbol}{itemAmount.Amount}', with confidence {itemAmountField.Confidence}");
                        }
                    }
                }
            }
        }
    }

    if (document.Fields.TryGetValue("SubTotal", out DocumentField subTotalField))
    {
        if (subTotalField.FieldType == DocumentFieldType.Currency)
        {
            CurrencyValue subTotal = subTotalField.Value.AsCurrency();
            Console.WriteLine($"Sub Total: '{subTotal.Symbol}{subTotal.Amount}', with confidence {subTotalField.Confidence}");
        }
    }

    if (document.Fields.TryGetValue("TotalTax", out DocumentField totalTaxField))
    {
        if (totalTaxField.FieldType == DocumentFieldType.Currency)
        {
            CurrencyValue totalTax = totalTaxField.Value.AsCurrency();
            Console.WriteLine($"Total Tax: '{totalTax.Symbol}{totalTax.Amount}', with confidence {totalTaxField.Confidence}");
        }
    }

    if (document.Fields.TryGetValue("InvoiceTotal", out DocumentField invoiceTotalField))
    {
        if (invoiceTotalField.FieldType == DocumentFieldType.Currency)
        {
            CurrencyValue invoiceTotal = invoiceTotalField.Value.AsCurrency();
            Console.WriteLine($"Invoice Total: '{invoiceTotal.Symbol}{invoiceTotal.Amount}', with confidence {invoiceTotalField.Confidence}");
        }
    }
}

Você não está limitado a faturas! Há alguns modelos predefinidos para escolher, cada um com seu próprio conjunto de campos com suporte. Mais informações sobre os tipos de documento com suporte podem ser encontradas na documentação do serviço.

Para obter mais informações e exemplos, consulte aqui.

Criar um modelo personalizado

Crie um modelo personalizado em seu próprio tipo de documento. O modelo resultante pode ser usado para analisar valores dos tipos de documentos nos quais foi criado.

// For this sample, you can use the training documents found in the `trainingFiles` folder.
// Upload the documents to your storage container and then generate a container SAS URL. Note
// that a container URI without SAS is accepted only when the container is public or has a
// managed identity configured.
//
// For instructions to set up documents for training in an Azure Blob Storage Container, please see:
// https://aka.ms/azsdk/formrecognizer/buildcustommodel

Uri blobContainerUri = new Uri("<blobContainerUri>");
var client = new DocumentModelAdministrationClient(new Uri(endpoint), new AzureKeyCredential(apiKey));

// We are selecting the Template build mode in this sample. For more information about the available
// build modes and their differences, please see:
// https://aka.ms/azsdk/formrecognizer/buildmode

BuildDocumentModelOperation operation = await client.BuildDocumentModelAsync(WaitUntil.Completed, blobContainerUri, DocumentBuildMode.Template);
DocumentModelDetails model = operation.Value;

Console.WriteLine($"  Model Id: {model.ModelId}");
Console.WriteLine($"  Created on: {model.CreatedOn}");

Console.WriteLine("  Document types the model can recognize:");
foreach (KeyValuePair<string, DocumentTypeDetails> documentType in model.DocumentTypes)
{
    Console.WriteLine($"    Document type: {documentType.Key} which has the following fields:");
    foreach (KeyValuePair<string, DocumentFieldSchema> schema in documentType.Value.FieldSchema)
    {
        Console.WriteLine($"    Field: {schema.Key} with confidence {documentType.Value.FieldConfidence[schema.Key]}");
    }
}

Para obter mais informações e exemplos, consulte aqui.

Analisar documentos personalizados

Analise texto, valores de campo, marcas de seleção e estruturas de tabela, estilos e parágrafos de documentos personalizados, usando modelos criados com seus próprios tipos de documento.

string modelId = "<modelId>";
Uri fileUri = new Uri("<fileUri>");

AnalyzeDocumentOperation operation = await client.AnalyzeDocumentFromUriAsync(WaitUntil.Completed, modelId, fileUri);
AnalyzeResult result = operation.Value;

Console.WriteLine($"Document was analyzed with model with ID: {result.ModelId}");

foreach (AnalyzedDocument document in result.Documents)
{
    Console.WriteLine($"Document of type: {document.DocumentType}");

    foreach (KeyValuePair<string, DocumentField> fieldKvp in document.Fields)
    {
        string fieldName = fieldKvp.Key;
        DocumentField field = fieldKvp.Value;

        Console.WriteLine($"Field '{fieldName}': ");

        Console.WriteLine($"  Content: '{field.Content}'");
        Console.WriteLine($"  Confidence: '{field.Confidence}'");
    }
}

Para obter mais informações e exemplos, consulte aqui.

Gerenciar Modelos

Gerencie os modelos armazenados em sua conta.

var client = new DocumentModelAdministrationClient(new Uri(endpoint), new AzureKeyCredential(apiKey));

// Check number of custom models in the Form Recognizer resource, and the maximum number of custom models that can be stored.
ResourceDetails resourceDetails = await client.GetResourceDetailsAsync();
Console.WriteLine($"Resource has {resourceDetails.CustomDocumentModelCount} custom models.");
Console.WriteLine($"It can have at most {resourceDetails.CustomDocumentModelLimit} custom models.");

// List the first ten or fewer models currently stored in the resource.
AsyncPageable<DocumentModelSummary> models = client.GetDocumentModelsAsync();

int count = 0;
await foreach (DocumentModelSummary modelSummary in models)
{
    Console.WriteLine($"Custom Model Summary:");
    Console.WriteLine($"  Model Id: {modelSummary.ModelId}");
    if (string.IsNullOrEmpty(modelSummary.Description))
        Console.WriteLine($"  Model description: {modelSummary.Description}");
    Console.WriteLine($"  Created on: {modelSummary.CreatedOn}");
    if (++count == 10)
        break;
}

// Create a new model to store in the resource.
Uri blobContainerUri = new Uri("<blobContainerUri>");
BuildDocumentModelOperation operation = await client.BuildDocumentModelAsync(WaitUntil.Completed, blobContainerUri, DocumentBuildMode.Template);
DocumentModelDetails model = operation.Value;

// Get the model that was just created.
DocumentModelDetails newCreatedModel = await client.GetDocumentModelAsync(model.ModelId);

Console.WriteLine($"Custom Model with Id {newCreatedModel.ModelId} has the following information:");

Console.WriteLine($"  Model Id: {newCreatedModel.ModelId}");
if (string.IsNullOrEmpty(newCreatedModel.Description))
    Console.WriteLine($"  Model description: {newCreatedModel.Description}");
Console.WriteLine($"  Created on: {newCreatedModel.CreatedOn}");

// Delete the model from the resource.
await client.DeleteDocumentModelAsync(newCreatedModel.ModelId);

Para obter mais informações e exemplos, consulte aqui.

Gerenciar modelos de forma síncrona

Gerencie os modelos armazenados em sua conta com uma API síncrona.

var client = new DocumentModelAdministrationClient(new Uri(endpoint), new AzureKeyCredential(apiKey));

// Check number of custom models in the Form Recognizer resource, and the maximum number of custom models that can be stored.
ResourceDetails resourceDetails = client.GetResourceDetails();
Console.WriteLine($"Resource has {resourceDetails.CustomDocumentModelCount} custom models.");
Console.WriteLine($"It can have at most {resourceDetails.CustomDocumentModelLimit} custom models.");

// List the first ten or fewer models currently stored in the resource.
Pageable<DocumentModelSummary> models = client.GetDocumentModels();

foreach (DocumentModelSummary modelSummary in models.Take(10))
{
    Console.WriteLine($"Custom Model Summary:");
    Console.WriteLine($"  Model Id: {modelSummary.ModelId}");
    if (string.IsNullOrEmpty(modelSummary.Description))
        Console.WriteLine($"  Model description: {modelSummary.Description}");
    Console.WriteLine($"  Created on: {modelSummary.CreatedOn}");
}

// Create a new model to store in the resource.

Uri blobContainerUri = new Uri("<blobContainerUri>");
BuildDocumentModelOperation operation = client.BuildDocumentModel(WaitUntil.Completed, blobContainerUri, DocumentBuildMode.Template);
DocumentModelDetails model = operation.Value;

// Get the model that was just created.
DocumentModelDetails newCreatedModel = client.GetDocumentModel(model.ModelId);

Console.WriteLine($"Custom Model with Id {newCreatedModel.ModelId} has the following information:");

Console.WriteLine($"  Model Id: {newCreatedModel.ModelId}");
if (string.IsNullOrEmpty(newCreatedModel.Description))
    Console.WriteLine($"  Model description: {newCreatedModel.Description}");
Console.WriteLine($"  Created on: {newCreatedModel.CreatedOn}");

// Delete the created model from the resource.
client.DeleteDocumentModel(newCreatedModel.ModelId);

Criar um classificador de documento

Crie um classificador de documento carregando documentos de treinamento personalizados.

// For this sample, you can use the training documents found in the `classifierTrainingFiles` folder.
// Upload the documents to your storage container and then generate a container SAS URL. Note
// that a container URI without SAS is accepted only when the container is public or has a
// managed identity configured.
//
// For instructions to set up documents for training in an Azure Blob Storage Container, please see:
// https://aka.ms/azsdk/formrecognizer/buildclassifiermodel

Uri trainingFilesUri = new Uri("<trainingFilesUri>");
var client = new DocumentModelAdministrationClient(new Uri(endpoint), new AzureKeyCredential(apiKey));

var sourceA = new BlobContentSource(trainingFilesUri) { Prefix = "IRS-1040-A/train" };
var sourceB = new BlobContentSource(trainingFilesUri) { Prefix = "IRS-1040-B/train" };

var documentTypes = new Dictionary<string, ClassifierDocumentTypeDetails>()
{
    { "IRS-1040-A", new ClassifierDocumentTypeDetails(sourceA) },
    { "IRS-1040-B", new ClassifierDocumentTypeDetails(sourceB) }
};

BuildDocumentClassifierOperation operation = await client.BuildDocumentClassifierAsync(WaitUntil.Completed, documentTypes);
DocumentClassifierDetails classifier = operation.Value;

Console.WriteLine($"  Classifier Id: {classifier.ClassifierId}");
Console.WriteLine($"  Created on: {classifier.CreatedOn}");

Console.WriteLine("  Document types the classifier can recognize:");
foreach (KeyValuePair<string, ClassifierDocumentTypeDetails> documentType in classifier.DocumentTypes)
{
    Console.WriteLine($"    {documentType.Key}");
}

Para obter mais informações e exemplos, consulte aqui.

Classificar um documento

Use classificadores de documentos para detectar e identificar com precisão os documentos que você processa em seu aplicativo.

string classifierId = "<classifierId>";
Uri fileUri = new Uri("<fileUri>");

ClassifyDocumentOperation operation = await client.ClassifyDocumentFromUriAsync(WaitUntil.Completed, classifierId, fileUri);
AnalyzeResult result = operation.Value;

Console.WriteLine($"Document was classified by classifier with ID: {result.ModelId}");

foreach (AnalyzedDocument document in result.Documents)
{
    Console.WriteLine($"Document of type: {document.DocumentType}");
}

Para obter mais informações e exemplos, consulte aqui.

Solução de problemas

Geral

Quando você interage com a biblioteca de clientes Reconhecimento de Formulários usando o SDK do .NET, os erros retornados pelo serviço resultarão em um RequestFailedException com o mesmo código http status retornado pela solicitação da API REST.

Por exemplo, se você enviar uma imagem de recibo com um inválido Uri, um 400 erro será retornado, indicando "Solicitação Incorreta".

try
{
    AnalyzeDocumentOperation operation = await client.AnalyzeDocumentFromUriAsync(WaitUntil.Completed, "prebuilt-receipt", new Uri("http://invalid.uri"));
}
catch (RequestFailedException e)
{
    Console.WriteLine(e.ToString());
}

Você observará que informações adicionais são registradas, como a ID de solicitação do cliente da operação.

Message:
    Azure.RequestFailedException: Service request failed.
    Status: 400 (Bad Request)
    ErrorCode: InvalidRequest

Content:
    {"error":{"code":"InvalidRequest","message":"Invalid request.","innererror":{"code":"InvalidContent","message":"The file is corrupted or format is unsupported. Refer to documentation for the list of supported formats."}}}

Headers:
    Transfer-Encoding: chunked
    x-envoy-upstream-service-time: REDACTED
    apim-request-id: REDACTED
    Strict-Transport-Security: REDACTED
    X-Content-Type-Options: REDACTED
    Date: Fri, 01 Oct 2021 02:55:44 GMT
    Content-Type: application/json; charset=utf-8

Códigos de erro e mensagens geradas pelo serviço de Inteligência de Documentos podem ser encontrados na documentação do serviço.

Para obter mais detalhes sobre problemas comuns, consulte nosso guia de solução de problemas.

Configuração do registro em log do console

A maneira mais simples de ver os logs é habilitar o log do console. Para criar um ouvinte de log do SDK do Azure que gera mensagens para o console, use o método AzureEventSourceListener.CreateConsoleLogger.

// Setup a listener to monitor logged events.
using AzureEventSourceListener listener = AzureEventSourceListener.CreateConsoleLogger();

Para saber mais sobre outros mecanismos de registro em log, confira Exemplos de diagnóstico.

Próximas etapas

Exemplos que mostram como usar a biblioteca de Reconhecimento de Formulários estão disponíveis neste repositório GitHub. Os exemplos são fornecidos para cada área funcional main:

Observe que esses exemplos usam a versão 4.1.0do SDK. Para versões 3.1.1 ou inferiores, consulte Exemplos de Reconhecimento de Formulários para V3.1.X.

Contribuição

Este projeto aceita contribuições e sugestões. A maioria das contribuições exige que você concorde com um CLA (Contrato de Licença do Colaborador) declarando que você tem o direito de nos conceder, e de fato concede, os direitos de usar sua contribuição. Para obter detalhes, visite cla.microsoft.com.

Quando você envia uma solicitação de pull, um bot do CLA determina automaticamente se você precisa fornecer um CLA e preencher a PR corretamente (por exemplo, rótulo, comentário). Basta seguir as instruções fornecidas pelo bot. Você só precisará fazer isso uma vez em todos os repositórios que usam nosso CLA.

Este projeto adotou o Código de Conduta de Software Livre da Microsoft. Para obter mais informações, confira as Perguntas frequentes sobre o Código de Conduta ou contate opencode@microsoft.com para enviar outras perguntas ou comentários.

Impressões