Inicio rápido: SDK v3.0 de la biblioteca cliente de C# | Versión preliminar
Nota
Form Recognizer v3.0 está actualmente en versión preliminar pública. Es posible que algunas características no se admitan o que tengan funcionalidades limitadas.
Documentación de referencia | Código fuente de la biblioteca | Paquete (NuGet) | Ejemplos
Comience a usar Azure Form Recognizer mediante el lenguaje de programación C#. Azure Form Recognizer es un componente de Azure Applied AI Services en la nube que usa el aprendizaje automático para extraer y analizar campos de formulario, texto y tablas de los documentos. Puede llamar fácilmente a los modelos de Form Recognizer mediante la integración de los SDK de biblioteca cliente en los flujos de trabajo y aplicaciones. Se recomienda usar el servicio gratuito cuando se está aprendiendo la tecnología. Recuerde que el número de páginas gratuitas se limita a 500 al mes.
Para más información sobre las características y las opciones de desarrollo de Form Recognizer, visite nuestra página de información general.
En este inicio rápido, usará las siguientes características para analizar y extraer datos y valores de formularios y documentos:
🆕 Documento general: análisis y extracción de texto, tablas, estructuras, pares clave-valor y entidades con nombre.
Diseño: análisis y extracción de tablas, líneas, palabras y marcas de selección, como botones de radio y casillas en documentos de formularios, sin necesidad de entrenar un modelo.
Modelo precompilado (factura) : análisis y extracción de campos comunes de facturas mediante un modelo de facturas entrenado previamente.
Prerrequisitos
Una suscripción a Azure: cree una cuenta gratuita.
Versión actual del IDE de Visual Studio.
Un recurso de Cognitive Services o Form Recognizer. Una vez que tenga la suscripción de Azure, cree un recurso de Form Recognizer de servicio único o de varios servicios en Azure Portal para obtener la clave y el punto de conexión. Puede usar el plan de tarifa gratis (
F0) para probar el servicio y actualizarlo más adelante a un plan de pago para producción.
Sugerencia
Cree un recurso de Cognitive Services si tiene previsto acceder a varios servicios de Cognitive Services en un único punto de conexión o clave. Para acceder únicamente a Form Recognizer, cree un recurso de Form Recognizer. Tenga en cuenta que necesitará un recurso de servicio único si tiene previsto usar la autenticación de Azure Active Directory.
Una vez implementado el recurso, seleccione Ir al recurso. Necesitará la clave y el punto de conexión del recurso que ha creado para conectar la aplicación a la API de Form Recognizer. En una sección posterior de este inicio rápido, pegará la clave y el punto de conexión en el código siguiente:
Configurar
Inicie Visual Studio 2019.
En la página de inicio, elija Crear un proyecto nuevo.
En la página Crear un proyecto, escriba consola en el cuadro de búsqueda. Elija la plantilla Aplicación de consola y, a continuación, seleccione Siguiente.
En la ventana de diálogo Configure su nuevo proyecto, escriba
formRecognizer_quickstarten el cuadro Nombre de proyecto. Después, haga clic en Siguiente.
En la ventana de diálogo Información adicional, seleccione .NET 5.0 (Actual) y, a continuación, seleccione Crear.
Instalación de la biblioteca cliente con NuGet
Haga clic con el botón derecho en el proyecto formRecognizer_quickstart y seleccione Administrar paquetes NuGet... .
Seleccione la pestaña Examinar y escriba Azure.AI.FormRecognizer.
Active la casilla Incluir versión preliminar.
Seleccione la versión 4.0.0-beta.1 en el menú desplegable y elija Instalar.
Compilación de la aplicación
Para interactuar con el servicio Form Recognizer, tiene que crear una instancia de la clase DocumentAnalysisClient. Para ello, creará un elemento AzureKeyCredential con el elemento apiKey y una instancia de DocumentAnalysisClient con el elemento AzureKeyCredential y el elemento endpoint de Form Recognizer.
Abra el archivo Program.cs.
Agregue las siguientes directivas using:
using System; using System.Threading.Tasks; using Azure; using Azure.AI.FormRecognizer; using Azure.AI.FormRecognizer.DocumentAnalysis;Establezca las variables de entorno
endpointyapiKey, y cree la instancia deAzureKeyCredentialyDocumentAnalysisClient:string endpoint = "<your-endpoint>"; string apiKey = "<your-apiKey>"; AzureKeyCredential credential = new AzureKeyCredential(apiKey); DocumentAnalysisClient client = new DocumentAnalysisClient(new Uri(endpoint), credential);Elimine la línea
Console.Writeline("Hello World!");y agregue uno de los ejemplos de código Probar al método Main en el archivo Program.cs:
Seleccione un ejemplo de código para copiar y pegar en el método main de la aplicación:
Importante
Recuerde quitar la clave del código cuando haya terminado y no hacerla nunca pública. En producción, use métodos seguros para almacenar y acceder a sus credenciales. Para más información, consulte el artículo sobre la seguridad de Cognitive Services.
Pruébelo: modelo de documento general
- Para este ejemplo, necesitará un archivo de documento de formulario en un identificador URI. Puede usar nuestro documento de formulario de ejemplo para este inicio rápido.
- Para analizar un archivo determinado en un identificador URI, utilizará el método
StartAnalyzeDocumentFromUri. El valor devuelto es un objetoAnalyzeResultque contiene datos sobre el documento enviado. - Se ha agregado el valor del URI del archivo a la variable
string fileUrien la parte superior del método main. - Por motivos de simplicidad, aquí no se muestran todos los campos de entidad que devuelve el servicio. Para ver la lista de todos los campos admitidos y los tipos correspondientes, consulte nuestra página de concepto del documento general.
Agregue el código siguiente al método Main de la aplicación de documento general.
// sample form document
string fileUri = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/sample-layout.pdf";
AnalyzeDocumentOperation operation = await client.StartAnalyzeDocumentFromUriAsync("prebuilt-document", fileUri);
await operation.WaitForCompletionAsync();
AnalyzeResult result = operation.Value;
Console.WriteLine("Detected entities:");
foreach (DocumentEntity entity in result.Entities)
{
if (entity.SubCategory == null)
{
Console.WriteLine($" Found entity '{entity.Content}' with category '{entity.Category}'.");
}
else
{
Console.WriteLine($" Found entity '{entity.Content}' with category '{entity.Category}' and sub-category '{entity.SubCategory}'.");
}
}
Console.WriteLine("Detected key-value pairs:");
foreach (DocumentKeyValuePair kvp in result.KeyValuePairs)
{
if (kvp.Value.Content == 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 box is:");
Console.WriteLine($" Upper left => X: {line.BoundingBox[0].X}, Y= {line.BoundingBox[0].Y}");
Console.WriteLine($" Upper right => X: {line.BoundingBox[1].X}, Y= {line.BoundingBox[1].Y}");
Console.WriteLine($" Lower right => X: {line.BoundingBox[2].X}, Y= {line.BoundingBox[2].Y}");
Console.WriteLine($" Lower left => X: {line.BoundingBox[3].X}, Y= {line.BoundingBox[3].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 box is:");
Console.WriteLine($" Upper left => X: {selectionMark.BoundingBox[0].X}, Y= {selectionMark.BoundingBox[0].Y}");
Console.WriteLine($" Upper right => X: {selectionMark.BoundingBox[1].X}, Y= {selectionMark.BoundingBox[1].Y}");
Console.WriteLine($" Lower right => X: {selectionMark.BoundingBox[2].X}, Y= {selectionMark.BoundingBox[2].Y}");
Console.WriteLine($" Lower left => X: {selectionMark.BoundingBox[3].X}, Y= {selectionMark.BoundingBox[3].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.Offset, 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}'.");
}
}
Pruébelo: modelo de diseño
Extraiga de los documentos texto, marcas de selección, estilos de texto y estructuras de tablas, junto con las coordenadas de su región delimitadora.
- Para este ejemplo, necesitará un archivo de documento de formulario en un identificador URI. Puede usar nuestro documento de formulario de ejemplo para este inicio rápido.
- Se ha agregado el valor del URI del archivo a la variable
string fileUrien la parte superior del método main. - Para extraer el diseño de un archivo determinado en un identificador URI, use el método
StartAnalyzeDocumentFromUriy paseprebuilt-layoutcomo identificador de modelo. El valor devuelto es un objetoAnalyzeResultque contiene datos del documento enviado.
Agregue el código siguiente al método Main de la aplicación de diseño.
// sample form document
string fileUri = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/sample-layout.pdf";
AnalyzeDocumentOperation operation = await client.StartAnalyzeDocumentFromUriAsync("prebuilt-layout", fileUri);
await operation.WaitForCompletionAsync();
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 box is:");
Console.WriteLine($" Upper left => X: {line.BoundingBox[0].X}, Y= {line.BoundingBox[0].Y}");
Console.WriteLine($" Upper right => X: {line.BoundingBox[1].X}, Y= {line.BoundingBox[1].Y}");
Console.WriteLine($" Lower right => X: {line.BoundingBox[2].X}, Y= {line.BoundingBox[2].Y}");
Console.WriteLine($" Lower left => X: {line.BoundingBox[3].X}, Y= {line.BoundingBox[3].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 box is:");
Console.WriteLine($" Upper left => X: {selectionMark.BoundingBox[0].X}, Y= {selectionMark.BoundingBox[0].Y}");
Console.WriteLine($" Upper right => X: {selectionMark.BoundingBox[1].X}, Y= {selectionMark.BoundingBox[1].Y}");
Console.WriteLine($" Lower right => X: {selectionMark.BoundingBox[2].X}, Y= {selectionMark.BoundingBox[2].Y}");
Console.WriteLine($" Lower left => X: {selectionMark.BoundingBox[3].X}, Y= {selectionMark.BoundingBox[3].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.Offset, 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}'.");
}
}
Probar: modelo precompilado
En este ejemplo se muestra cómo analizar datos procedentes de algunos tipos de documentos comunes con un modelo previamente entrenado. Por ejemplo, utilizando una factura.
- En este ejemplo, analizaremos un documento de factura mediante un modelo precompilado. Puede usar nuestro documento de factura de ejemplo para este inicio rápido.
- Se ha agregado el valor del URI del archivo a la variable
string fileUrien la parte superior del método main. - Para analizar un archivo determinado en un identificador URI, use el método
StartAnalyzeDocumentFromUriy paseprebuilt-invoicecomo identificador de modelo. El valor devuelto es un objetoAnalyzeResultque contiene datos del documento enviado. - Por motivos de simplicidad, aquí no se muestran todos los pares clave-valor que devuelve el servicio. Para ver la lista de todos los campos admitidos y los tipos correspondientes, consulte nuestra página de concepto de factura.
Elección del identificador de modelo precompilado de factura
No está limitado a las facturas: hay varios modelos precompilados entre los que elegir, cada uno de los cuales tiene su propio conjunto de campos admitidos. El modelo que se va a usar para la operación de análisis depende del tipo de documento que se va a analizar. Estos son los identificadores de modelo de los modelos precompilados admitidos actualmente por el servicio Form Recognizer:
- prebuilt-invoice: extrae texto, marcas de selección, tablas, pares clave-valor e información clave de las facturas.
- prebuilt-receipt: extrae texto e información clave de los recibos.
- prebuilt-idDocument: extrae texto e información clave de permisos de conducir y pasaportes internacionales.
- prebuilt-businessCard: extrae texto e información clave de las tarjetas de presentación.
Agregue el código siguiente al método Main de la aplicación de factura pregenerada.
// sample invoice document
string filePath = "(https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/sample-invoice.pdf";
using var stream = new FileStream(filePath, FileMode.Open);
AnalyzeDocumentOperation operation = await client.StartAnalyzeDocumentAsync("prebuilt-invoice", stream);
await operation.WaitForCompletionAsync();
AnalyzeResult result = operation.Value;
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.ValueType == DocumentFieldType.String)
{
string vendorName = vendorNameField.AsString();
Console.WriteLine($"Vendor Name: '{vendorName}', with confidence {vendorNameField.Confidence}");
}
}
if (document.Fields.TryGetValue("CustomerName", out DocumentField customerNameField))
{
if (customerNameField.ValueType == DocumentFieldType.String)
{
string customerName = customerNameField.AsString();
Console.WriteLine($"Customer Name: '{customerName}', with confidence {customerNameField.Confidence}");
}
}
if (document.Fields.TryGetValue("Items", out DocumentField itemsField))
{
if (itemsField.ValueType == DocumentFieldType.List)
{
foreach (DocumentField itemField in itemsField.AsList())
{
Console.WriteLine("Item:");
if (itemField.ValueType == DocumentFieldType.Dictionary)
{
IReadOnlyDictionary<string, DocumentField> itemFields = itemField.AsDictionary();
if (itemFields.TryGetValue("Description", out DocumentField itemDescriptionField))
{
if (itemDescriptionField.ValueType == DocumentFieldType.String)
{
string itemDescription = itemDescriptionField.AsString();
Console.WriteLine($" Description: '{itemDescription}', with confidence {itemDescriptionField.Confidence}");
}
}
if (itemFields.TryGetValue("Amount", out DocumentField itemAmountField))
{
if (itemAmountField.ValueType == DocumentFieldType.Double)
{
double itemAmount = itemAmountField.AsDouble();
Console.WriteLine($" Amount: '{itemAmount}', with confidence {itemAmountField.Confidence}");
}
}
}
}
}
}
if (document.Fields.TryGetValue("SubTotal", out DocumentField subTotalField))
{
if (subTotalField.ValueType == DocumentFieldType.Double)
{
double subTotal = subTotalField.AsDouble();
Console.WriteLine($"Sub Total: '{subTotal}', with confidence {subTotalField.Confidence}");
}
}
if (document.Fields.TryGetValue("TotalTax", out DocumentField totalTaxField))
{
if (totalTaxField.ValueType == DocumentFieldType.Double)
{
double totalTax = totalTaxField.AsDouble();
Console.WriteLine($"Total Tax: '{totalTax}', with confidence {totalTaxField.Confidence}");
}
}
if (document.Fields.TryGetValue("InvoiceTotal", out DocumentField invoiceTotalField))
{
if (invoiceTotalField.ValueType == DocumentFieldType.Double)
{
double invoiceTotal = invoiceTotalField.AsDouble();
Console.WriteLine($"Invoice Total: '{invoiceTotal}', with confidence {invoiceTotalField.Confidence}");
}
}
}
Ejecución de la aplicación
Elija el botón verde Inicio situado junto a formRecognizer_quickstart para compilar y ejecutar el programa, o pulse F5.
¡Enhorabuena! En este inicio rápido, ha usado el SDK de Form Recognizer para C# para analizar varios formularios y documentos de maneras diferentes. A continuación, explore la documentación de referencia para encontrar más información sobre la API de Form Recognizer.