Поделиться через


Использование моделей аналитики документов

Это содержимое относится к: версии 4.0 (предварительная версия) | Предыдущие версии: флажоксиняя галочка версия 3.1 (GA) версии 3.0 (GA) синяя галочка версии 2.1 (GA) синяя галочка

Это содержимое относится к: версия 3.1 (GA) | Последняя версия: фиолетовый флажокфлажок версия 4.0 (предварительная версия) | Предыдущие версии: синяя галочка версии 3.0синяя галочка версии 2.1

Это содержимое относится к: версия 3.0 (GA) | Последние версии: флажок фиолетовый флажок v4.0 (предварительная версия) фиолетовый флажок версии 3.1 | Предыдущая версия: синяя галочка версия 2.1

Это содержимое относится к: версия 2.1 Последняя версия: флажоксиняя галочка версия 4.0 (предварительная версия) |

В этом руководстве описано, как добавить модели аналитики документов в приложения и рабочие процессы. Используйте пакет SDK для языка программирования или REST API.

Azure AI Document Intelligence — это облачная служба ИИ Azure, которая использует машинное обучение для извлечения ключевых элементов текста и структуры из документов. Мы рекомендуем использовать бесплатную службу при изучении технологии. Имейте в виду, что количество бесплатных страниц ограничено до 500 страниц в месяц.

Выберите из следующих моделей аналитики документов и проанализируйте и извлеките данные и значения из форм и документов:

  • Предварительно созданная модель чтения находится в основе всех моделей аналитики документов и может обнаруживать строки, слова, расположения и языки. Макет, общие документы, предварительно созданные и пользовательские модели используют read модель в качестве основы для извлечения текстов из документов.

  • Предварительно созданная модель макета извлекает текстовые и текстовые расположения, таблицы, знаки выделения и сведения о структуре из документов и изображений. Пары "ключ-значение" можно извлечь с помощью модели макета с включенным необязательным параметром features=keyValuePairs строки запроса.

  • Предварительно созданная модель контракта извлекает ключевые сведения из договорных соглашений.

  • Модель prebuilt-healthInsuranceCard.us извлекает ключевые сведения из карт медицинского страхования США.

  • Предварительно созданная модель моделей налоговых документов извлекает информацию о налоговых формах США.

  • Предварительно созданная модель счета извлекает ключевые поля и элементы строк из счетов по продажам в различных форматах и качестве. Поля включают захваченные телефоном изображения, сканированные документы и цифровые PDF-файлы.

  • Предварительно созданная модель квитанций извлекает ключевые сведения из печатных и рукописных квитанций о продажах.

  • Предварительно созданная модель idDocument извлекает ключевые сведения из лицензий водителей США, международных биографических страниц паспортов, идентификаторов штата США, карт социального страхования и постоянных резидентных карт.

Справочник по | пакету SDK для клиентской библиотеки | REST API. Примеры| | | пакетов, поддерживаемые версией REST API

Необходимые компоненты

Настройка переменных среды

Чтобы взаимодействовать со службой аналитики DocumentAnalysisClient документов, необходимо создать экземпляр класса. Для этого создайте экземпляр клиента с портал Azure key endpoint. Для этого проекта используйте переменные среды для хранения и доступа к учетным данным.

Внимание

Если вы используете ключ API, сохраните его в другом месте, например в Azure Key Vault. Не включайте ключ API непосредственно в код и никогда не публикуйте его.

Дополнительные сведения о безопасности служб ИИ см. в статье "Проверка подлинности запросов к службам ИИ Azure".

Чтобы задать переменную среды для ключа ресурса Аналитики документов, откройте окно консоли и следуйте инструкциям в вашей операционной системе и среде разработки. Замените <yourKey> и <yourEndpoint> значениями из ресурса в портал Azure.

Переменные среды в Windows не учитывает регистр. Они обычно объявляются в верхнем регистре, с словами, присоединенными подчеркиванием. В командной строке выполните следующие команды:

  1. Задайте ключевую переменную:

    setx DI_KEY <yourKey>
    
  2. Настройка переменной конечной точки

    setx DI_ENDPOINT <yourEndpoint>
    
  3. Закройте окно командной строки после задания переменных среды. Значения остаются до тех пор, пока не измените их еще раз.

  4. Перезапустите все запущенные программы, которые считывают переменную среды. Например, если вы используете Visual Studio или Visual Studio Code в качестве редактора, перезапустите перед запуском примера кода.

Ниже приведены несколько дополнительных полезных команд для использования с переменными среды:

Команда Действие Пример
setx VARIABLE_NAME= Удалите переменную среды, задав значение пустой строке. setx DI_KEY=
setx VARIABLE_NAME=value Задайте или измените значение переменной среды. setx DI_KEY=<yourKey>
set VARIABLE_NAME Отображение значения определенной переменной среды. set DI_KEY
set Отображение всех переменных среды. set

Настройка среды программирования

  1. Запустите Visual Studio.

  2. На начальной странице выберите Создать проект.

    Снимок экрана: окно запуска Visual Studio.

  3. На странице Создание проекта введите в поле поиска консоль. Выберите шаблон консольного приложения , а затем нажмите кнопку "Далее".

    Снимок экрана: страница создания проекта Visual Studio.

  4. На странице "Настройка нового проекта" в поле "Имя проекта" введите docIntelligence_app. Затем выберите Далее.

    Снимок экрана: страница настройки нового проекта Visual Studio.

  5. На странице "Дополнительные сведения" выберите .NET 8.0 (долгосрочная поддержка) и нажмите кнопку "Создать".

    Снимок экрана: страница дополнительных сведений Visual Studio.

Установка клиентской библиотеки с помощью NuGet

  1. Щелкните правой кнопкой мыши проект docIntelligence_app и выберите "Управление пакетами NuGet...".

    Снимок экрана: окно выбранного пакета NuGet в Visual Studio.

  2. Выберите вкладку "Обзор" и введите Azure.AI.FormRecognizer.

  3. Include prerelease Установите флажок.

    Снимок экрана: выбор предварительного пакета NuGet в Visual Studio.

  4. Выберите версию из раскрывающегося меню и установите пакет в проекте.

Сборка приложения

Примечание.

Начиная с .NET 6, в новых проектах, где используется шаблон console, создается новый стиль программы, отличный от предыдущих версий. В новых выходных данных используются последние функции C#, упрощающие код, который необходимо написать.

При использовании более новой версии необходимо только написать текст метода Main. Вам не нужно включать инструкции верхнего уровня, глобальные директивы using или неявные директивы using. Дополнительные сведения см. в разделе шаблон консольного приложения C#, который создает инструкции верхнего уровня.

  1. Откройте файл Program.cs.

  2. Удалите существующий код, включая строку Console.Writeline("Hello World!").

  3. Выберите один из следующих примеров кода и скопируйте и вставьте в файл Program.cs приложения:

  4. После добавления примера кода в приложение нажмите зеленую кнопку "Пуск " рядом с именем проекта, чтобы создать и запустить программу, или нажмите клавишу F5.

    Снимок экрана: запуск программы Visual Studio.

Использование модели чтения

using Azure;
using Azure.AI.DocumentIntelligence;

//use your `key` and `endpoint` environment variables to create your `AzureKeyCredential` and `DocumentIntelligenceClient` instances
string key = Environment.GetEnvironmentVariable("DI_KEY");
string endpoint = Environment.GetEnvironmentVariable("DI_ENDPOINT");
AzureKeyCredential credential = new AzureKeyCredential(key);
DocumentIntelligenceClient client = new DocumentIntelligenceClient(new Uri(endpoint), credential);

//sample document
Uri fileUri = new Uri("https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/read.png");

Operation<AnalyzeResult> operation = await client.AnalyzeDocumentAsync(WaitUntil.Completed, "prebuilt-read", 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}");
        }
    }
}

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("Detected languages:");

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

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные read данные модели.

Использование модели макета

using Azure;
using Azure.AI.DocumentIntelligence;

//use your `key` and `endpoint` environment variables to create your `AzureKeyCredential` and `DocumentIntelligenceClient` instances
string key = Environment.GetEnvironmentVariable("DI_KEY");
string endpoint = Environment.GetEnvironmentVariable("DI_ENDPOINT");
AzureKeyCredential credential = new AzureKeyCredential(key);
DocumentIntelligenceClient client = new DocumentIntelligenceClient(new Uri(endpoint), credential);

// sample document document
Uri fileUri = new Uri ("https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/layout.png");

Operation<AnalyzeResult> operation = await client.AnalyzeDocumentAsync(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}'.");
    }
}

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные данные модели макета.

Использование модели общего документа

using Azure;
using Azure.AI.DocumentIntelligence;

//use your `key` and `endpoint` environment variables to create your `AzureKeyCredential` and `DocumentIntelligenceClient` instances
string key = Environment.GetEnvironmentVariable("DI_KEY");
string endpoint = Environment.GetEnvironmentVariable("DI_ENDPOINT");
AzureKeyCredential credential = new AzureKeyCredential(key);
DocumentIntelligenceClient client = new DocumentIntelligenceClient(new Uri(endpoint), credential);

// sample document document
Uri fileUri = new Uri("https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/sample-layout.pdf");

Operation<AnalyzeResult> operation = await client.AnalyzeDocumentAsync(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}'.");
    }
}

Посетите репозиторий примеров Azure на GitHub и просмотрите общие выходные данные модели документов.

Использование налоговой модели W-2


using Azure;
using Azure.AI.DocumentIntelligence;

//use your `key` and `endpoint` environment variables to create your `AzureKeyCredential` and `DocumentIntelligenceClient` instances
string key = Environment.GetEnvironmentVariable("DI_KEY");
string endpoint = Environment.GetEnvironmentVariable("DI_ENDPOINT");
AzureKeyCredential credential = new AzureKeyCredential(key);
DocumentIntelligenceClient client = new DocumentIntelligenceClient(new Uri(endpoint), credential);

// sample document document
Uri w2Uri = new Uri("https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/w2.png");

Operation<AnalyzeResult> operation = await client.AnalyzeDocumentAsync(WaitUntil.Completed, "prebuilt-tax.us.w2", w2Uri);

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("AdditionalInfo", out DocumentField? additionalInfoField))
    {
        if (additionalInfoField.FieldType == DocumentFieldType.List)
        {
            foreach (DocumentField infoField in additionalInfoField.Value.AsList())
            {
                Console.WriteLine("AdditionalInfo:");

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

                    if (infoFields.TryGetValue("Amount", out DocumentField? amountField))
                    {
                        if (amountField.FieldType == DocumentFieldType.Double)
                        {
                            double amount = amountField.Value.AsDouble();

                            Console.WriteLine($"  Amount: '{amount}', with confidence {amountField.Confidence}");
                        }
                    }

                    if (infoFields.TryGetValue("LetterCode", out DocumentField? letterCodeField))
                    {
                        if (letterCodeField.FieldType == DocumentFieldType.String)
                        {
                            string letterCode = letterCodeField.Value.AsString();

                            Console.WriteLine($"  LetterCode: '{letterCode}', with confidence {letterCodeField.Confidence}");
                        }
                    }
                }
            }
        }
    }


    if (document.Fields.TryGetValue("AllocatedTips", out DocumentField? allocatedTipsField))
    {
        if (allocatedTipsField.FieldType == DocumentFieldType.Double)
        {
            double allocatedTips = allocatedTipsField.Value.AsDouble();
            Console.WriteLine($"Allocated Tips: '{allocatedTips}', with confidence {allocatedTipsField.Confidence}");
        }
    }

    if (document.Fields.TryGetValue("Employer", out DocumentField? employerField))
    {
        if (employerField.FieldType == DocumentFieldType.Dictionary)
        {
            IReadOnlyDictionary<string, DocumentField> employerFields = employerField.Value.AsDictionary();

            if (employerFields.TryGetValue("Name", out DocumentField? employerNameField))
            {
                if (employerNameField.FieldType == DocumentFieldType.String)
                {
                    string name = employerNameField.Value.AsString();

                    Console.WriteLine($"Employer Name: '{name}', with confidence {employerNameField.Confidence}");
                }
            }

            if (employerFields.TryGetValue("IdNumber", out DocumentField? idNumberField))
            {
                if (idNumberField.FieldType == DocumentFieldType.String)
                {
                    string id = idNumberField.Value.AsString();

                    Console.WriteLine($"Employer ID Number: '{id}', with confidence {idNumberField.Confidence}");
                }
            }

            if (employerFields.TryGetValue("Address", out DocumentField? addressField))
            {
                if (addressField.FieldType == DocumentFieldType.Address)
                {
                    Console.WriteLine($"Employer Address: '{addressField.Content}', with confidence {addressField.Confidence}");
                }
            }
        }
    }
}

Посетите репозиторий примеров Azure на сайте GitHub и просмотрите выходные данные налоговой модели W-2.

Использование модели счета

using Azure;
using Azure.AI.DocumentIntelligence;

//use your `key` and `endpoint` environment variables to create your `AzureKeyCredential` and `DocumentIntelligenceClient` instances
string key = Environment.GetEnvironmentVariable("DI_KEY");
string endpoint = Environment.GetEnvironmentVariable("DI_ENDPOINT");
AzureKeyCredential credential = new AzureKeyCredential(key);
DocumentIntelligenceClient client = new DocumentIntelligenceClient(new Uri(endpoint), credential);

// sample document document
Uri invoiceUri = new Uri("https://github.com/Azure-Samples/cognitive-services-REST-api-samples/raw/master/curl/form-recognizer/rest-api/invoice.pdf");

Operation<AnalyzeResult> operation = await client.AnalyzeDocumentAsync(WaitUntil.Completed, "prebuilt-invoice", invoiceUri);

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.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}");
        }
    }
}

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные данные модели счета.

Использование модели квитанции


using Azure;
using Azure.AI.DocumentIntelligence;

//use your `key` and `endpoint` environment variables to create your `AzureKeyCredential` and `DocumentIntelligenceClient` instances
string key = Environment.GetEnvironmentVariable("DI_KEY");
string endpoint = Environment.GetEnvironmentVariable("DI_ENDPOINT");
AzureKeyCredential credential = new AzureKeyCredential(key);
DocumentIntelligenceClient client = new DocumentIntelligenceClient(new Uri(endpoint), credential);

// sample document document
Uri receiptUri = new Uri("https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/receipt.png");

Operation<AnalyzeResult> operation = await client.AnalyzeDocumentAsync(WaitUntil.Completed, "prebuilt-receipt", receiptUri);

AnalyzeResult receipts = operation.Value;

foreach (AnalyzedDocument receipt in receipts.Documents)
{
    if (receipt.Fields.TryGetValue("MerchantName", out DocumentField merchantNameField))
    {
        if (merchantNameField.FieldType == DocumentFieldType.String)
        {
            string merchantName = merchantNameField.Value.AsString();

            Console.WriteLine($"Merchant Name: '{merchantName}', with confidence {merchantNameField.Confidence}");
        }
    }

    if (receipt.Fields.TryGetValue("TransactionDate", out DocumentField transactionDateField))
    {
        if (transactionDateField.FieldType == DocumentFieldType.Date)
        {
            DateTimeOffset transactionDate = transactionDateField.Value.AsDate();

            Console.WriteLine($"Transaction Date: '{transactionDate}', with confidence {transactionDateField.Confidence}");
        }
    }

    if (receipt.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("TotalPrice", out DocumentField itemTotalPriceField))
                    {
                        if (itemTotalPriceField.FieldType == DocumentFieldType.Double)
                        {
                            double itemTotalPrice = itemTotalPriceField.Value.AsDouble();

                            Console.WriteLine($"  Total Price: '{itemTotalPrice}', with confidence {itemTotalPriceField.Confidence}");
                        }
                    }
                }
            }
        }
    }

    if (receipt.Fields.TryGetValue("Total", out DocumentField totalField))
    {
        if (totalField.FieldType == DocumentFieldType.Double)
        {
            double total = totalField.Value.AsDouble();

            Console.WriteLine($"Total: '{total}', with confidence '{totalField.Confidence}'");
        }
    }
}

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные данные модели квитанций.

Использование модели удостоверения


using Azure;
using Azure.AI.DocumentIntelligence;

//use your `key` and `endpoint` environment variables to create your `AzureKeyCredential` and `DocumentIntelligenceClient` instances
string key = Environment.GetEnvironmentVariable("DI_KEY");
string endpoint = Environment.GetEnvironmentVariable("DI_ENDPOINT");
AzureKeyCredential credential = new AzureKeyCredential(key);
DocumentIntelligenceClient client = new DocumentIntelligenceClient(new Uri(endpoint), credential);

// sample document document

Uri idDocumentUri = new Uri("https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/identity_documents.png");

Operation<AnalyzeResult> operation = await client.AnalyzeDocumentAsync(WaitUntil.Completed, "prebuilt-idDocument", idDocumentUri);

AnalyzeResult identityDocuments = operation.Value;

AnalyzedDocument identityDocument = identityDocuments.Documents.Single();

if (identityDocument.Fields.TryGetValue("Address", out DocumentField addressField))
{
    if (addressField.FieldType == DocumentFieldType.String)
    {
        string address = addressField.Value. AsString();
        Console.WriteLine($"Address: '{address}', with confidence {addressField.Confidence}");
    }
}

if (identityDocument.Fields.TryGetValue("CountryRegion", out DocumentField countryRegionField))
{
    if (countryRegionField.FieldType == DocumentFieldType.CountryRegion)
    {
        string countryRegion = countryRegionField.Value.AsCountryRegion();
        Console.WriteLine($"CountryRegion: '{countryRegion}', with confidence {countryRegionField.Confidence}");
    }
}

if (identityDocument.Fields.TryGetValue("DateOfBirth", out DocumentField dateOfBirthField))
{
    if (dateOfBirthField.FieldType == DocumentFieldType.Date)
    {
        DateTimeOffset dateOfBirth = dateOfBirthField.Value.AsDate();
        Console.WriteLine($"Date Of Birth: '{dateOfBirth}', with confidence {dateOfBirthField.Confidence}");
    }
}

if (identityDocument.Fields.TryGetValue("DateOfExpiration", out DocumentField dateOfExpirationField))
{
    if (dateOfExpirationField.FieldType == DocumentFieldType.Date)
    {
        DateTimeOffset dateOfExpiration = dateOfExpirationField.Value.AsDate();
        Console.WriteLine($"Date Of Expiration: '{dateOfExpiration}', with confidence {dateOfExpirationField.Confidence}");
    }
}

if (identityDocument.Fields.TryGetValue("DocumentNumber", out DocumentField documentNumberField))
{
    if (documentNumberField.FieldType == DocumentFieldType.String)
    {
        string documentNumber = documentNumberField.Value.AsString();
        Console.WriteLine($"Document Number: '{documentNumber}', with confidence {documentNumberField.Confidence}");
    }
}

if (identityDocument.Fields.TryGetValue("FirstName", out DocumentField firstNameField))
{
    if (firstNameField.FieldType == DocumentFieldType.String)
    {
        string firstName = firstNameField.Value.AsString();
        Console.WriteLine($"First Name: '{firstName}', with confidence {firstNameField.Confidence}");
    }
}

if (identityDocument.Fields.TryGetValue("LastName", out DocumentField lastNameField))
{
    if (lastNameField.FieldType == DocumentFieldType.String)
    {
        string lastName = lastNameField.Value.AsString();
        Console.WriteLine($"Last Name: '{lastName}', with confidence {lastNameField.Confidence}");
    }
}

if (identityDocument.Fields.TryGetValue("Region", out DocumentField regionfield))
{
    if (regionfield.FieldType == DocumentFieldType.String)
    {
        string region = regionfield.Value.AsString();
        Console.WriteLine($"Region: '{region}', with confidence {regionfield.Confidence}");
    }
}

if (identityDocument.Fields.TryGetValue("Sex", out DocumentField sexfield))
{
    if (sexfield.FieldType == DocumentFieldType.String)
    {
        string sex = sexfield.Value.AsString();
        Console.WriteLine($"Sex: '{sex}', with confidence {sexfield.Confidence}");
    }
}

Посетите репозиторий примеров Azure на сайте GitHub и просмотрите выходные данные модели документов идентификатора.

Необходимые компоненты

Настройка переменных среды

Чтобы взаимодействовать со службой аналитики DocumentAnalysisClient документов, необходимо создать экземпляр класса. Для этого создайте экземпляр клиента с портал Azure key endpoint. Для этого проекта используйте переменные среды для хранения и доступа к учетным данным.

Внимание

Если вы используете ключ API, сохраните его в другом месте, например в Azure Key Vault. Не включайте ключ API непосредственно в код и никогда не публикуйте его.

Дополнительные сведения о безопасности служб ИИ см. в статье "Проверка подлинности запросов к службам ИИ Azure".

Чтобы задать переменную среды для ключа ресурса Аналитики документов, откройте окно консоли и следуйте инструкциям в вашей операционной системе и среде разработки. Замените <yourKey> и <yourEndpoint> значениями из ресурса в портал Azure.

Переменные среды в Windows не учитывает регистр. Они обычно объявляются в верхнем регистре, с словами, присоединенными подчеркиванием. В командной строке выполните следующие команды:

  1. Задайте ключевую переменную:

    setx DI_KEY <yourKey>
    
  2. Настройка переменной конечной точки

    setx DI_ENDPOINT <yourEndpoint>
    
  3. Закройте окно командной строки после задания переменных среды. Значения остаются до тех пор, пока не измените их еще раз.

  4. Перезапустите все запущенные программы, которые считывают переменную среды. Например, если вы используете Visual Studio или Visual Studio Code в качестве редактора, перезапустите перед запуском примера кода.

Ниже приведены несколько дополнительных полезных команд для использования с переменными среды:

Команда Действие Пример
setx VARIABLE_NAME= Удалите переменную среды, задав значение пустой строке. setx DI_KEY=
setx VARIABLE_NAME=value Задайте или измените значение переменной среды. setx DI_KEY=<yourKey>
set VARIABLE_NAME Отображение значения определенной переменной среды. set DI_KEY
set Отображение всех переменных среды. set

Настройка среды программирования

  1. Запустите Visual Studio.

  2. На начальной странице выберите Создать проект.

    Снимок экрана: окно запуска Visual Studio.

  3. На странице Создание проекта введите в поле поиска консоль. Выберите шаблон консольного приложения , а затем нажмите кнопку "Далее".

    Снимок экрана: страница создания проекта Visual Studio.

  4. На странице "Настройка нового проекта" в поле "Имя проекта" введите docIntelligence_app. Затем выберите Далее.

    Снимок экрана: страница настройки нового проекта Visual Studio.

  5. На странице "Дополнительные сведения" выберите .NET 8.0 (долгосрочная поддержка) и нажмите кнопку "Создать".

    Снимок экрана: страница дополнительных сведений Visual Studio.

Установка клиентской библиотеки с помощью NuGet

  1. Щелкните правой кнопкой мыши проект docIntelligence_app и выберите "Управление пакетами NuGet...".

    Снимок экрана: окно выбранного пакета NuGet в Visual Studio.

  2. Выберите вкладку "Обзор" и введите Azure.AI.FormRecognizer.

    Снимок экрана: выбор предварительного пакета NuGet в Visual Studio.

  3. Выберите версию из раскрывающегося меню и установите пакет в проекте.

Сборка приложения

Примечание.

Начиная с .NET 6, в новых проектах, где используется шаблон console, создается новый стиль программы, отличный от предыдущих версий. В новых выходных данных используются последние функции C#, упрощающие код, который необходимо написать.

При использовании более новой версии необходимо только написать текст метода Main. Вам не нужно включать инструкции верхнего уровня, глобальные директивы using или неявные директивы using. Дополнительные сведения см. в разделе шаблон консольного приложения C#, который создает инструкции верхнего уровня.

  1. Откройте файл Program.cs.

  2. Удалите существующий код, включая строку Console.Writeline("Hello World!").

  3. Выберите один из следующих примеров кода и скопируйте и вставьте в файл Program.cs приложения:

  4. После добавления примера кода в приложение нажмите зеленую кнопку "Пуск " рядом с именем проекта, чтобы создать и запустить программу, или нажмите клавишу F5.

    Снимок экрана: запуск программы Visual Studio.

Использование модели чтения

using Azure;
using Azure.AI.FormRecognizer.DocumentAnalysis;

//use your `key` and `endpoint` environment variables to create your `AzureKeyCredential` and `DocumentAnalysisClient` instances
string key = Environment.GetEnvironmentVariable("DI_KEY");
string endpoint = Environment.GetEnvironmentVariable("DI_ENDPOINT");
AzureKeyCredential credential = new AzureKeyCredential(key);
DocumentAnalysisClient client = new DocumentAnalysisClient(new Uri(endpoint), credential);

//sample document
Uri fileUri = new Uri("https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/read.png");

AnalyzeDocumentOperation operation = await client.AnalyzeDocumentFromUriAsync(WaitUntil.Completed, "prebuilt-read", 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}");
        }
    }
}

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("Detected languages:");

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

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные read данные модели.

Использование модели макета

using Azure;
using Azure.AI.FormRecognizer.DocumentAnalysis;

//use your `key` and `endpoint` environment variables to create your `AzureKeyCredential` and `DocumentAnalysisClient` instances
string key = Environment.GetEnvironmentVariable("DI_KEY");
string endpoint = Environment.GetEnvironmentVariable("DI_ENDPOINT");
AzureKeyCredential credential = new AzureKeyCredential(key);
DocumentAnalysisClient client = new DocumentAnalysisClient(new Uri(endpoint), credential);

// sample document document
Uri fileUri = new Uri ("https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/layout.png");

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}'.");
    }
}

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные данные модели макета.

Использование модели общего документа

using Azure;
using Azure.AI.FormRecognizer.DocumentAnalysis;

//use your `key` and `endpoint` environment variables to create your `AzureKeyCredential` and `DocumentAnalysisClient` instances
string key = Environment.GetEnvironmentVariable("DI_KEY");
string endpoint = Environment.GetEnvironmentVariable("DI_ENDPOINT");
AzureKeyCredential credential = new AzureKeyCredential(key);
DocumentAnalysisClient client = new DocumentAnalysisClient(new Uri(endpoint), credential);

// sample document document
Uri fileUri = new Uri("https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/sample-layout.pdf");

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}'.");
    }
}

Посетите репозиторий примеров Azure на GitHub и просмотрите общие выходные данные модели документов.

Использование налоговой модели W-2


using Azure;
using Azure.AI.FormRecognizer.DocumentAnalysis;

//use your `key` and `endpoint` environment variables to create your `AzureKeyCredential` and `DocumentAnalysisClient` instances
string key = Environment.GetEnvironmentVariable("DI_KEY");
string endpoint = Environment.GetEnvironmentVariable("DI_ENDPOINT");
AzureKeyCredential credential = new AzureKeyCredential(key);
DocumentAnalysisClient client = new DocumentAnalysisClient(new Uri(endpoint), credential);

// sample document document
Uri w2Uri = new Uri("https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/w2.png");

AnalyzeDocumentOperation operation = await client.AnalyzeDocumentFromUriAsync(WaitUntil.Completed, "prebuilt-tax.us.w2", w2Uri);

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("AdditionalInfo", out DocumentField? additionalInfoField))
    {
        if (additionalInfoField.FieldType == DocumentFieldType.List)
        {
            foreach (DocumentField infoField in additionalInfoField.Value.AsList())
            {
                Console.WriteLine("AdditionalInfo:");

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

                    if (infoFields.TryGetValue("Amount", out DocumentField? amountField))
                    {
                        if (amountField.FieldType == DocumentFieldType.Double)
                        {
                            double amount = amountField.Value.AsDouble();

                            Console.WriteLine($"  Amount: '{amount}', with confidence {amountField.Confidence}");
                        }
                    }

                    if (infoFields.TryGetValue("LetterCode", out DocumentField? letterCodeField))
                    {
                        if (letterCodeField.FieldType == DocumentFieldType.String)
                        {
                            string letterCode = letterCodeField.Value.AsString();

                            Console.WriteLine($"  LetterCode: '{letterCode}', with confidence {letterCodeField.Confidence}");
                        }
                    }
                }
            }
        }
    }


    if (document.Fields.TryGetValue("AllocatedTips", out DocumentField? allocatedTipsField))
    {
        if (allocatedTipsField.FieldType == DocumentFieldType.Double)
        {
            double allocatedTips = allocatedTipsField.Value.AsDouble();
            Console.WriteLine($"Allocated Tips: '{allocatedTips}', with confidence {allocatedTipsField.Confidence}");
        }
    }

    if (document.Fields.TryGetValue("Employer", out DocumentField? employerField))
    {
        if (employerField.FieldType == DocumentFieldType.Dictionary)
        {
            IReadOnlyDictionary<string, DocumentField> employerFields = employerField.Value.AsDictionary();

            if (employerFields.TryGetValue("Name", out DocumentField? employerNameField))
            {
                if (employerNameField.FieldType == DocumentFieldType.String)
                {
                    string name = employerNameField.Value.AsString();

                    Console.WriteLine($"Employer Name: '{name}', with confidence {employerNameField.Confidence}");
                }
            }

            if (employerFields.TryGetValue("IdNumber", out DocumentField? idNumberField))
            {
                if (idNumberField.FieldType == DocumentFieldType.String)
                {
                    string id = idNumberField.Value.AsString();

                    Console.WriteLine($"Employer ID Number: '{id}', with confidence {idNumberField.Confidence}");
                }
            }

            if (employerFields.TryGetValue("Address", out DocumentField? addressField))
            {
                if (addressField.FieldType == DocumentFieldType.Address)
                {
                    Console.WriteLine($"Employer Address: '{addressField.Content}', with confidence {addressField.Confidence}");
                }
            }
        }
    }
}

Посетите репозиторий примеров Azure на сайте GitHub и просмотрите выходные данные налоговой модели W-2.

Использование модели счета

using Azure;
using Azure.AI.FormRecognizer.DocumentAnalysis;

//use your `key` and `endpoint` environment variables to create your `AzureKeyCredential` and `DocumentAnalysisClient` instances
string key = Environment.GetEnvironmentVariable("DI_KEY");
string endpoint = Environment.GetEnvironmentVariable("DI_ENDPOINT");
AzureKeyCredential credential = new AzureKeyCredential(key);
DocumentAnalysisClient client = new DocumentAnalysisClient(new Uri(endpoint), credential);

// sample document document
Uri invoiceUri = new Uri("https://github.com/Azure-Samples/cognitive-services-REST-api-samples/raw/master/curl/form-recognizer/rest-api/invoice.pdf");

AnalyzeDocumentOperation operation = await client.AnalyzeDocumentFromUriAsync(WaitUntil.Completed, "prebuilt-invoice", invoiceUri);

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.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}");
        }
    }
}

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные данные модели счета.

Использование модели квитанции


using Azure;
using Azure.AI.FormRecognizer.DocumentAnalysis;

//use your `key` and `endpoint` environment variables to create your `AzureKeyCredential` and `DocumentAnalysisClient` instances
string key = Environment.GetEnvironmentVariable("DI_KEY");
string endpoint = Environment.GetEnvironmentVariable("DI_ENDPOINT");
AzureKeyCredential credential = new AzureKeyCredential(key);
DocumentAnalysisClient client = new DocumentAnalysisClient(new Uri(endpoint), credential);

// sample document document
Uri receiptUri = new Uri("https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/receipt.png");

AnalyzeDocumentOperation operation = await client.AnalyzeDocumentFromUriAsync(WaitUntil.Completed, "prebuilt-receipt", receiptUri);

AnalyzeResult receipts = operation.Value;

foreach (AnalyzedDocument receipt in receipts.Documents)
{
    if (receipt.Fields.TryGetValue("MerchantName", out DocumentField merchantNameField))
    {
        if (merchantNameField.FieldType == DocumentFieldType.String)
        {
            string merchantName = merchantNameField.Value.AsString();

            Console.WriteLine($"Merchant Name: '{merchantName}', with confidence {merchantNameField.Confidence}");
        }
    }

    if (receipt.Fields.TryGetValue("TransactionDate", out DocumentField transactionDateField))
    {
        if (transactionDateField.FieldType == DocumentFieldType.Date)
        {
            DateTimeOffset transactionDate = transactionDateField.Value.AsDate();

            Console.WriteLine($"Transaction Date: '{transactionDate}', with confidence {transactionDateField.Confidence}");
        }
    }

    if (receipt.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("TotalPrice", out DocumentField itemTotalPriceField))
                    {
                        if (itemTotalPriceField.FieldType == DocumentFieldType.Double)
                        {
                            double itemTotalPrice = itemTotalPriceField.Value.AsDouble();

                            Console.WriteLine($"  Total Price: '{itemTotalPrice}', with confidence {itemTotalPriceField.Confidence}");
                        }
                    }
                }
            }
        }
    }

    if (receipt.Fields.TryGetValue("Total", out DocumentField totalField))
    {
        if (totalField.FieldType == DocumentFieldType.Double)
        {
            double total = totalField.Value.AsDouble();

            Console.WriteLine($"Total: '{total}', with confidence '{totalField.Confidence}'");
        }
    }
}

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные данные модели квитанций.

Модель удостоверения


using Azure;
using Azure.AI.FormRecognizer.DocumentAnalysis;

//use your `key` and `endpoint` environment variables to create your `AzureKeyCredential` and `DocumentAnalysisClient` instances
string key = Environment.GetEnvironmentVariable("DI_KEY");
string endpoint = Environment.GetEnvironmentVariable("DI_ENDPOINT");
AzureKeyCredential credential = new AzureKeyCredential(key);
DocumentAnalysisClient client = new DocumentAnalysisClient(new Uri(endpoint), credential);

// sample document document

Uri idDocumentUri = new Uri("https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/identity_documents.png");

AnalyzeDocumentOperation operation = await client.AnalyzeDocumentFromUriAsync(WaitUntil.Completed, "prebuilt-idDocument", idDocumentUri);

AnalyzeResult identityDocuments = operation.Value;

AnalyzedDocument identityDocument = identityDocuments.Documents.Single();

if (identityDocument.Fields.TryGetValue("Address", out DocumentField addressField))
{
    if (addressField.FieldType == DocumentFieldType.String)
    {
        string address = addressField.Value. AsString();
        Console.WriteLine($"Address: '{address}', with confidence {addressField.Confidence}");
    }
}

if (identityDocument.Fields.TryGetValue("CountryRegion", out DocumentField countryRegionField))
{
    if (countryRegionField.FieldType == DocumentFieldType.CountryRegion)
    {
        string countryRegion = countryRegionField.Value.AsCountryRegion();
        Console.WriteLine($"CountryRegion: '{countryRegion}', with confidence {countryRegionField.Confidence}");
    }
}

if (identityDocument.Fields.TryGetValue("DateOfBirth", out DocumentField dateOfBirthField))
{
    if (dateOfBirthField.FieldType == DocumentFieldType.Date)
    {
        DateTimeOffset dateOfBirth = dateOfBirthField.Value.AsDate();
        Console.WriteLine($"Date Of Birth: '{dateOfBirth}', with confidence {dateOfBirthField.Confidence}");
    }
}

if (identityDocument.Fields.TryGetValue("DateOfExpiration", out DocumentField dateOfExpirationField))
{
    if (dateOfExpirationField.FieldType == DocumentFieldType.Date)
    {
        DateTimeOffset dateOfExpiration = dateOfExpirationField.Value.AsDate();
        Console.WriteLine($"Date Of Expiration: '{dateOfExpiration}', with confidence {dateOfExpirationField.Confidence}");
    }
}

if (identityDocument.Fields.TryGetValue("DocumentNumber", out DocumentField documentNumberField))
{
    if (documentNumberField.FieldType == DocumentFieldType.String)
    {
        string documentNumber = documentNumberField.Value.AsString();
        Console.WriteLine($"Document Number: '{documentNumber}', with confidence {documentNumberField.Confidence}");
    }
}

if (identityDocument.Fields.TryGetValue("FirstName", out DocumentField firstNameField))
{
    if (firstNameField.FieldType == DocumentFieldType.String)
    {
        string firstName = firstNameField.Value.AsString();
        Console.WriteLine($"First Name: '{firstName}', with confidence {firstNameField.Confidence}");
    }
}

if (identityDocument.Fields.TryGetValue("LastName", out DocumentField lastNameField))
{
    if (lastNameField.FieldType == DocumentFieldType.String)
    {
        string lastName = lastNameField.Value.AsString();
        Console.WriteLine($"Last Name: '{lastName}', with confidence {lastNameField.Confidence}");
    }
}

if (identityDocument.Fields.TryGetValue("Region", out DocumentField regionfield))
{
    if (regionfield.FieldType == DocumentFieldType.String)
    {
        string region = regionfield.Value.AsString();
        Console.WriteLine($"Region: '{region}', with confidence {regionfield.Confidence}");
    }
}

if (identityDocument.Fields.TryGetValue("Sex", out DocumentField sexfield))
{
    if (sexfield.FieldType == DocumentFieldType.String)
    {
        string sex = sexfield.Value.AsString();
        Console.WriteLine($"Sex: '{sex}', with confidence {sexfield.Confidence}");
    }
}

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные данные модели id-document.

Использование модели визитной карточки

using Azure;
using Azure.AI.FormRecognizer.DocumentAnalysis;

//use your `key` and `endpoint` environment variables to create your `AzureKeyCredential` and `DocumentAnalysisClient` instances
string key = Environment.GetEnvironmentVariable("DI_KEY");
string endpoint = Environment.GetEnvironmentVariable("DI_ENDPOINT");
AzureKeyCredential credential = new AzureKeyCredential(key);
DocumentAnalysisClient client = new DocumentAnalysisClient(new Uri(endpoint), credential);

// sample document document
Uri businessCardUri = new Uri("https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/business-card-english.jpg");

AnalyzeDocumentOperation operation = await client.AnalyzeDocumentFromUriAsync(WaitUntil.Completed, "prebuilt-businessCard", businessCardUri);

AnalyzeResult businessCards = operation.Value;

foreach (AnalyzedDocument businessCard in businessCards.Documents)
{
    if (businessCard.Fields.TryGetValue("ContactNames", out DocumentField ContactNamesField))
    {
        if (ContactNamesField.FieldType == DocumentFieldType.List)
        {
            foreach (DocumentField contactNameField in ContactNamesField.Value.AsList())
            {
                Console.WriteLine("Contact Name: ");

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

                    if (contactNameFields.TryGetValue("FirstName", out DocumentField firstNameField))
                    {
                        if (firstNameField.FieldType == DocumentFieldType.String)
                        {
                            string firstName = firstNameField.Value.AsString();

                            Console.WriteLine($"  First Name: '{firstName}', with confidence {firstNameField.Confidence}");
                        }
                    }

                    if (contactNameFields.TryGetValue("LastName", out DocumentField lastNameField))
                    {
                        if (lastNameField.FieldType == DocumentFieldType.String)
                        {
                            string lastName = lastNameField.Value.AsString();

                            Console.WriteLine($"  Last Name: '{lastName}', with confidence {lastNameField.Confidence}");
                        }
                    }
                }
            }
        }
    }

    if (businessCard.Fields.TryGetValue("JobTitles", out DocumentField jobTitlesFields))
    {
        if (jobTitlesFields.FieldType == DocumentFieldType.List)
        {
            foreach (DocumentField jobTitleField in jobTitlesFields.Value.AsList())
            {
                if (jobTitleField.FieldType == DocumentFieldType.String)
                {
                    string jobTitle = jobTitleField.Value.AsString();

                    Console.WriteLine($"Job Title: '{jobTitle}', with confidence {jobTitleField.Confidence}");
                }
            }
        }
    }

    if (businessCard.Fields.TryGetValue("Departments", out DocumentField departmentFields))
    {
        if (departmentFields.FieldType == DocumentFieldType.List)
        {
            foreach (DocumentField departmentField in departmentFields.Value.AsList())
            {
                if (departmentField.FieldType == DocumentFieldType.String)
                {
                    string department = departmentField.Value.AsString();

                    Console.WriteLine($"Department: '{department}', with confidence {departmentField.Confidence}");
                }
            }
        }
    }

    if (businessCard.Fields.TryGetValue("Emails", out DocumentField emailFields))
    {
        if (emailFields.FieldType == DocumentFieldType.List)
        {
            foreach (DocumentField emailField in emailFields.Value.AsList())
            {
                if (emailField.FieldType == DocumentFieldType.String)
                {
                    string email = emailField.Value.AsString();

                    Console.WriteLine($"Email: '{email}', with confidence {emailField.Confidence}");
                }
            }
        }
    }

    if (businessCard.Fields.TryGetValue("Websites", out DocumentField websiteFields))
    {
        if (websiteFields.FieldType == DocumentFieldType.List)
        {
            foreach (DocumentField websiteField in websiteFields.Value.AsList())
            {
                if (websiteField.FieldType == DocumentFieldType.String)
                {
                    string website = websiteField.Value.AsString();

                    Console.WriteLine($"Website: '{website}', with confidence {websiteField.Confidence}");
                }
            }
        }
    }

    if (businessCard.Fields.TryGetValue("MobilePhones", out DocumentField mobilePhonesFields))
    {
        if (mobilePhonesFields.FieldType == DocumentFieldType.List)
        {
            foreach (DocumentField mobilePhoneField in mobilePhonesFields.Value.AsList())
            {
                if (mobilePhoneField.FieldType == DocumentFieldType.PhoneNumber)
                {
                    string mobilePhone = mobilePhoneField.Value.AsPhoneNumber();

                    Console.WriteLine($"Mobile phone number: '{mobilePhone}', with confidence {mobilePhoneField.Confidence}");
                }
            }
        }
    }

    if (businessCard.Fields.TryGetValue("WorkPhones", out DocumentField workPhonesFields))
    {
        if (workPhonesFields.FieldType == DocumentFieldType.List)
        {
            foreach (DocumentField workPhoneField in workPhonesFields.Value.AsList())
            {
                if (workPhoneField.FieldType == DocumentFieldType.PhoneNumber)
                {
                    string workPhone = workPhoneField.Value.AsPhoneNumber();

                    Console.WriteLine($"Work phone number: '{workPhone}', with confidence {workPhoneField.Confidence}");
                }
            }
        }
    }

    if (businessCard.Fields.TryGetValue("Faxes", out DocumentField faxesFields))
    {
        if (faxesFields.FieldType == DocumentFieldType.List)
        {
            foreach (DocumentField faxField in faxesFields.Value.AsList())
            {
                if (faxField.FieldType == DocumentFieldType.PhoneNumber)
                {
                    string fax = faxField.Value.AsPhoneNumber();

                    Console.WriteLine($"Fax phone number: '{fax}', with confidence {faxField.Confidence}");
                }
            }
        }
    }

    if (businessCard.Fields.TryGetValue("Addresses", out DocumentField addressesFields))
    {
        if (addressesFields.FieldType == DocumentFieldType.List)
        {
            foreach (DocumentField addressField in addressesFields.Value.AsList())
            {
                if (addressField.FieldType == DocumentFieldType.String)
                {
                    string address = addressField.Value.AsString();

                    Console.WriteLine($"Address: '{address}', with confidence {addressField.Confidence}");
                }
            }
        }
    }

    if (businessCard.Fields.TryGetValue("CompanyNames", out DocumentField companyNamesFields))
    {
        if (companyNamesFields.FieldType == DocumentFieldType.List)
        {
            foreach (DocumentField companyNameField in companyNamesFields.Value.AsList())
            {
                if (companyNameField.FieldType == DocumentFieldType.String)
                {
                    string companyName = companyNameField.Value.AsString();

                    Console.WriteLine($"Company name: '{companyName}', with confidence {companyNameField.Confidence}");
                }
            }
        }
    }
}

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные данные модели визитных карточек.

Справочник по | пакету REST API для | пакета SDK для клиентской библиотеки | (Maven) | Примеры |поддерживаемой версии REST API

Необходимые компоненты

  • Подписка Azure — создайте бесплатную учетную запись.

  • Последняя версия Visual Studio Code или предпочтительная интегрированная среда разработки. См. Java в Visual Studio Code.

    • Visual Studio Code предлагает пакет кода для Java для Windows и macOS. Пакет кода — это пакет кода, пакет средств разработки VS Java (JDK) и коллекция предлагаемых расширений корпорацией Майкрософт. Пакет кодировки можно также использовать для исправления существующей среды разработки.
    • Если вы используете VS код и пакет кода для Java, установите расширение Gradle для Java .

    Если вы не используете Visual Studio Code, убедитесь, что в среде разработки установлено следующее:

  • Служба ИИ Azure или ресурс аналитики документов. Создание одной службы или нескольких служб. Используйте бесплатную ценовую категорию (F0), чтобы опробовать службу, а затем выполните обновление до платного уровня для рабочей среды.

    Совет

    Создайте ресурс служб ИИ Azure, если вы планируете получить доступ к нескольким службам ИИ Azure с помощью одной конечной точки и ключа. Только для доступа к аналитике документов создайте ресурс аналитики документов. Если вы планируете использовать проверку подлинности Microsoft Entra, вам потребуется ресурс с одним обслуживанием.

  • Ключ и конечная точка из ресурса, создаваемого для подключения приложения к службе аналитики документов Azure.

    1. После развертывания ресурса выберите Перейти к ресурсу.
    2. В меню навигации слева выберите "Ключи" и "Конечная точка".
    3. Скопируйте один из ключей и конечной точки для использования далее в этой статье.

    Снимок экрана: расположение ключей и конечной точки на портале Azure.

  • Файл документа по URL-адресу. Для этого проекта можно использовать примеры форм, указанных в следующей таблице для каждой функции:

    Функция modelID document-url
    Модель чтения prebuilt-read Пример брошюры
    Модель макета prebuilt-layout Пример подтверждения резервирования
    Модель с формой W-2 prebuilt-tax.us.w2 Пример формы W-2
    Модель накладных prebuilt-invoice Пример счета
    Модель получения prebuilt-receipt Пример квитанции
    Модель документа идентификатора prebuilt-idDocument Пример удостоверения

Настройка переменных среды

Чтобы взаимодействовать со службой аналитики DocumentAnalysisClient документов, необходимо создать экземпляр класса. Для этого создайте экземпляр клиента с портал Azure key endpoint. Для этого проекта используйте переменные среды для хранения и доступа к учетным данным.

Внимание

Если вы используете ключ API, сохраните его в другом месте, например в Azure Key Vault. Не включайте ключ API непосредственно в код и никогда не публикуйте его.

Дополнительные сведения о безопасности служб ИИ см. в статье "Проверка подлинности запросов к службам ИИ Azure".

Чтобы задать переменную среды для ключа ресурса Аналитики документов, откройте окно консоли и следуйте инструкциям в вашей операционной системе и среде разработки. Замените <yourKey> и <yourEndpoint> значениями из ресурса в портал Azure.

Переменные среды в Windows не учитывает регистр. Они обычно объявляются в верхнем регистре, с словами, присоединенными подчеркиванием. В командной строке выполните следующие команды:

  1. Задайте ключевую переменную:

    setx DI_KEY <yourKey>
    
  2. Настройка переменной конечной точки

    setx DI_ENDPOINT <yourEndpoint>
    
  3. Закройте окно командной строки после задания переменных среды. Значения остаются до тех пор, пока не измените их еще раз.

  4. Перезапустите все запущенные программы, которые считывают переменную среды. Например, если вы используете Visual Studio или Visual Studio Code в качестве редактора, перезапустите перед запуском примера кода.

Ниже приведены несколько дополнительных полезных команд для использования с переменными среды:

Команда Действие Пример
setx VARIABLE_NAME= Удалите переменную среды, задав значение пустой строке. setx DI_KEY=
setx VARIABLE_NAME=value Задайте или измените значение переменной среды. setx DI_KEY=<yourKey>
set VARIABLE_NAME Отображение значения определенной переменной среды. set DI_KEY
set Отображение всех переменных среды. set

Настройка среды программирования

Чтобы настроить среду программирования, создайте проект Gradle и установите клиентская библиотека.

Создание проекта Gradle

  1. В окне консоли создайте каталог для приложения под названием doc-intelligence-app и перейдите к нему.

    mkdir doc-intelligence-app
    cd doc-intelligence-app
    
  2. Выполните команду gradle init из рабочей папки. Эта команда создает основные файлы сборки для Gradle, включая build.gradle.kts, который используется во время выполнения для создания и настройки приложения.

    gradle init --type basic
    
  3. Когда появится запрос на выбор предметно-ориентированного языка, выберите Kotlin.

  4. Нажмите клавишу ВВОД , чтобы принять имя проекта по умолчанию, doc-intelligence-app.

Установка клиентской библиотеки

В этой статье используется диспетчер зависимостей Gradle. Клиентскую библиотеку и информацию для других диспетчеров зависимостей можно найти в центральном репозитории Maven.

  1. Откройте файл проекта Build. gradle. КТС в интегрированной среде разработки. Скопируйте и вставьте следующий код, чтобы включить клиентская библиотека в качестве implementation инструкции, а также необходимые подключаемые модули и параметры.

    plugins {
       java
       application
    }
    application {
        mainClass.set("DocIntelligence")
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        implementation group: 'com.azure', name: 'azure-ai-documentintelligence', version: '1.0.0-beta.4'
    }
    

Создание приложения Java

Чтобы взаимодействовать со службой аналитики DocumentIntelligenceClient документов, создайте экземпляр класса. Для этого вы создадите AzureKeyCredential с key помощью портал Azure и DocumentIntelligenceClient экземпляра с AzureKeyCredential помощью аналитики документовendpoint.

  1. В каталоге doc-intelligence-app выполните следующую команду:

    mkdir -p src/main/java
    

Эта команда создает следующую структуру каталогов:

Снимок экрана: структура каталогов Java

  1. Перейдите java в каталог и создайте файл с именем DocIntelligence.java.

    Совет

    Новый файл можно создать с помощью PowerShell. Откройте окно PowerShell в каталоге проекта, удерживая клавишу SHIFT и щелкнув правой кнопкой мыши папку, а затем введите следующую команду: New-Item DocIntelligence.java.

  2. Откройте файл DocIntelligence.java и выберите один из следующих примеров кода И скопируйте и вставьте в приложение:

    • Предварительно созданная модель чтения находится в основе всех моделей аналитики документов и может обнаруживать строки, слова, расположения и языки. Макет, общие документы, предварительно созданные и пользовательские модели используют read модель в качестве основы для извлечения текстов из документов.
    • Предварительно созданная модель макета извлекает текстовые и текстовые расположения, таблицы, знаки выделения и сведения о структуре из документов и изображений.
    • Предварительно созданная модель tax.us.w2 извлекает информацию о налоговых формах внутренней налоговой службы США (IRS).
    • Предварительно созданная модель счета извлекает ключевые поля и элементы строк из счетов-фактур продаж в различных форматах.
    • Предварительно созданная модель квитанций извлекает ключевые сведения из печатных и рукописных квитанций о продажах.
    • Предварительно созданная модель idDocument извлекает ключевые сведения из лицензий водителей США; международные биографические страницы паспортов; Идентификаторы штатов США; карточки социального страхования; и постоянные карточки резидентов.
  3. Введите такие команды:

    gradle build
    gradle run
    

Использование модели чтения

import com.azure.ai.documentintelligence;

import com.azure.ai.documentintelligence.models.AnalyzeDocumentRequest;
import com.azure.ai.documentintelligence.models.AnalyzeResult;
import com.azure.ai.documentintelligence.models.AnalyzeResultOperation;
import com.azure.ai.documentintelligence.models.Document;
import com.azure.ai.documentintelligence.models.DocumentField;
import com.azure.ai.documentintelligence.models.DocumentFieldType;
import com.azure.core.credential.AzureKeyCredential;
import com.azure.core.util.polling.SyncPoller;

import java.io.IOException;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;


public class DocIntelligence {

  //use your `key` and `endpoint` environment variables
  private static final String key = System.getenv("FR_KEY");
  private static final String endpoint = System.getenv("FR_ENDPOINT");

  public static void main(final String[] args) {

      // create your `DocumentIntelligenceClient` instance and `AzureKeyCredential` variable
      DocumentIntelligenceClient client = new DocumentIntelligenceClientBuilder()
        .credential(new AzureKeyCredential(key))
        .endpoint(endpoint)
        .buildClient();

//sample document
String documentUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/read.png";

String modelId = "prebuilt-read";

SyncPoller < OperationResult, AnalyzeResult > analyzeLayoutResultPoller =
  client.beginAnalyzeDocument(modelId, invoiceUrl);;

AnalyzeResult analyzeLayoutResult = analyzeLayoutResultPoller.getFinalResult().getAnalyzeResult();

// pages
analyzeLayoutResult.getPages().forEach(documentPage -> {
  System.out.printf("Page has width: %.2f and height: %.2f, measured with unit: %s%n",
    documentPage.getWidth(),
    documentPage.getHeight(),
    documentPage.getUnit());

  // lines
  documentPage.getLines().forEach(documentLine ->
    System.out.printf("Line %s is within a bounding polygon %s.%n",
      documentLine.getContent(),
      documentLine.getBoundingPolygon().toString()));

  // words
  documentPage.getWords().forEach(documentWord ->
    System.out.printf("Word '%s' has a confidence score of %.2f.%n",
      documentWord.getContent(),
      documentWord.getConfidence()));
});
}
}

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные read данные модели.

Использование модели макета

import com.azure.ai.documentintelligence;

import com.azure.ai.documentintelligence.models.AnalyzeDocumentRequest;
import com.azure.ai.documentintelligence.models.AnalyzeResult;
import com.azure.ai.documentintelligence.models.AnalyzeResultOperation;
import com.azure.ai.documentintelligence.models.Document;
import com.azure.ai.documentintelligence.models.DocumentField;
import com.azure.ai.documentintelligence.models.DocumentFieldType;
import com.azure.core.credential.AzureKeyCredential;
import com.azure.core.util.polling.SyncPoller;

import java.io.IOException;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;

public class DocIntelligence {
  //use your `key` and `endpoint` environment variables
  private static final String key = System.getenv("FR_KEY");
  private static final String endpoint = System.getenv("FR_ENDPOINT");

  public static void main(final String[] args) {

      // create your `DocumentIntelligenceClient` instance and `AzureKeyCredential` variable
      DocumentIntelligenceClient client = new DocumentIntelligenceClientBuilder()
        .credential(new AzureKeyCredential(key))
        .endpoint(endpoint)
        .buildClient();

//sample document
String layoutDocumentUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/layout.png";
String modelId = "prebuilt-layout";

SyncPoller < OperationResult, AnalyzeResult > analyzeLayoutResultPoller =
  client.beginAnalyzeDocument(modelId, layoutDocumentUrl);

AnalyzeResult analyzeLayoutResult = analyzeLayoutResultPoller.getFinalResult().getAnalyzeResult();

// pages
analyzeLayoutResult.getPages().forEach(documentPage -> {
  System.out.printf("Page has width: %.2f and height: %.2f, measured with unit: %s%n",
    documentPage.getWidth(),
    documentPage.getHeight(),
    documentPage.getUnit());

  // lines
  documentPage.getLines().forEach(documentLine ->
    System.out.printf("Line %s is within a bounding polygon %s.%n",
      documentLine.getContent(),
      documentLine.getBoundingPolygon().toString()));

  // words
  documentPage.getWords().forEach(documentWord ->
    System.out.printf("Word '%s' has a confidence score of %.2f%n",
      documentWord.getContent(),
      documentWord.getConfidence()));

  // selection marks
  documentPage.getSelectionMarks().forEach(documentSelectionMark ->
    System.out.printf("Selection mark is '%s' and is within a bounding polygon %s with confidence %.2f.%n",
      documentSelectionMark.getSelectionMarkState().toString(),
      getBoundingCoordinates(documentSelectionMark.getBoundingPolygon()),
      documentSelectionMark.getConfidence()));
});

// tables
List < DocumentTable > tables = analyzeLayoutResult.getTables();
for (int i = 0; i < tables.size(); i++) {
  DocumentTable documentTables = tables.get(i);
  System.out.printf("Table %d has %d rows and %d columns.%n", i, documentTables.getRowCount(),
    documentTables.getColumnCount());
  documentTables.getCells().forEach(documentTableCell -> {
    System.out.printf("Cell '%s', has row index %d and column index %d.%n", documentTableCell.getContent(),
      documentTableCell.getRowIndex(), documentTableCell.getColumnIndex());
  });
  System.out.println();
}

}

// Utility function to get the bounding polygon coordinates.
private static String getBoundingCoordinates(List < Point > boundingPolygon) {
  return boundingPolygon.stream().map(point -> String.format("[%.2f, %.2f]", point.getX(),
    point.getY())).collect(Collectors.joining(", "));
}

}

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные данные модели макета.

Использование модели общего документа

import com.azure.ai.documentintelligence;

import com.azure.ai.documentintelligence.models.AnalyzeDocumentRequest;
import com.azure.ai.documentintelligence.models.AnalyzeResult;
import com.azure.ai.documentintelligence.models.AnalyzeResultOperation;
import com.azure.ai.documentintelligence.models.Document;
import com.azure.ai.documentintelligence.models.DocumentField;
import com.azure.ai.documentintelligence.models.DocumentFieldType;
import com.azure.core.credential.AzureKeyCredential;
import com.azure.core.util.polling.SyncPoller;

import java.io.IOException;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;

public class DocIntelligence {
  //use your `key` and `endpoint` environment variables
  private static final String key = System.getenv("FR_KEY");
  private static final String endpoint = System.getenv("FR_ENDPOINT");

  public static void main(final String[] args) {

      // create your `DocumentIntelligenceClient` instance and `AzureKeyCredential` variable
      DocumentIntelligenceClient client = new DocumentIntelligenceClientBuilder()
        .credential(new AzureKeyCredential(key))
        .endpoint(endpoint)
        .buildClient();

//sample document
String generalDocumentUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/sample-layout.pdf";
String modelId = "prebuilt-document";
SyncPoller < OperationResult, AnalyzeResult > analyzeDocumentPoller =
  client.beginAnalyzeDocument(modelId, generalDocumentUrl);

AnalyzeResult analyzeResult = analyzeDocumentPoller.getFinalResult().getAnalyzeResult();;

// pages
analyzeResult.getPages().forEach(documentPage -> {
  System.out.printf("Page has width: %.2f and height: %.2f, measured with unit: %s%n",
    documentPage.getWidth(),
    documentPage.getHeight(),
    documentPage.getUnit());

  // lines
  documentPage.getLines().forEach(documentLine ->
    System.out.printf("Line %s is within a bounding polygon %s.%n",
      documentLine.getContent(),
      documentLine.getBoundingPolygon().toString()));

  // words
  documentPage.getWords().forEach(documentWord ->
    System.out.printf("Word %s has a confidence score of %.2f%n.",
      documentWord.getContent(),
      documentWord.getConfidence()));
});

// tables
List < DocumentTable > tab_les = analyzeResult.getTables();
for (int i = 0; i < tab_les.size(); i++) {
  DocumentTable documentTable = tab_les.get(i);
  System.out.printf("Table %d has %d rows and %d columns.%n", i, documentTable.getRowCount(),
    documentTable.getColumnCount());
  documentTable.getCells().forEach(documentTableCell -> {
    System.out.printf("Cell '%s', has row index %d and column index %d.%n",
      documentTableCell.getContent(),
      documentTableCell.getRowIndex(), documentTableCell.getColumnIndex());
  });
  System.out.println();
}

// Key-value pairs
analyzeResult.getKeyValuePairs().forEach(documentKeyValuePair -> {
  System.out.printf("Key content: %s%n", documentKeyValuePair.getKey().getContent());
  System.out.printf("Key content bounding region: %s%n",
    documentKeyValuePair.getKey().getBoundingRegions().toString());

  if (documentKeyValuePair.getValue() != null) {
    System.out.printf("Value content: %s%n", documentKeyValuePair.getValue().getContent());
    System.out.printf("Value content bounding region: %s%n", documentKeyValuePair.getValue().getBoundingRegions().toString());
  }
});

}

}

Посетите репозиторий примеров Azure на GitHub и просмотрите общие выходные данные модели документов.

Использование налоговой модели W-2

import com.azure.ai.documentintelligence;

import com.azure.ai.documentintelligence.models.AnalyzeDocumentRequest;
import com.azure.ai.documentintelligence.models.AnalyzeResult;
import com.azure.ai.documentintelligence.models.AnalyzeResultOperation;
import com.azure.ai.documentintelligence.models.Document;
import com.azure.ai.documentintelligence.models.DocumentField;
import com.azure.ai.documentintelligence.models.DocumentFieldType;
import com.azure.core.credential.AzureKeyCredential;
import com.azure.core.util.polling.SyncPoller;

import java.io.IOException;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;

public class DocIntelligence {
  //use your `key` and `endpoint` environment variables
  private static final String key = System.getenv("FR_KEY");
  private static final String endpoint = System.getenv("FR_ENDPOINT");

  public static void main(final String[] args) {

      // create your `DocumentIntelligenceClient` instance and `AzureKeyCredential` variable
      DocumentIntelligenceClient client = new DocumentIntelligenceClientBuilder()
        .credential(new AzureKeyCredential(key))
        .endpoint(endpoint)
        .buildClient();

// sample document
String w2Url = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/w2.png";
String modelId = "prebuilt-tax.us.w2";

SyncPoller < OperationResult, AnalyzeResult > analyzeW2Poller =
  client.beginAnalyzeDocument(modelId, w2Url);

AnalyzeResult analyzeTaxResult = analyzeW2Poller.getFinalResult().getAnalyzeResult();

for (int i = 0; i < analyzeTaxResult.getDocuments().size(); i++) {
  AnalyzedDocument analyzedTaxDocument = analyzeTaxResult.getDocuments().get(i);
  Map < String, DocumentField > taxFields = analyzedTaxDocument.getFields();
  System.out.printf("----------- Analyzing Document  %d -----------%n", i);
  DocumentField w2FormVariantField = taxFields.get("W2FormVariant");
  if (w2FormVariantField != null) {
    if (DocumentFieldType.STRING == w2FormVariantField.getType()) {
      String merchantName = w2FormVariantField.getValueAsString();
      System.out.printf("Form variant: %s, confidence: %.2f%n",
        merchantName, w2FormVariantField.getConfidence());
    }
  }

  DocumentField employeeField = taxFields.get("Employee");
  if (employeeField != null) {
    System.out.println("Employee Data: ");
    if (DocumentFieldType.MAP == employeeField.getType()) {
      Map < String, DocumentField > employeeDataFieldMap = employeeField.getValueAsMap();
      DocumentField employeeName = employeeDataFieldMap.get("Name");
      if (employeeName != null) {
        if (DocumentFieldType.STRING == employeeName.getType()) {
          String employeesName = employeeName.getValueAsString();
          System.out.printf("Employee Name: %s, confidence: %.2f%n",
            employeesName, employeeName.getConfidence());
        }
      }
      DocumentField employeeAddrField = employeeDataFieldMap.get("Address");
      if (employeeAddrField != null) {
        if (DocumentFieldType.STRING == employeeAddrField.getType()) {
          String employeeAddress = employeeAddrField.getValueAsString();
          System.out.printf("Employee Address: %s, confidence: %.2f%n",
            employeeAddress, employeeAddrField.getConfidence());
        }
      }
    }
  }

  DocumentField employerField = taxFields.get("Employer");
  if (employerField != null) {
    System.out.println("Employer Data: ");
    if (DocumentFieldType.MAP == employerField.getType()) {
      Map < String, DocumentField > employerDataFieldMap = employerField.getValueAsMap();
      DocumentField employerNameField = employerDataFieldMap.get("Name");
      if (employerNameField != null) {
        if (DocumentFieldType.STRING == employerNameField.getType()) {
          String employerName = employerNameField.getValueAsString();
          System.out.printf("Employer Name: %s, confidence: %.2f%n",
            employerName, employerNameField.getConfidence());
        }
      }

      DocumentField employerIDNumberField = employerDataFieldMap.get("IdNumber");
      if (employerIDNumberField != null) {
        if (DocumentFieldType.STRING == employerIDNumberField.getType()) {
          String employerIdNumber = employerIDNumberField.getValueAsString();
          System.out.printf("Employee ID Number: %s, confidence: %.2f%n",
            employerIdNumber, employerIDNumberField.getConfidence());
        }
      }
    }
  }

  DocumentField taxYearField = taxFields.get("TaxYear");
  if (taxYearField != null) {
    if (DocumentFieldType.STRING == taxYearField.getType()) {
      String taxYear = taxYearField.getValueAsString();
      System.out.printf("Tax year: %s, confidence: %.2f%n",
        taxYear, taxYearField.getConfidence());
    }
  }

  DocumentField taxDateField = taxFields.get("TaxDate");
  if (taxDateField != null) {
    if (DocumentFieldType.DATE == taxDateField.getType()) {
      LocalDate taxDate = taxDateField.getValueAsDate();
      System.out.printf("Tax Date: %s, confidence: %.2f%n",
        taxDate, taxDateField.getConfidence());
    }
  }

  DocumentField socialSecurityTaxField = taxFields.get("SocialSecurityTaxWithheld");
  if (socialSecurityTaxField != null) {
    if (DocumentFieldType.DOUBLE == socialSecurityTaxField.getType()) {
      Double socialSecurityTax = socialSecurityTaxField.getValueAsDouble();
      System.out.printf("Social Security Tax withheld: %.2f, confidence: %.2f%n",
        socialSecurityTax, socialSecurityTaxField.getConfidence());
    }
  }
}
}
}

Посетите репозиторий примеров Azure на сайте GitHub и просмотрите выходные данные налоговой модели W-2.

Использование модели счета

import com.azure.ai.documentintelligence;

import com.azure.ai.documentintelligence.models.AnalyzeDocumentRequest;
import com.azure.ai.documentintelligence.models.AnalyzeResult;
import com.azure.ai.documentintelligence.models.AnalyzeResultOperation;
import com.azure.ai.documentintelligence.models.Document;
import com.azure.ai.documentintelligence.models.DocumentField;
import com.azure.ai.documentintelligence.models.DocumentFieldType;
import com.azure.core.credential.AzureKeyCredential;
import com.azure.core.util.polling.SyncPoller;

import java.io.IOException;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;

public class DocIntelligence {
  //use your `key` and `endpoint` environment variables
  private static final String key = System.getenv("FR_KEY");
  private static final String endpoint = System.getenv("FR_ENDPOINT");

  public static void main(final String[] args) {

      // create your `DocumentIntelligenceClient` instance and `AzureKeyCredential` variable
      DocumentIntelligenceClient client = new DocumentIntelligenceClientBuilder()
        .credential(new AzureKeyCredential(key))
        .endpoint(endpoint)
        .buildClient();

// sample document
String invoiceUrl = "https://github.com/Azure-Samples/cognitive-services-REST-api-samples/raw/master/curl/form-recognizer/rest-api/invoice.pdf";
String modelId = "prebuilt-invoice";

SyncPoller < OperationResult, AnalyzeResult > analyzeInvoicesPoller =
  client.beginAnalyzeDocument(modelId, invoiceUrl);

AnalyzeResult analyzeInvoiceResult = analyzeInvoicesPoller.getFinalResult().getAnalyzeResult();

for (int i = 0; i < analyzeInvoiceResult.getDocuments().size(); i++) {
  AnalyzedDocument analyzedInvoice = analyzeInvoiceResult.getDocuments().get(i);
  Map < String, DocumentField > invoiceFields = analyzedInvoice.getFields();
  System.out.printf("----------- Analyzing invoice  %d -----------%n", i);
  DocumentField vendorNameField = invoiceFields.get("VendorName");
  if (vendorNameField != null) {
    if (DocumentFieldType.STRING == vendorNameField.getType()) {
      String merchantName = vendorNameField.getValueAsString();
      System.out.printf("Vendor Name: %s, confidence: %.2f%n",
        merchantName, vendorNameField.getConfidence());
    }
  }

  DocumentField vendorAddressField = invoiceFields.get("VendorAddress");
  if (vendorAddressField != null) {
    if (DocumentFieldType.STRING == vendorAddressField.getType()) {
      String merchantAddress = vendorAddressField.getValueAsString();
      System.out.printf("Vendor address: %s, confidence: %.2f%n",
        merchantAddress, vendorAddressField.getConfidence());
    }
  }

  DocumentField customerNameField = invoiceFields.get("CustomerName");
  if (customerNameField != null) {
    if (DocumentFieldType.STRING == customerNameField.getType()) {
      String merchantAddress = customerNameField.getValueAsString();
      System.out.printf("Customer Name: %s, confidence: %.2f%n",
        merchantAddress, customerNameField.getConfidence());
    }
  }

  DocumentField customerAddressRecipientField = invoiceFields.get("CustomerAddressRecipient");
  if (customerAddressRecipientField != null) {
    if (DocumentFieldType.STRING == customerAddressRecipientField.getType()) {
      String customerAddr = customerAddressRecipientField.getValueAsString();
      System.out.printf("Customer Address Recipient: %s, confidence: %.2f%n",
        customerAddr, customerAddressRecipientField.getConfidence());
    }
  }

  DocumentField invoiceIdField = invoiceFields.get("InvoiceId");
  if (invoiceIdField != null) {
    if (DocumentFieldType.STRING == invoiceIdField.getType()) {
      String invoiceId = invoiceIdField.getValueAsString();
      System.out.printf("Invoice ID: %s, confidence: %.2f%n",
        invoiceId, invoiceIdField.getConfidence());
    }
  }

  DocumentField invoiceDateField = invoiceFields.get("InvoiceDate");
  if (customerNameField != null) {
    if (DocumentFieldType.DATE == invoiceDateField.getType()) {
      LocalDate invoiceDate = invoiceDateField.getValueAsDate();
      System.out.printf("Invoice Date: %s, confidence: %.2f%n",
        invoiceDate, invoiceDateField.getConfidence());
    }
  }

  DocumentField invoiceTotalField = invoiceFields.get("InvoiceTotal");
  if (customerAddressRecipientField != null) {
    if (DocumentFieldType.DOUBLE == invoiceTotalField.getType()) {
      Double invoiceTotal = invoiceTotalField.getValueAsDouble();
      System.out.printf("Invoice Total: %.2f, confidence: %.2f%n",
        invoiceTotal, invoiceTotalField.getConfidence());
    }
  }

  DocumentField invoiceItemsField = invoiceFields.get("Items");
  if (invoiceItemsField != null) {
    System.out.printf("Invoice Items: %n");
    if (DocumentFieldType.LIST == invoiceItemsField.getType()) {
      List < DocumentField > invoiceItems = invoiceItemsField.getValueAsList();
      invoiceItems.stream()
        .filter(invoiceItem -> DocumentFieldType.MAP == invoiceItem.getType())
        .map(documentField -> documentField.getValueAsMap())
        .forEach(documentFieldMap -> documentFieldMap.forEach((key, documentField) -> {
          if ("Description".equals(key)) {
            if (DocumentFieldType.STRING == documentField.getType()) {
              String name = documentField.getValueAsString();
              System.out.printf("Description: %s, confidence: %.2fs%n",
                name, documentField.getConfidence());
            }
          }
          if ("Quantity".equals(key)) {
            if (DocumentFieldType.DOUBLE == documentField.getType()) {
              Double quantity = documentField.getValueAsDouble();
              System.out.printf("Quantity: %f, confidence: %.2f%n",
                quantity, documentField.getConfidence());
            }
          }
          if ("UnitPrice".equals(key)) {
            if (DocumentFieldType.DOUBLE == documentField.getType()) {
              Double unitPrice = documentField.getValueAsDouble();
              System.out.printf("Unit Price: %f, confidence: %.2f%n",
                unitPrice, documentField.getConfidence());
            }
          }
          if ("ProductCode".equals(key)) {
            if (DocumentFieldType.DOUBLE == documentField.getType()) {
              Double productCode = documentField.getValueAsDouble();
              System.out.printf("Product Code: %f, confidence: %.2f%n",
                productCode, documentField.getConfidence());
            }
          }
        }));
    }
  }
}
}
}

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные данные модели счета.

Использование модели получения

import com.azure.ai.documentintelligence;

import com.azure.ai.documentintelligence.models.AnalyzeDocumentRequest;
import com.azure.ai.documentintelligence.models.AnalyzeResult;
import com.azure.ai.documentintelligence.models.AnalyzeResultOperation;
import com.azure.ai.documentintelligence.models.Document;
import com.azure.ai.documentintelligence.models.DocumentField;
import com.azure.ai.documentintelligence.models.DocumentFieldType;
import com.azure.core.credential.AzureKeyCredential;
import com.azure.core.util.polling.SyncPoller;

import java.io.IOException;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;

public class DocIntelligence {
  //use your `key` and `endpoint` environment variables
  private static final String key = System.getenv("FR_KEY");
  private static final String endpoint = System.getenv("FR_ENDPOINT");

  public static void main(final String[] args) {

      // create your `DocumentIntelligenceClient` instance and `AzureKeyCredential` variable
      DocumentIntelligenceClient client = new DocumentIntelligenceClientBuilder()
        .credential(new AzureKeyCredential(key))
        .endpoint(endpoint)
        .buildClient();

String receiptUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/receipt.png";
String modelId = "prebuilt-receipt";

SyncPoller < OperationResult, AnalyzeResult > analyzeReceiptPoller =
  client.beginAnalyzeDocument(modelId, receiptUrl);

AnalyzeResult receiptResults = analyzeReceiptPoller.getFinalResult().getAnalyzeResult();

for (int i = 0; i < receiptResults.getDocuments().size(); i++) {
  AnalyzedDocument analyzedReceipt = receiptResults.getDocuments().get(i);
  Map < String, DocumentField > receiptFields = analyzedReceipt.getFields();
  System.out.printf("----------- Analyzing receipt info %d -----------%n", i);
  DocumentField merchantNameField = receiptFields.get("MerchantName");
  if (merchantNameField != null) {
    if (DocumentFieldType.STRING == merchantNameField.getType()) {
      String merchantName = merchantNameField.getValueAsString();
      System.out.printf("Merchant Name: %s, confidence: %.2f%n",
        merchantName, merchantNameField.getConfidence());
    }
  }

  DocumentField merchantPhoneNumberField = receiptFields.get("MerchantPhoneNumber");
  if (merchantPhoneNumberField != null) {
    if (DocumentFieldType.PHONE_NUMBER == merchantPhoneNumberField.getType()) {
      String merchantAddress = merchantPhoneNumberField.getValueAsPhoneNumber();
      System.out.printf("Merchant Phone number: %s, confidence: %.2f%n",
        merchantAddress, merchantPhoneNumberField.getConfidence());
    }
  }

  DocumentField merchantAddressField = receiptFields.get("MerchantAddress");
  if (merchantAddressField != null) {
    if (DocumentFieldType.STRING == merchantAddressField.getType()) {
      String merchantAddress = merchantAddressField.getValueAsString();
      System.out.printf("Merchant Address: %s, confidence: %.2f%n",
        merchantAddress, merchantAddressField.getConfidence());
    }
  }

  DocumentField transactionDateField = receiptFields.get("TransactionDate");
  if (transactionDateField != null) {
    if (DocumentFieldType.DATE == transactionDateField.getType()) {
      LocalDate transactionDate = transactionDateField.getValueAsDate();
      System.out.printf("Transaction Date: %s, confidence: %.2f%n",
        transactionDate, transactionDateField.getConfidence());
    }
  }

  DocumentField receiptItemsField = receiptFields.get("Items");
  if (receiptItemsField != null) {
    System.out.printf("Receipt Items: %n");
    if (DocumentFieldType.LIST == receiptItemsField.getType()) {
      List < DocumentField > receiptItems = receiptItemsField.getValueAsList();
      receiptItems.stream()
        .filter(receiptItem -> DocumentFieldType.MAP == receiptItem.getType())
        .map(documentField -> documentField.getValueAsMap())
        .forEach(documentFieldMap -> documentFieldMap.forEach((key, documentField) -> {
          if ("Name".equals(key)) {
            if (DocumentFieldType.STRING == documentField.getType()) {
              String name = documentField.getValueAsString();
              System.out.printf("Name: %s, confidence: %.2fs%n",
                name, documentField.getConfidence());
            }
          }
          if ("Quantity".equals(key)) {
            if (DocumentFieldType.DOUBLE == documentField.getType()) {
              Double quantity = documentField.getValueAsDouble();
              System.out.printf("Quantity: %f, confidence: %.2f%n",
                quantity, documentField.getConfidence());
            }
          }
          if ("Price".equals(key)) {
            if (DocumentFieldType.DOUBLE == documentField.getType()) {
              Double price = documentField.getValueAsDouble();
              System.out.printf("Price: %f, confidence: %.2f%n",
                price, documentField.getConfidence());
            }
          }
          if ("TotalPrice".equals(key)) {
            if (DocumentFieldType.DOUBLE == documentField.getType()) {
              Double totalPrice = documentField.getValueAsDouble();
              System.out.printf("Total Price: %f, confidence: %.2f%n",
                totalPrice, documentField.getConfidence());
            }
          }
        }));
    }
  }
}
}
}

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные данные модели квитанций.

Использование модели удостоверения

import com.azure.ai.documentintelligence;

import com.azure.ai.documentintelligence.models.AnalyzeDocumentRequest;
import com.azure.ai.documentintelligence.models.AnalyzeResult;
import com.azure.ai.documentintelligence.models.AnalyzeResultOperation;
import com.azure.ai.documentintelligence.models.Document;
import com.azure.ai.documentintelligence.models.DocumentField;
import com.azure.ai.documentintelligence.models.DocumentFieldType;
import com.azure.core.credential.AzureKeyCredential;
import com.azure.core.util.polling.SyncPoller;

import java.io.IOException;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;

public class DocIntelligence {
  //use your `key` and `endpoint` environment variables
  private static final String key = System.getenv("FR_KEY");
  private static final String endpoint = System.getenv("FR_ENDPOINT");

  public static void main(final String[] args) {

      // create your `DocumentIntelligenceClient` instance and `AzureKeyCredential` variable
      DocumentIntelligenceClient client = new DocumentIntelligenceClientBuilder()
        .credential(new AzureKeyCredential(key))
        .endpoint(endpoint)
        .buildClient();

//sample document
String licenseUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/identity_documents.png";
String modelId = "prebuilt-idDocument";

SyncPoller < OperationResult, AnalyzeResult > analyzeIdentityDocumentPoller = client.beginAnalyzeDocument(modelId, licenseUrl);

AnalyzeResult identityDocumentResults = analyzeIdentityDocumentPoller.getFinalResult().getAnalyzeResult();

for (int i = 0; i < identityDocumentResults.getDocuments().size(); i++) {
  AnalyzedDocument analyzedIDDocument = identityDocumentResults.getDocuments().get(i);
  Map < String, DocumentField > licenseFields = analyzedIDDocument.getFields();
  System.out.printf("----------- Analyzed license info for page %d -----------%n", i);
  DocumentField addressField = licenseFields.get("Address");
  if (addressField != null) {
    if (DocumentFieldType.STRING == addressField.getType()) {
      String address = addressField.getValueAsString();
      System.out.printf("Address: %s, confidence: %.2f%n",
        address, addressField.getConfidence());
    }
  }

  DocumentField countryRegionDocumentField = licenseFields.get("CountryRegion");
  if (countryRegionDocumentField != null) {
    if (DocumentFieldType.STRING == countryRegionDocumentField.getType()) {
      String countryRegion = countryRegionDocumentField.getValueAsCountry();
      System.out.printf("Country or region: %s, confidence: %.2f%n",
        countryRegion, countryRegionDocumentField.getConfidence());
    }
  }

  DocumentField dateOfBirthField = licenseFields.get("DateOfBirth");
  if (dateOfBirthField != null) {
    if (DocumentFieldType.DATE == dateOfBirthField.getType()) {
      LocalDate dateOfBirth = dateOfBirthField.getValueAsDate();
      System.out.printf("Date of Birth: %s, confidence: %.2f%n",
        dateOfBirth, dateOfBirthField.getConfidence());
    }
  }

  DocumentField dateOfExpirationField = licenseFields.get("DateOfExpiration");
  if (dateOfExpirationField != null) {
    if (DocumentFieldType.DATE == dateOfExpirationField.getType()) {
      LocalDate expirationDate = dateOfExpirationField.getValueAsDate();
      System.out.printf("Document date of expiration: %s, confidence: %.2f%n",
        expirationDate, dateOfExpirationField.getConfidence());
    }
  }

  DocumentField documentNumberField = licenseFields.get("DocumentNumber");
  if (documentNumberField != null) {
    if (DocumentFieldType.STRING == documentNumberField.getType()) {
      String documentNumber = documentNumberField.getValueAsString();
      System.out.printf("Document number: %s, confidence: %.2f%n",
        documentNumber, documentNumberField.getConfidence());
    }
  }

  DocumentField firstNameField = licenseFields.get("FirstName");
  if (firstNameField != null) {
    if (DocumentFieldType.STRING == firstNameField.getType()) {
      String firstName = firstNameField.getValueAsString();
      System.out.printf("First Name: %s, confidence: %.2f%n",
        firstName, documentNumberField.getConfidence());
    }
  }

  DocumentField lastNameField = licenseFields.get("LastName");
  if (lastNameField != null) {
    if (DocumentFieldType.STRING == lastNameField.getType()) {
      String lastName = lastNameField.getValueAsString();
      System.out.printf("Last name: %s, confidence: %.2f%n",
        lastName, lastNameField.getConfidence());
    }
  }

  DocumentField regionField = licenseFields.get("Region");
  if (regionField != null) {
    if (DocumentFieldType.STRING == regionField.getType()) {
      String region = regionField.getValueAsString();
      System.out.printf("Region: %s, confidence: %.2f%n",
        region, regionField.getConfidence());
    }
  }
}
}
}

Посетите репозиторий примеров Azure на сайте GitHub и просмотрите выходные данные модели документов идентификатора.

Необходимые компоненты

  • Подписка Azure — создайте бесплатную учетную запись.

  • Последняя версия Visual Studio Code или предпочтительная интегрированная среда разработки. См. Java в Visual Studio Code.

    • Visual Studio Code предлагает пакет кода для Java для Windows и macOS. Пакет программирования — это пакет VS Codeпакета средств разработки Java (JDK) и коллекция предлагаемых расширений корпорацией Майкрософт. Пакет кодировки можно также использовать для исправления существующей среды разработки.
    • Если вы используете VS Code и пакет программирования для Java, установите расширение Gradle для Java .

    Если вы не используете Visual Studio Code, убедитесь, что в среде разработки установлено следующее:

  • Служба ИИ Azure или ресурс аналитики документов. Создание одной службы или нескольких служб. Используйте бесплатную ценовую категорию (F0), чтобы опробовать службу, а затем выполните обновление до платного уровня для рабочей среды.

    Совет

    Создайте ресурс служб ИИ Azure, если вы планируете получить доступ к нескольким службам ИИ Azure с помощью одной конечной точки и ключа. Только для доступа к аналитике документов создайте ресурс аналитики документов. Если вы планируете использовать проверку подлинности Microsoft Entra, вам потребуется ресурс с одним обслуживанием.

  • Ключ и конечная точка из ресурса, создаваемого для подключения приложения к службе аналитики документов Azure.

    1. После развертывания ресурса выберите Перейти к ресурсу.
    2. В меню навигации слева выберите "Ключи" и "Конечная точка".
    3. Скопируйте один из ключей и конечной точки для использования далее в этой статье.

    Снимок экрана: расположение ключей и конечной точки на портале Azure.

  • Файл документа по URL-адресу. Для этого проекта можно использовать примеры форм, указанных в следующей таблице для каждой функции:

    Функция modelID document-url
    Модель чтения prebuilt-read Пример брошюры
    Модель макета prebuilt-layout Пример подтверждения резервирования
    Модель с формой W-2 prebuilt-tax.us.w2 Пример формы W-2
    Модель накладных prebuilt-invoice Пример счета
    Модель получения prebuilt-receipt Пример квитанции
    Модель документа идентификатора prebuilt-idDocument Пример удостоверения
    Модель визитных карточек prebuilt-businessCard Пример визитной карточки

Настройка переменных среды

Чтобы взаимодействовать со службой аналитики DocumentAnalysisClient документов, необходимо создать экземпляр класса. Для этого создайте экземпляр клиента с портал Azure key endpoint. Для этого проекта используйте переменные среды для хранения и доступа к учетным данным.

Внимание

Если вы используете ключ API, сохраните его в другом месте, например в Azure Key Vault. Не включайте ключ API непосредственно в код и никогда не публикуйте его.

Дополнительные сведения о безопасности служб ИИ см. в статье "Проверка подлинности запросов к службам ИИ Azure".

Чтобы задать переменную среды для ключа ресурса Аналитики документов, откройте окно консоли и следуйте инструкциям в вашей операционной системе и среде разработки. Замените <yourKey> и <yourEndpoint> значениями из ресурса в портал Azure.

Переменные среды в Windows не учитывает регистр. Они обычно объявляются в верхнем регистре, с словами, присоединенными подчеркиванием. В командной строке выполните следующие команды:

  1. Задайте ключевую переменную:

    setx DI_KEY <yourKey>
    
  2. Настройка переменной конечной точки

    setx DI_ENDPOINT <yourEndpoint>
    
  3. Закройте окно командной строки после задания переменных среды. Значения остаются до тех пор, пока не измените их еще раз.

  4. Перезапустите все запущенные программы, которые считывают переменную среды. Например, если вы используете Visual Studio или Visual Studio Code в качестве редактора, перезапустите перед запуском примера кода.

Ниже приведены несколько дополнительных полезных команд для использования с переменными среды:

Команда Действие Пример
setx VARIABLE_NAME= Удалите переменную среды, задав значение пустой строке. setx DI_KEY=
setx VARIABLE_NAME=value Задайте или измените значение переменной среды. setx DI_KEY=<yourKey>
set VARIABLE_NAME Отображение значения определенной переменной среды. set DI_KEY
set Отображение всех переменных среды. set

Настройка среды программирования

Чтобы настроить среду программирования, создайте проект Gradle и установите клиентская библиотека.

Создание проекта Gradle

  1. В окне консоли создайте каталог для приложения с именем распознавателя форм и перейдите к нему.

    mkdir form-recognizer-app
    cd form-recognizer-app
    
  2. Выполните команду gradle init из рабочей папки. Эта команда создает основные файлы сборки для Gradle, включая build.gradle.kts, который используется во время выполнения для создания и настройки приложения.

    gradle init --type basic
    
  3. Когда появится запрос на выбор предметно-ориентированного языка, выберите Kotlin.

  4. Нажмите клавишу ВВОД , чтобы принять имя проекта по умолчанию, приложение распознавателя форм.

Установка клиентской библиотеки

В этой статье используется диспетчер зависимостей Gradle. Клиентскую библиотеку и информацию для других диспетчеров зависимостей можно найти в центральном репозитории Maven.

  1. Откройте файл проекта Build. gradle. КТС в интегрированной среде разработки. Скопируйте и вставьте следующий код, чтобы включить клиентская библиотека в качестве implementation инструкции, а также необходимые подключаемые модули и параметры.

    plugins {
        java
        application
    }
    application {
        mainClass.set("FormRecognizer")
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        implementation(group = "com.azure", name = "azure-ai-formrecognizer", version = "4.0.0")
    }
    

Создание приложения Java

Чтобы взаимодействовать со службой аналитики DocumentAnalysisClient документов, создайте экземпляр класса. Для этого вы создадите AzureKeyCredential с key помощью портал Azure и DocumentAnalysisClient экземпляра с AzureKeyCredential помощью аналитики документовendpoint.

  1. В каталоге приложения распознавателя форм выполните следующую команду:

    mkdir -p src/main/java
    

    Вы создадите следующую структуру каталогов:

    Снимок экрана: структура каталогов Java

  2. Перейдите java в каталог и создайте файл с именем FormRecognizer.java.

    Совет

    Новый файл можно создать с помощью PowerShell. Откройте окно PowerShell в каталоге проекта, удерживая клавишу SHIFT и щелкнув правой кнопкой мыши папку, а затем введите следующую команду: New-Item FormRecognizer.java.

  3. Откройте файл FormRecognizer.java и выберите один из следующих примеров кода и скопируйте и вставьте в приложение:

    • Предварительно созданная модель чтения находится в основе всех моделей аналитики документов и может обнаруживать строки, слова, расположения и языки. Макет, общие документы, предварительно созданные и пользовательские модели используют read модель в качестве основы для извлечения текстов из документов.
    • Предварительно созданная модель макета извлекает текстовые и текстовые расположения, таблицы, знаки выделения и сведения о структуре из документов и изображений.
    • Предварительно созданная модель tax.us.w2 извлекает информацию о налоговых формах внутренней налоговой службы США (IRS).
    • Предварительно созданная модель счета извлекает ключевые поля и элементы строк из счетов-фактур продаж в различных форматах.
    • Предварительно созданная модель квитанций извлекает ключевые сведения из печатных и рукописных квитанций о продажах.
    • Предварительно созданная модель idDocument извлекает ключевые сведения из лицензий водителей США; международные биографические страницы паспортов; Идентификаторы штатов США; карточки социального страхования; и постоянные карточки резидентов.
  4. Введите такие команды:

    gradle build
    gradle -PmainClass=FormRecognizer run
    

Использование модели чтения

import com.azure.ai.formrecognizer.*;

import com.azure.ai.formrecognizer.documentanalysis.models.*;
import com.azure.ai.formrecognizer.documentanalysis.DocumentAnalysisClient;
import com.azure.ai.formrecognizer.documentanalysis.DocumentAnalysisClientBuilder;

import com.azure.core.credential.AzureKeyCredential;
import com.azure.core.util.polling.SyncPoller;

import java.io.IOException;
import java.util.List;
import java.util.Arrays;
import java.time.LocalDate;
import java.util.Map;
import java.util.stream.Collectors;

public class FormRecognizer {
  //use your `key` and `endpoint` environment variables
  private static final String key = System.getenv("FR_KEY");
  private static final String endpoint = System.getenv("FR_ENDPOINT");

  public static void main(final String[] args) {

      // create your `DocumentAnalysisClient` instance and `AzureKeyCredential` variable
      DocumentAnalysisClient client = new DocumentAnalysisClientBuilder()
        .credential(new AzureKeyCredential(key))
        .endpoint(endpoint)
        .buildClient();

//sample document
String documentUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/read.png";

String modelId = "prebuilt-read";

SyncPoller < OperationResult, AnalyzeResult > analyzeLayoutResultPoller =
  client.beginAnalyzeDocumentFromUrl(modelId, documentUrl);

AnalyzeResult analyzeLayoutResult = analyzeLayoutResultPoller.getFinalResult();

// pages
analyzeLayoutResult.getPages().forEach(documentPage -> {
  System.out.printf("Page has width: %.2f and height: %.2f, measured with unit: %s%n",
    documentPage.getWidth(),
    documentPage.getHeight(),
    documentPage.getUnit());

  // lines
  documentPage.getLines().forEach(documentLine ->
    System.out.printf("Line %s is within a bounding polygon %s.%n",
      documentLine.getContent(),
      documentLine.getBoundingPolygon().toString()));

  // words
  documentPage.getWords().forEach(documentWord ->
    System.out.printf("Word '%s' has a confidence score of %.2f.%n",
      documentWord.getContent(),
      documentWord.getConfidence()));
});
}
}

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные read данные модели.

Использование модели макета

import com.azure.ai.formrecognizer.*;

import com.azure.ai.formrecognizer.documentanalysis.models.*;
import com.azure.ai.formrecognizer.documentanalysis.DocumentAnalysisClient;
import com.azure.ai.formrecognizer.documentanalysis.DocumentAnalysisClientBuilder;

import com.azure.core.credential.AzureKeyCredential;
import com.azure.core.util.polling.SyncPoller;

import java.io.IOException;
import java.util.List;
import java.util.Arrays;
import java.time.LocalDate;
import java.util.Map;
import java.util.stream.Collectors;

public class FormRecognizer {
  //use your `key` and `endpoint` environment variables
  private static final String key = System.getenv("FR_KEY");
  private static final String endpoint = System.getenv("FR_ENDPOINT");

  public static void main(final String[] args) {

      // create your `DocumentAnalysisClient` instance and `AzureKeyCredential` variable
      DocumentAnalysisClient client = new DocumentAnalysisClientBuilder()
        .credential(new AzureKeyCredential(key))
        .endpoint(endpoint)
        .buildClient();

//sample document
String layoutDocumentUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/layout.png";
String modelId = "prebuilt-layout";

SyncPoller < OperationResult, AnalyzeResult > analyzeLayoutResultPoller =
  client.beginAnalyzeDocumentFromUrl(modelId, layoutDocumentUrl);

AnalyzeResult analyzeLayoutResult = analyzeLayoutResultPoller.getFinalResult();

// pages
analyzeLayoutResult.getPages().forEach(documentPage -> {
  System.out.printf("Page has width: %.2f and height: %.2f, measured with unit: %s%n",
    documentPage.getWidth(),
    documentPage.getHeight(),
    documentPage.getUnit());

  // lines
  documentPage.getLines().forEach(documentLine ->
    System.out.printf("Line %s is within a bounding polygon %s.%n",
      documentLine.getContent(),
      documentLine.getBoundingPolygon().toString()));

  // words
  documentPage.getWords().forEach(documentWord ->
    System.out.printf("Word '%s' has a confidence score of %.2f%n",
      documentWord.getContent(),
      documentWord.getConfidence()));

  // selection marks
  documentPage.getSelectionMarks().forEach(documentSelectionMark ->
    System.out.printf("Selection mark is '%s' and is within a bounding polygon %s with confidence %.2f.%n",
      documentSelectionMark.getSelectionMarkState().toString(),
      getBoundingCoordinates(documentSelectionMark.getBoundingPolygon()),
      documentSelectionMark.getConfidence()));
});

// tables
List < DocumentTable > tables = analyzeLayoutResult.getTables();
for (int i = 0; i < tables.size(); i++) {
  DocumentTable documentTables = tables.get(i);
  System.out.printf("Table %d has %d rows and %d columns.%n", i, documentTables.getRowCount(),
    documentTables.getColumnCount());
  documentTables.getCells().forEach(documentTableCell -> {
    System.out.printf("Cell '%s', has row index %d and column index %d.%n", documentTableCell.getContent(),
      documentTableCell.getRowIndex(), documentTableCell.getColumnIndex());
  });
  System.out.println();
}

}

// Utility function to get the bounding polygon coordinates.
private static String getBoundingCoordinates(List < Point > boundingPolygon) {
  return boundingPolygon.stream().map(point -> String.format("[%.2f, %.2f]", point.getX(),
    point.getY())).collect(Collectors.joining(", "));
}

}

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные данные модели макета.

Использование модели общего документа

import com.azure.ai.formrecognizer.*;

import com.azure.ai.formrecognizer.documentanalysis.models.*;
import com.azure.ai.formrecognizer.documentanalysis.DocumentAnalysisClient;
import com.azure.ai.formrecognizer.documentanalysis.DocumentAnalysisClientBuilder;

import com.azure.core.credential.AzureKeyCredential;
import com.azure.core.util.polling.SyncPoller;

import java.io.IOException;
import java.util.List;
import java.util.Arrays;
import java.time.LocalDate;
import java.util.Map;
import java.util.stream.Collectors;

public class FormRecognizer {
  //use your `key` and `endpoint` environment variables
  private static final String key = System.getenv("FR_KEY");
  private static final String endpoint = System.getenv("FR_ENDPOINT");

  public static void main(final String[] args) {

      // create your `DocumentAnalysisClient` instance and `AzureKeyCredential` variable
      DocumentAnalysisClient client = new DocumentAnalysisClientBuilder()
        .credential(new AzureKeyCredential(key))
        .endpoint(endpoint)
        .buildClient();

//sample document
String generalDocumentUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/sample-layout.pdf";
String modelId = "prebuilt-document";
SyncPoller < OperationResult, AnalyzeResult > analyzeDocumentPoller =
  client.beginAnalyzeDocumentFromUrl(modelId, generalDocumentUrl);

AnalyzeResult analyzeResult = analyzeDocumentPoller.getFinalResult();

// pages
analyzeResult.getPages().forEach(documentPage -> {
  System.out.printf("Page has width: %.2f and height: %.2f, measured with unit: %s%n",
    documentPage.getWidth(),
    documentPage.getHeight(),
    documentPage.getUnit());

  // lines
  documentPage.getLines().forEach(documentLine ->
    System.out.printf("Line %s is within a bounding polygon %s.%n",
      documentLine.getContent(),
      documentLine.getBoundingPolygon().toString()));

  // words
  documentPage.getWords().forEach(documentWord ->
    System.out.printf("Word %s has a confidence score of %.2f%n.",
      documentWord.getContent(),
      documentWord.getConfidence()));
});

// tables
List < DocumentTable > tab_les = analyzeResult.getTables();
for (int i = 0; i < tab_les.size(); i++) {
  DocumentTable documentTable = tab_les.get(i);
  System.out.printf("Table %d has %d rows and %d columns.%n", i, documentTable.getRowCount(),
    documentTable.getColumnCount());
  documentTable.getCells().forEach(documentTableCell -> {
    System.out.printf("Cell '%s', has row index %d and column index %d.%n",
      documentTableCell.getContent(),
      documentTableCell.getRowIndex(), documentTableCell.getColumnIndex());
  });
  System.out.println();
}

// Key-value pairs
analyzeResult.getKeyValuePairs().forEach(documentKeyValuePair -> {
  System.out.printf("Key content: %s%n", documentKeyValuePair.getKey().getContent());
  System.out.printf("Key content bounding region: %s%n",
    documentKeyValuePair.getKey().getBoundingRegions().toString());

  if (documentKeyValuePair.getValue() != null) {
    System.out.printf("Value content: %s%n", documentKeyValuePair.getValue().getContent());
    System.out.printf("Value content bounding region: %s%n", documentKeyValuePair.getValue().getBoundingRegions().toString());
  }
});

}

}

Посетите репозиторий примеров Azure на GitHub и просмотрите общие выходные данные модели документов.

Использование налоговой модели W-2

import com.azure.ai.formrecognizer.*;

import com.azure.ai.formrecognizer.documentanalysis.models.*;
import com.azure.ai.formrecognizer.documentanalysis.DocumentAnalysisClient;
import com.azure.ai.formrecognizer.documentanalysis.DocumentAnalysisClientBuilder;

import com.azure.core.credential.AzureKeyCredential;
import com.azure.core.util.polling.SyncPoller;

import java.io.IOException;
import java.util.List;
import java.util.Arrays;
import java.time.LocalDate;
import java.util.Map;
import java.util.stream.Collectors;

public class FormRecognizer {
  //use your `key` and `endpoint` environment variables
  private static final String key = System.getenv("FR_KEY");
  private static final String endpoint = System.getenv("FR_ENDPOINT");

  public static void main(final String[] args) {

      // create your `DocumentAnalysisClient` instance and `AzureKeyCredential` variable
      DocumentAnalysisClient client = new DocumentAnalysisClientBuilder()
        .credential(new AzureKeyCredential(key))
        .endpoint(endpoint)
        .buildClient();

// sample document
String w2Url = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/w2.png";
String modelId = "prebuilt-tax.us.w2";

SyncPoller < OperationResult, AnalyzeResult > analyzeW2Poller =
  client.beginAnalyzeDocumentFromUrl(modelId, w2Url);

AnalyzeResult analyzeTaxResult = analyzeW2Poller.getFinalResult();

for (int i = 0; i < analyzeTaxResult.getDocuments().size(); i++) {
  AnalyzedDocument analyzedTaxDocument = analyzeTaxResult.getDocuments().get(i);
  Map < String, DocumentField > taxFields = analyzedTaxDocument.getFields();
  System.out.printf("----------- Analyzing Document  %d -----------%n", i);
  DocumentField w2FormVariantField = taxFields.get("W2FormVariant");
  if (w2FormVariantField != null) {
    if (DocumentFieldType.STRING == w2FormVariantField.getType()) {
      String merchantName = w2FormVariantField.getValueAsString();
      System.out.printf("Form variant: %s, confidence: %.2f%n",
        merchantName, w2FormVariantField.getConfidence());
    }
  }

  DocumentField employeeField = taxFields.get("Employee");
  if (employeeField != null) {
    System.out.println("Employee Data: ");
    if (DocumentFieldType.MAP == employeeField.getType()) {
      Map < String, DocumentField > employeeDataFieldMap = employeeField.getValueAsMap();
      DocumentField employeeName = employeeDataFieldMap.get("Name");
      if (employeeName != null) {
        if (DocumentFieldType.STRING == employeeName.getType()) {
          String employeesName = employeeName.getValueAsString();
          System.out.printf("Employee Name: %s, confidence: %.2f%n",
            employeesName, employeeName.getConfidence());
        }
      }
      DocumentField employeeAddrField = employeeDataFieldMap.get("Address");
      if (employeeAddrField != null) {
        if (DocumentFieldType.STRING == employeeAddrField.getType()) {
          String employeeAddress = employeeAddrField.getValueAsString();
          System.out.printf("Employee Address: %s, confidence: %.2f%n",
            employeeAddress, employeeAddrField.getConfidence());
        }
      }
    }
  }

  DocumentField employerField = taxFields.get("Employer");
  if (employerField != null) {
    System.out.println("Employer Data: ");
    if (DocumentFieldType.MAP == employerField.getType()) {
      Map < String, DocumentField > employerDataFieldMap = employerField.getValueAsMap();
      DocumentField employerNameField = employerDataFieldMap.get("Name");
      if (employerNameField != null) {
        if (DocumentFieldType.STRING == employerNameField.getType()) {
          String employerName = employerNameField.getValueAsString();
          System.out.printf("Employer Name: %s, confidence: %.2f%n",
            employerName, employerNameField.getConfidence());
        }
      }

      DocumentField employerIDNumberField = employerDataFieldMap.get("IdNumber");
      if (employerIDNumberField != null) {
        if (DocumentFieldType.STRING == employerIDNumberField.getType()) {
          String employerIdNumber = employerIDNumberField.getValueAsString();
          System.out.printf("Employee ID Number: %s, confidence: %.2f%n",
            employerIdNumber, employerIDNumberField.getConfidence());
        }
      }
    }
  }

  DocumentField taxYearField = taxFields.get("TaxYear");
  if (taxYearField != null) {
    if (DocumentFieldType.STRING == taxYearField.getType()) {
      String taxYear = taxYearField.getValueAsString();
      System.out.printf("Tax year: %s, confidence: %.2f%n",
        taxYear, taxYearField.getConfidence());
    }
  }

  DocumentField taxDateField = taxFields.get("TaxDate");
  if (taxDateField != null) {
    if (DocumentFieldType.DATE == taxDateField.getType()) {
      LocalDate taxDate = taxDateField.getValueAsDate();
      System.out.printf("Tax Date: %s, confidence: %.2f%n",
        taxDate, taxDateField.getConfidence());
    }
  }

  DocumentField socialSecurityTaxField = taxFields.get("SocialSecurityTaxWithheld");
  if (socialSecurityTaxField != null) {
    if (DocumentFieldType.DOUBLE == socialSecurityTaxField.getType()) {
      Double socialSecurityTax = socialSecurityTaxField.getValueAsDouble();
      System.out.printf("Social Security Tax withheld: %.2f, confidence: %.2f%n",
        socialSecurityTax, socialSecurityTaxField.getConfidence());
    }
  }
}
}
}

Посетите репозиторий примеров Azure на сайте GitHub и просмотрите выходные данные налоговой модели W-2.

Использование модели счета

import com.azure.ai.formrecognizer.*;

import com.azure.ai.formrecognizer.documentanalysis.models.*;
import com.azure.ai.formrecognizer.documentanalysis.DocumentAnalysisClient;
import com.azure.ai.formrecognizer.documentanalysis.DocumentAnalysisClientBuilder;

import com.azure.core.credential.AzureKeyCredential;
import com.azure.core.util.polling.SyncPoller;

import java.io.IOException;
import java.util.List;
import java.util.Arrays;
import java.time.LocalDate;
import java.util.Map;
import java.util.stream.Collectors;

public class FormRecognizer {
  //use your `key` and `endpoint` environment variables
  private static final String key = System.getenv("FR_KEY");
  private static final String endpoint = System.getenv("FR_ENDPOINT");

  public static void main(final String[] args) {

      // create your `DocumentAnalysisClient` instance and `AzureKeyCredential` variable
      DocumentAnalysisClient client = new DocumentAnalysisClientBuilder()
        .credential(new AzureKeyCredential(key))
        .endpoint(endpoint)
        .buildClient();

// sample document
String invoiceUrl = "https://github.com/Azure-Samples/cognitive-services-REST-api-samples/raw/master/curl/form-recognizer/rest-api/invoice.pdf";
String modelId = "prebuilt-invoice";

SyncPoller < OperationResult, AnalyzeResult > analyzeInvoicesPoller =
  client.beginAnalyzeDocumentFromUrl(modelId, invoiceUrl);

AnalyzeResult analyzeInvoiceResult = analyzeInvoicesPoller.getFinalResult();

for (int i = 0; i < analyzeInvoiceResult.getDocuments().size(); i++) {
  AnalyzedDocument analyzedInvoice = analyzeInvoiceResult.getDocuments().get(i);
  Map < String, DocumentField > invoiceFields = analyzedInvoice.getFields();
  System.out.printf("----------- Analyzing invoice  %d -----------%n", i);
  DocumentField vendorNameField = invoiceFields.get("VendorName");
  if (vendorNameField != null) {
    if (DocumentFieldType.STRING == vendorNameField.getType()) {
      String merchantName = vendorNameField.getValueAsString();
      System.out.printf("Vendor Name: %s, confidence: %.2f%n",
        merchantName, vendorNameField.getConfidence());
    }
  }

  DocumentField vendorAddressField = invoiceFields.get("VendorAddress");
  if (vendorAddressField != null) {
    if (DocumentFieldType.STRING == vendorAddressField.getType()) {
      String merchantAddress = vendorAddressField.getValueAsString();
      System.out.printf("Vendor address: %s, confidence: %.2f%n",
        merchantAddress, vendorAddressField.getConfidence());
    }
  }

  DocumentField customerNameField = invoiceFields.get("CustomerName");
  if (customerNameField != null) {
    if (DocumentFieldType.STRING == customerNameField.getType()) {
      String merchantAddress = customerNameField.getValueAsString();
      System.out.printf("Customer Name: %s, confidence: %.2f%n",
        merchantAddress, customerNameField.getConfidence());
    }
  }

  DocumentField customerAddressRecipientField = invoiceFields.get("CustomerAddressRecipient");
  if (customerAddressRecipientField != null) {
    if (DocumentFieldType.STRING == customerAddressRecipientField.getType()) {
      String customerAddr = customerAddressRecipientField.getValueAsString();
      System.out.printf("Customer Address Recipient: %s, confidence: %.2f%n",
        customerAddr, customerAddressRecipientField.getConfidence());
    }
  }

  DocumentField invoiceIdField = invoiceFields.get("InvoiceId");
  if (invoiceIdField != null) {
    if (DocumentFieldType.STRING == invoiceIdField.getType()) {
      String invoiceId = invoiceIdField.getValueAsString();
      System.out.printf("Invoice ID: %s, confidence: %.2f%n",
        invoiceId, invoiceIdField.getConfidence());
    }
  }

  DocumentField invoiceDateField = invoiceFields.get("InvoiceDate");
  if (customerNameField != null) {
    if (DocumentFieldType.DATE == invoiceDateField.getType()) {
      LocalDate invoiceDate = invoiceDateField.getValueAsDate();
      System.out.printf("Invoice Date: %s, confidence: %.2f%n",
        invoiceDate, invoiceDateField.getConfidence());
    }
  }

  DocumentField invoiceTotalField = invoiceFields.get("InvoiceTotal");
  if (customerAddressRecipientField != null) {
    if (DocumentFieldType.DOUBLE == invoiceTotalField.getType()) {
      Double invoiceTotal = invoiceTotalField.getValueAsDouble();
      System.out.printf("Invoice Total: %.2f, confidence: %.2f%n",
        invoiceTotal, invoiceTotalField.getConfidence());
    }
  }

  DocumentField invoiceItemsField = invoiceFields.get("Items");
  if (invoiceItemsField != null) {
    System.out.printf("Invoice Items: %n");
    if (DocumentFieldType.LIST == invoiceItemsField.getType()) {
      List < DocumentField > invoiceItems = invoiceItemsField.getValueAsList();
      invoiceItems.stream()
        .filter(invoiceItem -> DocumentFieldType.MAP == invoiceItem.getType())
        .map(documentField -> documentField.getValueAsMap())
        .forEach(documentFieldMap -> documentFieldMap.forEach((key, documentField) -> {
          if ("Description".equals(key)) {
            if (DocumentFieldType.STRING == documentField.getType()) {
              String name = documentField.getValueAsString();
              System.out.printf("Description: %s, confidence: %.2fs%n",
                name, documentField.getConfidence());
            }
          }
          if ("Quantity".equals(key)) {
            if (DocumentFieldType.DOUBLE == documentField.getType()) {
              Double quantity = documentField.getValueAsDouble();
              System.out.printf("Quantity: %f, confidence: %.2f%n",
                quantity, documentField.getConfidence());
            }
          }
          if ("UnitPrice".equals(key)) {
            if (DocumentFieldType.DOUBLE == documentField.getType()) {
              Double unitPrice = documentField.getValueAsDouble();
              System.out.printf("Unit Price: %f, confidence: %.2f%n",
                unitPrice, documentField.getConfidence());
            }
          }
          if ("ProductCode".equals(key)) {
            if (DocumentFieldType.DOUBLE == documentField.getType()) {
              Double productCode = documentField.getValueAsDouble();
              System.out.printf("Product Code: %f, confidence: %.2f%n",
                productCode, documentField.getConfidence());
            }
          }
        }));
    }
  }
}
}
}

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные данные модели счета.

Использование модели получения

import com.azure.ai.formrecognizer.*;

import com.azure.ai.formrecognizer.documentanalysis.models.*;
import com.azure.ai.formrecognizer.documentanalysis.DocumentAnalysisClient;
import com.azure.ai.formrecognizer.documentanalysis.DocumentAnalysisClientBuilder;

import com.azure.core.credential.AzureKeyCredential;
import com.azure.core.util.polling.SyncPoller;

import java.io.IOException;
import java.util.List;
import java.util.Arrays;
import java.time.LocalDate;
import java.util.Map;
import java.util.stream.Collectors;

public class FormRecognizer {
  //use your `key` and `endpoint` environment variables
  private static final String key = System.getenv("FR_KEY");
  private static final String endpoint = System.getenv("FR_ENDPOINT");

  public static void main(final String[] args) {

      // create your `DocumentAnalysisClient` instance and `AzureKeyCredential` variable
      DocumentAnalysisClient client = new DocumentAnalysisClientBuilder()
        .credential(new AzureKeyCredential(key))
        .endpoint(endpoint)
        .buildClient();

String receiptUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/receipt.png";
String modelId = "prebuilt-receipt";

SyncPoller < OperationResult, AnalyzeResult > analyzeReceiptPoller =
  client.beginAnalyzeDocumentFromUrl(modelId, receiptUrl);

AnalyzeResult receiptResults = analyzeReceiptPoller.getFinalResult();

for (int i = 0; i < receiptResults.getDocuments().size(); i++) {
  AnalyzedDocument analyzedReceipt = receiptResults.getDocuments().get(i);
  Map < String, DocumentField > receiptFields = analyzedReceipt.getFields();
  System.out.printf("----------- Analyzing receipt info %d -----------%n", i);
  DocumentField merchantNameField = receiptFields.get("MerchantName");
  if (merchantNameField != null) {
    if (DocumentFieldType.STRING == merchantNameField.getType()) {
      String merchantName = merchantNameField.getValueAsString();
      System.out.printf("Merchant Name: %s, confidence: %.2f%n",
        merchantName, merchantNameField.getConfidence());
    }
  }

  DocumentField merchantPhoneNumberField = receiptFields.get("MerchantPhoneNumber");
  if (merchantPhoneNumberField != null) {
    if (DocumentFieldType.PHONE_NUMBER == merchantPhoneNumberField.getType()) {
      String merchantAddress = merchantPhoneNumberField.getValueAsPhoneNumber();
      System.out.printf("Merchant Phone number: %s, confidence: %.2f%n",
        merchantAddress, merchantPhoneNumberField.getConfidence());
    }
  }

  DocumentField merchantAddressField = receiptFields.get("MerchantAddress");
  if (merchantAddressField != null) {
    if (DocumentFieldType.STRING == merchantAddressField.getType()) {
      String merchantAddress = merchantAddressField.getValueAsString();
      System.out.printf("Merchant Address: %s, confidence: %.2f%n",
        merchantAddress, merchantAddressField.getConfidence());
    }
  }

  DocumentField transactionDateField = receiptFields.get("TransactionDate");
  if (transactionDateField != null) {
    if (DocumentFieldType.DATE == transactionDateField.getType()) {
      LocalDate transactionDate = transactionDateField.getValueAsDate();
      System.out.printf("Transaction Date: %s, confidence: %.2f%n",
        transactionDate, transactionDateField.getConfidence());
    }
  }

  DocumentField receiptItemsField = receiptFields.get("Items");
  if (receiptItemsField != null) {
    System.out.printf("Receipt Items: %n");
    if (DocumentFieldType.LIST == receiptItemsField.getType()) {
      List < DocumentField > receiptItems = receiptItemsField.getValueAsList();
      receiptItems.stream()
        .filter(receiptItem -> DocumentFieldType.MAP == receiptItem.getType())
        .map(documentField -> documentField.getValueAsMap())
        .forEach(documentFieldMap -> documentFieldMap.forEach((key, documentField) -> {
          if ("Name".equals(key)) {
            if (DocumentFieldType.STRING == documentField.getType()) {
              String name = documentField.getValueAsString();
              System.out.printf("Name: %s, confidence: %.2fs%n",
                name, documentField.getConfidence());
            }
          }
          if ("Quantity".equals(key)) {
            if (DocumentFieldType.DOUBLE == documentField.getType()) {
              Double quantity = documentField.getValueAsDouble();
              System.out.printf("Quantity: %f, confidence: %.2f%n",
                quantity, documentField.getConfidence());
            }
          }
          if ("Price".equals(key)) {
            if (DocumentFieldType.DOUBLE == documentField.getType()) {
              Double price = documentField.getValueAsDouble();
              System.out.printf("Price: %f, confidence: %.2f%n",
                price, documentField.getConfidence());
            }
          }
          if ("TotalPrice".equals(key)) {
            if (DocumentFieldType.DOUBLE == documentField.getType()) {
              Double totalPrice = documentField.getValueAsDouble();
              System.out.printf("Total Price: %f, confidence: %.2f%n",
                totalPrice, documentField.getConfidence());
            }
          }
        }));
    }
  }
}
}
}

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные данные модели квитанций.

Использование модели удостоверения

import com.azure.ai.formrecognizer.*;

import com.azure.ai.formrecognizer.documentanalysis.models.*;
import com.azure.ai.formrecognizer.documentanalysis.DocumentAnalysisClient;
import com.azure.ai.formrecognizer.documentanalysis.DocumentAnalysisClientBuilder;

import com.azure.core.credential.AzureKeyCredential;
import com.azure.core.util.polling.SyncPoller;

import java.io.IOException;
import java.util.List;
import java.util.Arrays;
import java.time.LocalDate;
import java.util.Map;
import java.util.stream.Collectors;

public class FormRecognizer {
  //use your `key` and `endpoint` environment variables
  private static final String key = System.getenv("FR_KEY");
  private static final String endpoint = System.getenv("FR_ENDPOINT");

  public static void main(final String[] args) {

      // create your `DocumentAnalysisClient` instance and `AzureKeyCredential` variable
      DocumentAnalysisClient client = new DocumentAnalysisClientBuilder()
        .credential(new AzureKeyCredential(key))
        .endpoint(endpoint)
        .buildClient();

//sample document
String licenseUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/identity_documents.png";
String modelId = "prebuilt-idDocument";

SyncPoller < OperationResult, AnalyzeResult > analyzeIdentityDocumentPoller = client.beginAnalyzeDocumentFromUrl(modelId, licenseUrl);

AnalyzeResult identityDocumentResults = analyzeIdentityDocumentPoller.getFinalResult();

for (int i = 0; i < identityDocumentResults.getDocuments().size(); i++) {
  AnalyzedDocument analyzedIDDocument = identityDocumentResults.getDocuments().get(i);
  Map < String, DocumentField > licenseFields = analyzedIDDocument.getFields();
  System.out.printf("----------- Analyzed license info for page %d -----------%n", i);
  DocumentField addressField = licenseFields.get("Address");
  if (addressField != null) {
    if (DocumentFieldType.STRING == addressField.getType()) {
      String address = addressField.getValueAsString();
      System.out.printf("Address: %s, confidence: %.2f%n",
        address, addressField.getConfidence());
    }
  }

  DocumentField countryRegionDocumentField = licenseFields.get("CountryRegion");
  if (countryRegionDocumentField != null) {
    if (DocumentFieldType.STRING == countryRegionDocumentField.getType()) {
      String countryRegion = countryRegionDocumentField.getValueAsCountry();
      System.out.printf("Country or region: %s, confidence: %.2f%n",
        countryRegion, countryRegionDocumentField.getConfidence());
    }
  }

  DocumentField dateOfBirthField = licenseFields.get("DateOfBirth");
  if (dateOfBirthField != null) {
    if (DocumentFieldType.DATE == dateOfBirthField.getType()) {
      LocalDate dateOfBirth = dateOfBirthField.getValueAsDate();
      System.out.printf("Date of Birth: %s, confidence: %.2f%n",
        dateOfBirth, dateOfBirthField.getConfidence());
    }
  }

  DocumentField dateOfExpirationField = licenseFields.get("DateOfExpiration");
  if (dateOfExpirationField != null) {
    if (DocumentFieldType.DATE == dateOfExpirationField.getType()) {
      LocalDate expirationDate = dateOfExpirationField.getValueAsDate();
      System.out.printf("Document date of expiration: %s, confidence: %.2f%n",
        expirationDate, dateOfExpirationField.getConfidence());
    }
  }

  DocumentField documentNumberField = licenseFields.get("DocumentNumber");
  if (documentNumberField != null) {
    if (DocumentFieldType.STRING == documentNumberField.getType()) {
      String documentNumber = documentNumberField.getValueAsString();
      System.out.printf("Document number: %s, confidence: %.2f%n",
        documentNumber, documentNumberField.getConfidence());
    }
  }

  DocumentField firstNameField = licenseFields.get("FirstName");
  if (firstNameField != null) {
    if (DocumentFieldType.STRING == firstNameField.getType()) {
      String firstName = firstNameField.getValueAsString();
      System.out.printf("First Name: %s, confidence: %.2f%n",
        firstName, documentNumberField.getConfidence());
    }
  }

  DocumentField lastNameField = licenseFields.get("LastName");
  if (lastNameField != null) {
    if (DocumentFieldType.STRING == lastNameField.getType()) {
      String lastName = lastNameField.getValueAsString();
      System.out.printf("Last name: %s, confidence: %.2f%n",
        lastName, lastNameField.getConfidence());
    }
  }

  DocumentField regionField = licenseFields.get("Region");
  if (regionField != null) {
    if (DocumentFieldType.STRING == regionField.getType()) {
      String region = regionField.getValueAsString();
      System.out.printf("Region: %s, confidence: %.2f%n",
        region, regionField.getConfidence());
    }
  }
}
}
}

Посетите репозиторий примеров Azure на сайте GitHub и просмотрите выходные данные модели документов идентификатора.

Использование модели визитной карточки

import com.azure.ai.formrecognizer.*;

import com.azure.ai.formrecognizer.documentanalysis.models.*;
import com.azure.ai.formrecognizer.documentanalysis.DocumentAnalysisClient;
import com.azure.ai.formrecognizer.documentanalysis.DocumentAnalysisClientBuilder;

import com.azure.core.credential.AzureKeyCredential;
import com.azure.core.util.polling.SyncPoller;

import java.io.IOException;
import java.util.List;
import java.util.Arrays;
import java.time.LocalDate;
import java.util.Map;
import java.util.stream.Collectors;

public class FormRecognizer {
  //use your `key` and `endpoint` environment variables
  private static final String key = System.getenv("FR_KEY");
  private static final String endpoint = System.getenv("FR_ENDPOINT");

  public static void main(final String[] args) {

      // create your `DocumentAnalysisClient` instance and `AzureKeyCredential` variable
      DocumentAnalysisClient client = new DocumentAnalysisClientBuilder()
        .credential(new AzureKeyCredential(key))
        .endpoint(endpoint)
        .buildClient();

//sample document
String businessCardUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/de5e0d8982ab754823c54de47a47e8e499351523/curl/form-recognizer/rest-api/business_card.jpg";
String modelId = "prebuilt-businessCard";

SyncPoller < OperationResult, AnalyzeResult > analyzeBusinessCardPoller = client.beginAnalyzeDocumentFromUrl(modelId, businessCardUrl);

AnalyzeResult businessCardPageResults = analyzeBusinessCardPoller.getFinalResult();

for (int i = 0; i < businessCardPageResults.getDocuments().size(); i++) {
  System.out.printf("--------Analyzing business card %d -----------%n", i);
  AnalyzedDocument analyzedBusinessCard = businessCardPageResults.getDocuments().get(i);
  Map < String, DocumentField > businessCardFields = analyzedBusinessCard.getFields();
  DocumentField contactNamesDocumentField = businessCardFields.get("ContactNames");
  if (contactNamesDocumentField != null) {
    if (DocumentFieldType.LIST == contactNamesDocumentField.getType()) {
      List < DocumentField > contactNamesList = contactNamesDocumentField.getValueAsList();
      contactNamesList.stream()
        .filter(contactName -> DocumentFieldType.MAP == contactName.getType())
        .map(contactName -> {
          System.out.printf("Contact name: %s%n", contactName.getContent());
          return contactName.getValueAsMap();
        })
        .forEach(contactNamesMap -> contactNamesMap.forEach((key, contactName) -> {
          if ("FirstName".equals(key)) {
            if (DocumentFieldType.STRING == contactName.getType()) {
              String firstName = contactName.getValueAsString();
              System.out.printf("\tFirst Name: %s, confidence: %.2f%n",
                firstName, contactName.getConfidence());
            }
          }
          if ("LastName".equals(key)) {
            if (DocumentFieldType.STRING == contactName.getType()) {
              String lastName = contactName.getValueAsString();
              System.out.printf("\tLast Name: %s, confidence: %.2f%n",
                lastName, contactName.getConfidence());
            }
          }
        }));
    }
  }

  DocumentField jobTitles = businessCardFields.get("JobTitles");
  if (jobTitles != null) {
    if (DocumentFieldType.LIST == jobTitles.getType()) {
      List < DocumentField > jobTitlesItems = jobTitles.getValueAsList();
      jobTitlesItems.forEach(jobTitlesItem -> {
        if (DocumentFieldType.STRING == jobTitlesItem.getType()) {
          String jobTitle = jobTitlesItem.getValueAsString();
          System.out.printf("Job Title: %s, confidence: %.2f%n",
            jobTitle, jobTitlesItem.getConfidence());
        }
      });
    }
  }

  DocumentField departments = businessCardFields.get("Departments");
  if (departments != null) {
    if (DocumentFieldType.LIST == departments.getType()) {
      List < DocumentField > departmentsItems = departments.getValueAsList();
      departmentsItems.forEach(departmentsItem -> {
        if (DocumentFieldType.STRING == departmentsItem.getType()) {
          String department = departmentsItem.getValueAsString();
          System.out.printf("Department: %s, confidence: %.2f%n",
            department, departmentsItem.getConfidence());
        }
      });
    }
  }

  DocumentField emails = businessCardFields.get("Emails");
  if (emails != null) {
    if (DocumentFieldType.LIST == emails.getType()) {
      List < DocumentField > emailsItems = emails.getValueAsList();
      emailsItems.forEach(emailsItem -> {
        if (DocumentFieldType.STRING == emailsItem.getType()) {
          String email = emailsItem.getValueAsString();
          System.out.printf("Email: %s, confidence: %.2f%n", email, emailsItem.getConfidence());
        }
      });
    }
  }

  DocumentField websites = businessCardFields.get("Websites");
  if (websites != null) {
    if (DocumentFieldType.LIST == websites.getType()) {
      List < DocumentField > websitesItems = websites.getValueAsList();
      websitesItems.forEach(websitesItem -> {
        if (DocumentFieldType.STRING == websitesItem.getType()) {
          String website = websitesItem.getValueAsString();
          System.out.printf("Web site: %s, confidence: %.2f%n",
            website, websitesItem.getConfidence());
        }
      });
    }
  }

  DocumentField mobilePhones = businessCardFields.get("MobilePhones");
  if (mobilePhones != null) {
    if (DocumentFieldType.LIST == mobilePhones.getType()) {
      List < DocumentField > mobilePhonesItems = mobilePhones.getValueAsList();
      mobilePhonesItems.forEach(mobilePhonesItem -> {
        if (DocumentFieldType.PHONE_NUMBER == mobilePhonesItem.getType()) {
          String mobilePhoneNumber = mobilePhonesItem.getValueAsPhoneNumber();
          System.out.printf("Mobile phone number: %s, confidence: %.2f%n",
            mobilePhoneNumber, mobilePhonesItem.getConfidence());
        }
      });
    }
  }

  DocumentField otherPhones = businessCardFields.get("OtherPhones");
  if (otherPhones != null) {
    if (DocumentFieldType.LIST == otherPhones.getType()) {
      List < DocumentField > otherPhonesItems = otherPhones.getValueAsList();
      otherPhonesItems.forEach(otherPhonesItem -> {
        if (DocumentFieldType.PHONE_NUMBER == otherPhonesItem.getType()) {
          String otherPhoneNumber = otherPhonesItem.getValueAsPhoneNumber();
          System.out.printf("Other phone number: %s, confidence: %.2f%n",
            otherPhoneNumber, otherPhonesItem.getConfidence());
        }
      });
    }
  }

  DocumentField faxes = businessCardFields.get("Faxes");
  if (faxes != null) {
    if (DocumentFieldType.LIST == faxes.getType()) {
      List < DocumentField > faxesItems = faxes.getValueAsList();
      faxesItems.forEach(faxesItem -> {
        if (DocumentFieldType.PHONE_NUMBER == faxesItem.getType()) {
          String faxPhoneNumber = faxesItem.getValueAsPhoneNumber();
          System.out.printf("Fax phone number: %s, confidence: %.2f%n",
            faxPhoneNumber, faxesItem.getConfidence());
        }
      });
    }
  }

  DocumentField addresses = businessCardFields.get("Addresses");
  if (addresses != null) {
    if (DocumentFieldType.LIST == addresses.getType()) {
      List < DocumentField > addressesItems = addresses.getValueAsList();
      addressesItems.forEach(addressesItem -> {
        if (DocumentFieldType.STRING == addressesItem.getType()) {
          String address = addressesItem.getValueAsString();
          System.out
            .printf("Address: %s, confidence: %.2f%n", address, addressesItem.getConfidence());
        }
      });
    }
  }

  DocumentField companyName = businessCardFields.get("CompanyNames");
  if (companyName != null) {
    if (DocumentFieldType.LIST == companyName.getType()) {
      List < DocumentField > companyNameItems = companyName.getValueAsList();
      companyNameItems.forEach(companyNameItem -> {
        if (DocumentFieldType.STRING == companyNameItem.getType()) {
          String companyNameValue = companyNameItem.getValueAsString();
          System.out.printf("Company name: %s, confidence: %.2f%n", companyNameValue,
            companyNameItem.getConfidence());
        }
      });
    }
  }
}
}
}

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные данные модели визитных карточек.

Справочник по | пакету REST API клиентской библиотеки | (npm) | Samples |Supported REST API version

Необходимые компоненты

  • Подписка Azure — создайте бесплатную учетную запись.

  • Последняя версия Visual Studio Code или предпочтительная интегрированная среда разработки. Дополнительные сведения см. в разделе Node.js в Visual Studio Code.

  • Последняя LTS версия Node.js.

  • Служба ИИ Azure или ресурс аналитики документов. Создание одной службы или нескольких служб. Используйте бесплатную ценовую категорию (F0), чтобы опробовать службу, а затем выполните обновление до платного уровня для рабочей среды.

    Совет

    Создайте ресурс служб ИИ Azure, если вы планируете получить доступ к нескольким службам ИИ Azure с помощью одной конечной точки и ключа. Только для доступа к аналитике документов создайте ресурс аналитики документов. Если вы планируете использовать проверку подлинности Microsoft Entra, вам потребуется ресурс с одним обслуживанием.

  • Ключ и конечная точка из ресурса, создаваемого для подключения приложения к службе аналитики документов Azure.

    1. После развертывания ресурса выберите Перейти к ресурсу.
    2. В меню навигации слева выберите "Ключи" и "Конечная точка".
    3. Скопируйте один из ключей и конечной точки для использования далее в этой статье.

    Снимок экрана: расположение ключей и конечной точки на портале Azure.

  • Файл документа по URL-адресу. Для этого проекта можно использовать примеры форм, указанных в следующей таблице для каждой функции:

    Функция modelID document-url
    Модель чтения prebuilt-read Пример брошюры
    Модель макета prebuilt-layout Пример подтверждения резервирования
    Модель с формой W-2 prebuilt-tax.us.w2 Пример формы W-2
    Модель накладных prebuilt-invoice Пример счета
    Модель получения prebuilt-receipt Пример квитанции
    Модель документа идентификатора prebuilt-idDocument Пример удостоверения

Настройка переменных среды

Чтобы взаимодействовать со службой аналитики DocumentAnalysisClient документов, необходимо создать экземпляр класса. Для этого создайте экземпляр клиента с портал Azure key endpoint. Для этого проекта используйте переменные среды для хранения и доступа к учетным данным.

Внимание

Если вы используете ключ API, сохраните его в другом месте, например в Azure Key Vault. Не включайте ключ API непосредственно в код и никогда не публикуйте его.

Дополнительные сведения о безопасности служб ИИ см. в статье "Проверка подлинности запросов к службам ИИ Azure".

Чтобы задать переменную среды для ключа ресурса Аналитики документов, откройте окно консоли и следуйте инструкциям в вашей операционной системе и среде разработки. Замените <yourKey> и <yourEndpoint> значениями из ресурса в портал Azure.

Переменные среды в Windows не учитывает регистр. Они обычно объявляются в верхнем регистре, с словами, присоединенными подчеркиванием. В командной строке выполните следующие команды:

  1. Задайте ключевую переменную:

    setx DI_KEY <yourKey>
    
  2. Настройка переменной конечной точки

    setx DI_ENDPOINT <yourEndpoint>
    
  3. Закройте окно командной строки после задания переменных среды. Значения остаются до тех пор, пока не измените их еще раз.

  4. Перезапустите все запущенные программы, которые считывают переменную среды. Например, если вы используете Visual Studio или Visual Studio Code в качестве редактора, перезапустите перед запуском примера кода.

Ниже приведены несколько дополнительных полезных команд для использования с переменными среды:

Команда Действие Пример
setx VARIABLE_NAME= Удалите переменную среды, задав значение пустой строке. setx DI_KEY=
setx VARIABLE_NAME=value Задайте или измените значение переменной среды. setx DI_KEY=<yourKey>
set VARIABLE_NAME Отображение значения определенной переменной среды. set DI_KEY
set Отображение всех переменных среды. set

Настройка среды программирования

Создайте приложение Node.js Express.

  1. В окне консоли создайте и перейдите в новый каталог для приложения с именем doc-intel-app.

    mkdir doc-intel-app
    cd doc-intel-app
    
  2. Выполните команду npm init, чтобы инициализировать приложение и сформировать шаблон проекта.

    npm init
    
  3. Укажите атрибуты проекта с помощью запросов, представленных в терминале.

    • Наиболее важными атрибутами являются имя, номер версии и точка входа.
    • Рекомендуется сохранить index.js имя точки входа. Описание, команда тестирования, репозиторий GitHub, ключевые слова, автор и сведения о лицензии являются необязательными атрибутами. Их можно пропустить для этого проекта.
    • Нажмите клавишу ВВОД , чтобы принять предложения в скобках.

    После завершения запроса команда создает package.json файл в каталоге doc-intel-app .

  4. Установите клиентскую библиотеку ai-document-intelligence и пакеты npm azure/identity:

    npm i @azure-rest/[email protected] @azure/identity
    

Файл package.json приложения обновляется с помощью зависимостей.

  1. Создайте файл с именем index.js в каталоге приложения.

    Совет

    Новый файл можно создать с помощью PowerShell. Откройте окно PowerShell в каталоге проекта, удерживая клавишу SHIFT и щелкнув правой кнопкой мыши папку, а затем введите следующую команду: New-Item index.js.

Сборка приложения

Чтобы взаимодействовать со службой аналитики DocumentIntelligenceClient документов, необходимо создать экземпляр класса. Для этого создайте AzureKeyCredential ключ из портал Azure и DocumentIntelligenceClient экземпляра с AzureKeyCredential конечной точкой аналитики документов.

Откройте файл в Visual Studio Code или любимой index.js интегрированной среде разработки и выберите один из следующих примеров кода и скопируйте и вставьте в приложение:

  • Предварительно созданная модель чтения находится в основе всех моделей аналитики документов и может обнаруживать строки, слова, расположения и языки. Макет, общие документы, предварительно созданные и пользовательские модели используют read модель в качестве основы для извлечения текстов из документов.
  • Предварительно созданная модель макета извлекает текстовые и текстовые расположения, таблицы, знаки выделения и сведения о структуре из документов и изображений.
  • Предварительно созданная модель tax.us.w2 извлекает информацию о налоговых формах внутренней налоговой службы США (IRS).
  • Предварительно созданная модель счета извлекает информацию о налоговых формах внутренней налоговой службы США.
  • Предварительно созданная модель квитанций извлекает ключевые сведения из печатных и рукописных квитанций о продажах.
  • Предварительно созданная модель idDocument извлекает ключевые сведения из лицензий водителей США; международные биографические страницы паспортов; Идентификаторы штатов США; карточки социального страхования; и постоянные карточки резидентов.

Использование модели чтения

const { DocumentIntelligenceClient } = require("@azure-rest/ai-document-intelligence");
const  { AzureKeyCredential } = require("@azure/core-auth");

//use your `key` and `endpoint` environment variables
const key = process.env['DI_KEY'];
const endpoint = process.env['DI_ENDPOINT'];

// sample document
const documentUrlRead = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/read.png"

// helper function
function* getTextOfSpans(content, spans) {
    for (const span of spans) {
        yield content.slice(span.offset, span.offset + span.length);
    }
}

async function main() {
    // create your `DocumentIntelligenceClient` instance and `AzureKeyCredential` variable
    const client = DocumentIntelligence(endpoint, new AzureKeyCredential(key));
    const poller = await client.beginAnalyzeDocument("prebuilt-read", documentUrlRead);

    const {
        content,
        pages,
        languages,
        styles
    } = await poller.pollUntilDone();

    if (pages.length <= 0) {
        console.log("No pages were extracted from the document.");
    } else {
        console.log("Pages:");
        for (const page of pages) {
            console.log("- Page", page.pageNumber, `(unit: ${page.unit})`);
            console.log(`  ${page.width}x${page.height}, angle: ${page.angle}`);
            console.log(`  ${page.lines.length} lines, ${page.words.length} words`);

            if (page.lines.length > 0) {
                console.log("  Lines:");

                for (const line of page.lines) {
                    console.log(`  - "${line.content}"`);

                    // The words of the line can also be iterated independently. The words are computed based on their
                    // corresponding spans.
                    for (const word of line.words()) {
                        console.log(`    - "${word.content}"`);
                    }
                }
            }
        }
    }

    if (languages.length <= 0) {
        console.log("No language spans were extracted from the document.");
    } else {
        console.log("Languages:");
        for (const languageEntry of languages) {
            console.log(
                `- Found language: ${languageEntry.languageCode} (confidence: ${languageEntry.confidence})`
            );
            for (const text of getTextOfSpans(content, languageEntry.spans)) {
                const escapedText = text.replace(/\r?\n/g, "\\n").replace(/"/g, '\\"');
                console.log(`  - "${escapedText}"`);
            }
        }
    }

    if (styles.length <= 0) {
        console.log("No text styles were extracted from the document.");
    } else {
        console.log("Styles:");
        for (const style of styles) {
            console.log(
                `- Handwritten: ${style.isHandwritten ? "yes" : "no"} (confidence=${style.confidence})`
            );

            for (const word of getTextOfSpans(content, style.spans)) {
                console.log(`  - "${word}"`);
            }
        }
    }
}

main().catch((error) => {
    console.error("An error occurred:", error);
    process.exit(1);
});

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные read данные модели.

Использование модели макета

const { DocumentIntelligenceClient } = require("@azure-rest/ai-document-intelligence");
const  { AzureKeyCredential } = require("@azure/core-auth");

//use your `key` and `endpoint` environment variables
const key = process.env['DI_KEY'];
const endpoint = process.env['DI_ENDPOINT'];

// sample document
const layoutUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/layout.png"

async function main() {
    const client = DocumentIntelligence(endpoint, new AzureKeyCredential(key));

    const poller = await client.beginAnalyzeDocument(
      "prebuilt-layout", layoutUrl);

    // Layout extraction produces basic elements such as pages, words, lines, etc. as well as information about the
    // appearance (styles) of textual elements.
    const { pages, tables } = await poller.pollUntilDone();

    if (!pages || pages.length <= 0) {
      console.log("No pages were extracted from the document.");
    } else {
      console.log("Pages:");
      for (const page of pages) {
        console.log("- Page", page.pageNumber, `(unit: ${page.unit})`);
        console.log(`  ${page.width}x${page.height}, angle: ${page.angle}`);
        console.log(
          `  ${page.lines && page.lines.length} lines, ${page.words && page.words.length} words`
        );

        if (page.lines && page.lines.length > 0) {
          console.log("  Lines:");

          for (const line of page.lines) {
            console.log(`  - "${line.content}"`);

            // The words of the line can also be iterated independently. The words are computed based on their
            // corresponding spans.
            for (const word of line.words()) {
              console.log(`    - "${word.content}"`);
            }
          }
        }
      }
    }

    if (!tables || tables.length <= 0) {
      console.log("No tables were extracted from the document.");
    } else {
      console.log("Tables:");
      for (const table of tables) {
        console.log(
          `- Extracted table: ${table.columnCount} columns, ${table.rowCount} rows (${table.cells.length} cells)`
        );
      }
    }
  }

  main().catch((error) => {
    console.error("An error occurred:", error);
    process.exit(1);
  });

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные данные модели макета.

Использование модели общего документа

const { DocumentIntelligenceClient } = require("@azure-rest/ai-document-intelligence");
const  { AzureKeyCredential } = require("@azure/core-auth");

//use your `key` and `endpoint` environment variables
const key = process.env['DI_KEY'];
const endpoint = process.env['DI_ENDPOINT'];

// sample document
const documentUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/sample-layout.pdf"

async function main() {
    const client = DocumentIntelligence(endpoint, new AzureKeyCredential(key));

    const poller = await client.beginAnalyzeDocument("prebuilt-document", documentUrl);

    const {
        keyValuePairs
    } = await poller.pollUntilDone();

    if (!keyValuePairs || keyValuePairs.length <= 0) {
        console.log("No key-value pairs were extracted from the document.");
    } else {
        console.log("Key-Value Pairs:");
        for (const {
                key,
                value,
                confidence
            } of keyValuePairs) {
            console.log("- Key  :", `"${key.content}"`);
            console.log("  Value:", `"${(value && value.content) || "<undefined>"}" (${confidence})`);
        }
    }

}

main().catch((error) => {
    console.error("An error occurred:", error);
    process.exit(1);
});

Посетите репозиторий примеров Azure на GitHub и просмотрите общие выходные данные модели документов.

Использование налоговой модели W-2

const { DocumentIntelligenceClient } = require("@azure-rest/ai-document-intelligence");
const  { AzureKeyCredential } = require("@azure/core-auth");

//use your `key` and `endpoint` environment variables
const key = process.env['DI_KEY'];
const endpoint = process.env['DI_ENDPOINT'];

const w2DocumentURL = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/w2.png"

async function main() {
 const client = DocumentIntelligence(endpoint, new AzureKeyCredential(key));

 const poller = await client.beginAnalyzeDocument("prebuilt-tax.us.w2", w2DocumentURL);

 const {
   documents: [result]
 } = await poller.pollUntilDone();

  if (result) {
    const { Employee, Employer, ControlNumber, TaxYear, AdditionalInfo } = result.fields;

    if (Employee) {
      const { Name, Address, SocialSecurityNumber } = Employee.properties;
      console.log("Employee:");
      console.log("  Name:", Name && Name.content);
      console.log("  SSN/TIN:", SocialSecurityNumber && SocialSecurityNumber.content);
      if (Address && Address.value) {
        const { streetAddress, postalCode } = Address.value;
        console.log("  Address:");
        console.log("    Street Address:", streetAddress);
        console.log("    Postal Code:", postalCode);
      }
    } else {
      console.log("No employee information extracted.");
    }

    if (Employer) {
      const { Name, Address, IdNumber } = Employer.properties;
      console.log("Employer:");
      console.log("  Name:", Name && Name.content);
      console.log("  ID (EIN):", IdNumber && IdNumber.content);

      if (Address && Address.value) {
        const { streetAddress, postalCode } = Address.value;
        console.log("  Address:");
        console.log("    Street Address:", streetAddress);
        console.log("    Postal Code:", postalCode);
      }
    } else {
      console.log("No employer information extracted.");
    }

    console.log("Control Number:", ControlNumber && ControlNumber.content);
    console.log("Tax Year:", TaxYear && TaxYear.content);

    if (AdditionalInfo) {
      console.log("Additional Info:");

      for (const info of AdditionalInfo.values) {
        const { LetterCode, Amount } = info.properties;
        console.log(`- ${LetterCode && LetterCode.content}: ${Amount && Amount.content}`);
      }
    }
  } else {
    throw new Error("Expected at least one document in the result.");
  }
}

main().catch((error) => {
  console.error(error);
  process.exit(1);
});

Посетите репозиторий примеров Azure на сайте GitHub и просмотрите выходные данные налоговой модели W-2.

Использование модели счета

const { DocumentIntelligenceClient } = require("@azure-rest/ai-document-intelligence");
const  { AzureKeyCredential } = require("@azure/core-auth");

//use your `key` and `endpoint` environment variables
const key = process.env['DI_KEY'];
const endpoint = process.env['DI_ENDPOINT'];

// sample url
const invoiceUrl = "https://github.com/Azure-Samples/cognitive-services-REST-api-samples/raw/master/curl/form-recognizer/rest-api/invoice.pdf";

async function main() {

  const client = DocumentIntelligence(endpoint, new AzureKeyCredential(key));

  const poller = await client.beginAnalyzeDocument("prebuilt-invoice", invoiceUrl);

  const {
      documents: [result]
  } = await poller.pollUntilDone();

  if (result) {
      const invoice = result.fields;

      console.log("Vendor Name:", invoice.VendorName?.content);
      console.log("Customer Name:", invoice.CustomerName?.content);
      console.log("Invoice Date:", invoice.InvoiceDate?.content);
      console.log("Due Date:", invoice.DueDate?.content);

      console.log("Items:");
      for (const {
              properties: item
          } of invoice.Items?.values ?? []) {
          console.log("-", item.ProductCode?.content ?? "<no product code>");
          console.log("  Description:", item.Description?.content);
          console.log("  Quantity:", item.Quantity?.content);
          console.log("  Date:", item.Date?.content);
          console.log("  Unit:", item.Unit?.content);
          console.log("  Unit Price:", item.UnitPrice?.content);
          console.log("  Tax:", item.Tax?.content);
          console.log("  Amount:", item.Amount?.content);
      }

      console.log("Subtotal:", invoice.SubTotal?.content);
      console.log("Previous Unpaid Balance:", invoice.PreviousUnpaidBalance?.content);
      console.log("Tax:", invoice.TotalTax?.content);
      console.log("Amount Due:", invoice.AmountDue?.content);
  } else {
      throw new Error("Expected at least one receipt in the result.");
  }
}

main().catch((error) => {
  console.error("An error occurred:", error);
  process.exit(1);
});

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные данные модели счета.

Использование модели квитанции

const { DocumentIntelligenceClient } = require("@azure-rest/ai-document-intelligence");
const  { AzureKeyCredential } = require("@azure/core-auth");

//use your `key` and `endpoint` environment variables
const key = process.env['DI_KEY'];
const endpoint = process.env['DI_ENDPOINT'];

// sample url
const receiptUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/receipt.png";

async function main() {

    const client = DocumentIntelligence(endpoint, new AzureKeyCredential(key));

    const poller = await client.beginAnalyzeDocument("prebuilt-receipt", receiptUrl);

    const {
        documents: [result]
    } = await poller.pollUntilDone();

    if (result) {
        const {
            MerchantName,
            Items,
            Total
        } = result.fields;

        console.log("=== Receipt Information ===");
        console.log("Type:", result.docType);
        console.log("Merchant:", MerchantName && MerchantName.content);

        console.log("Items:");
        for (const item of (Items && Items.values) || []) {
            const {
                Description,
                TotalPrice
            } = item.properties;

            console.log("- Description:", Description && Description.content);
            console.log("  Total Price:", TotalPrice && TotalPrice.content);
        }

        console.log("Total:", Total && Total.content);
    } else {
        throw new Error("Expected at least one receipt in the result.");
    }

}

main().catch((err) => {
    console.error("The sample encountered an error:", err);
});

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные данные модели квитанций.

Использование модели удостоверения

const { DocumentIntelligenceClient } = require("@azure-rest/ai-document-intelligence");
const  { AzureKeyCredential } = require("@azure/core-auth");

//use your `key` and `endpoint` environment variables
const key = process.env['DI_KEY'];
const endpoint = process.env['DI_ENDPOINT'];

// sample document
const idDocumentURL = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/identity_documents.png"

async function main() {
 const client = DocumentIntelligence(endpoint, new AzureKeyCredential(key));

 const poller = await client.beginAnalyzeDocument("prebuilt-idDocument", idDocumentURL);

 const {
   documents: [result]
 } = await poller.pollUntilDone();

  if (result) {
// The identity document model has multiple document types, so we need to know which document type was actually
    extracted.
    if (result.docType === "idDocument.driverLicense") {
      const { FirstName, LastName, DocumentNumber, DateOfBirth, DateOfExpiration, Height, Weight, EyeColor, Endorsements, Restrictions, VehicleClassifications} = result.fields;

// For the sake of the example, we'll only show a few of the fields that are produced.
      console.log("Extracted a Driver License:");
      console.log("  Name:", FirstName && FirstName.content, LastName && LastName.content);
      console.log("  License No.:", DocumentNumber && DocumentNumber.content);
      console.log("  Date of Birth:", DateOfBirth && DateOfBirth.content);
      console.log("  Expiration:", DateOfExpiration && DateOfExpiration.content);
      console.log("  Height:", Height && Height.content);
      console.log("  Weight:", Weight && Weight.content);
      console.log("  Eye color:", EyeColor && EyeColor.content);
      console.log("  Restrictions:", Restrictions && Restrictions.content);
      console.log("  Endorsements:", Endorsements && Endorsements.content);
      console.log("  Class:", VehicleClassifications && VehicleClassifications.content);
    } else if (result.docType === "idDocument.passport") {
// The passport document type extracts and parses the Passport's machine-readable zone
      if (!result.fields.machineReadableZone) {
        throw new Error("No Machine Readable Zone extracted from passport.");
      }

      const {
        FirstName,
        LastName,
        DateOfBirth,
        Nationality,
        DocumentNumber,
        CountryRegion,
        DateOfExpiration,
      } = result.fields.machineReadableZone.properties;

      console.log("Extracted a Passport:");
      console.log("  Name:", FirstName && FirstName.content, LastName && LastName.content);
      console.log("  Date of Birth:", DateOfBirth && DateOfBirth.content);
      console.log("  Nationality:", Nationality && Nationality.content);
      console.log("  Passport No.:", DocumentNumber && DocumentNumber.content);
      console.log("  Issuer:", CountryRegion && CountryRegion.content);
      console.log("  Expiration Date:", DateOfExpiration && DateOfExpiration.content);
    } else {
// The only reason this would happen is if the client library's schema for the prebuilt identity document model is
      out of date, and a new document type has been introduced.
      console.error("Unknown document type in result:", result);
    }
  } else {
    throw new Error("Expected at least one receipt in the result.");
  }
}

main().catch((error) => {
  console.error("An error occurred:", error);
  process.exit(1);
});

Посетите репозиторий примеров Azure на сайте GitHub и просмотрите выходные данные модели документов идентификатора.

Необходимые компоненты

  • Подписка Azure — создайте бесплатную учетную запись.

  • Последняя версия Visual Studio Code или предпочтительная интегрированная среда разработки. Дополнительные сведения см. в разделе Node.js в Visual Studio Code.

  • Последняя LTS версия Node.js.

  • Служба ИИ Azure или ресурс аналитики документов. Создание одной службы или нескольких служб. Используйте бесплатную ценовую категорию (F0), чтобы опробовать службу, а затем выполните обновление до платного уровня для рабочей среды.

    Совет

    Создайте ресурс служб ИИ Azure, если вы планируете получить доступ к нескольким службам ИИ Azure с помощью одной конечной точки и ключа. Только для доступа к аналитике документов создайте ресурс аналитики документов. Если вы планируете использовать проверку подлинности Microsoft Entra, вам потребуется ресурс с одним обслуживанием.

  • Ключ и конечная точка из ресурса, создаваемого для подключения приложения к службе аналитики документов Azure.

    1. После развертывания ресурса выберите Перейти к ресурсу.
    2. В меню навигации слева выберите "Ключи" и "Конечная точка".
    3. Скопируйте один из ключей и конечной точки для использования далее в этой статье.

    Снимок экрана: расположение ключей и конечной точки на портале Azure.

  • Файл документа по URL-адресу. Для этого проекта можно использовать примеры форм, указанных в следующей таблице для каждой функции:

    Функция modelID document-url
    Модель чтения prebuilt-read Пример брошюры
    Модель макета prebuilt-layout Пример подтверждения резервирования
    Модель с формой W-2 prebuilt-tax.us.w2 Пример формы W-2
    Модель накладных prebuilt-invoice Пример счета
    Модель получения prebuilt-receipt Пример квитанции
    Модель документа идентификатора prebuilt-idDocument Пример удостоверения
    Модель визитных карточек prebuilt-businessCard Пример визитной карточки

Настройка переменных среды

Чтобы взаимодействовать со службой аналитики DocumentAnalysisClient документов, необходимо создать экземпляр класса. Для этого создайте экземпляр клиента с портал Azure key endpoint. Для этого проекта используйте переменные среды для хранения и доступа к учетным данным.

Внимание

Если вы используете ключ API, сохраните его в другом месте, например в Azure Key Vault. Не включайте ключ API непосредственно в код и никогда не публикуйте его.

Дополнительные сведения о безопасности служб ИИ см. в статье "Проверка подлинности запросов к службам ИИ Azure".

Чтобы задать переменную среды для ключа ресурса Аналитики документов, откройте окно консоли и следуйте инструкциям в вашей операционной системе и среде разработки. Замените <yourKey> и <yourEndpoint> значениями из ресурса в портал Azure.

Переменные среды в Windows не учитывает регистр. Они обычно объявляются в верхнем регистре, с словами, присоединенными подчеркиванием. В командной строке выполните следующие команды:

  1. Задайте ключевую переменную:

    setx DI_KEY <yourKey>
    
  2. Настройка переменной конечной точки

    setx DI_ENDPOINT <yourEndpoint>
    
  3. Закройте окно командной строки после задания переменных среды. Значения остаются до тех пор, пока не измените их еще раз.

  4. Перезапустите все запущенные программы, которые считывают переменную среды. Например, если вы используете Visual Studio или Visual Studio Code в качестве редактора, перезапустите перед запуском примера кода.

Ниже приведены несколько дополнительных полезных команд для использования с переменными среды:

Команда Действие Пример
setx VARIABLE_NAME= Удалите переменную среды, задав значение пустой строке. setx DI_KEY=
setx VARIABLE_NAME=value Задайте или измените значение переменной среды. setx DI_KEY=<yourKey>
set VARIABLE_NAME Отображение значения определенной переменной среды. set DI_KEY
set Отображение всех переменных среды. set

Настройка среды программирования

Создайте приложение Node.js Express.

  1. В окне консоли создайте и перейдите в новый каталог для приложения с именем form-recognizer-app.

    mkdir form-recognizer-app
    cd form-recognizer-app
    
  2. Выполните команду npm init, чтобы инициализировать приложение и сформировать шаблон проекта.

    npm init
    
  3. Укажите атрибуты проекта с помощью запросов, представленных в терминале.

    • Наиболее важными атрибутами являются имя, номер версии и точка входа.
    • Рекомендуется сохранить index.js имя точки входа. Описание, команда тестирования, репозиторий GitHub, ключевые слова, автор и сведения о лицензии являются необязательными атрибутами. Их можно пропустить для этого проекта.
    • Нажмите клавишу ВВОД , чтобы принять предложения в скобках.

    После завершения запроса команда создает package.json файл в каталоге приложения-распознавателя формы.

  4. Установите клиентскую библиотеку ai-form-recognizer и пакеты npm azure/identity:

    npm i @azure/ai-form-recognizer @azure/identity
    

Файл package.json приложения обновляется с помощью зависимостей.

  1. Создайте файл с именем index.js в каталоге приложения.

    Совет

    Новый файл можно создать с помощью PowerShell. Откройте окно PowerShell в каталоге проекта, удерживая клавишу SHIFT и щелкнув правой кнопкой мыши папку, а затем введите следующую команду: New-Item index.js.

Сборка приложения

Чтобы взаимодействовать со службой аналитики DocumentAnalysisClient документов, необходимо создать экземпляр класса. Для этого создайте AzureKeyCredential ключ из портал Azure и DocumentAnalysisClient экземпляра с AzureKeyCredential конечной точкой аналитики документов.

Откройте файл в Visual Studio Code или любимой index.js интегрированной среде разработки и выберите один из следующих примеров кода и скопируйте и вставьте в приложение:

  • Предварительно созданная модель чтения находится в основе всех моделей аналитики документов и может обнаруживать строки, слова, расположения и языки. Макет, общие документы, предварительно созданные и пользовательские модели используют read модель в качестве основы для извлечения текстов из документов.
  • Предварительно созданная модель макета извлекает текстовые и текстовые расположения, таблицы, знаки выделения и сведения о структуре из документов и изображений.
  • Предварительно созданная модель tax.us.w2 извлекает информацию о налоговых формах внутренней налоговой службы США (IRS).
  • Предварительно созданная модель счета извлекает информацию о налоговых формах внутренней налоговой службы США.
  • Предварительно созданная модель квитанций извлекает ключевые сведения из печатных и рукописных квитанций о продажах.
  • Предварительно созданная модель idDocument извлекает ключевые сведения из лицензий водителей США; международные биографические страницы паспортов; Идентификаторы штатов США; карточки социального страхования; и постоянные карточки резидентов.

Использование модели чтения

const { AzureKeyCredential, DocumentAnalysisClient } = require("@azure/ai-form-recognizer");

//use your `key` and `endpoint` environment variables
const key = process.env['FR_KEY'];
const endpoint = process.env['FR_ENDPOINT'];

// sample document
const documentUrlRead = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/read.png"

// helper function
function* getTextOfSpans(content, spans) {
    for (const span of spans) {
        yield content.slice(span.offset, span.offset + span.length);
    }
}

async function main() {
    // create your `DocumentAnalysisClient` instance and `AzureKeyCredential` variable
    const client = new DocumentAnalysisClient(endpoint, new AzureKeyCredential(key));
    const poller = await client.beginAnalyzeDocument("prebuilt-read", documentUrlRead);

    const {
        content,
        pages,
        languages,
        styles
    } = await poller.pollUntilDone();

    if (pages.length <= 0) {
        console.log("No pages were extracted from the document.");
    } else {
        console.log("Pages:");
        for (const page of pages) {
            console.log("- Page", page.pageNumber, `(unit: ${page.unit})`);
            console.log(`  ${page.width}x${page.height}, angle: ${page.angle}`);
            console.log(`  ${page.lines.length} lines, ${page.words.length} words`);

            if (page.lines.length > 0) {
                console.log("  Lines:");

                for (const line of page.lines) {
                    console.log(`  - "${line.content}"`);

                    // The words of the line can also be iterated independently. The words are computed based on their
                    // corresponding spans.
                    for (const word of line.words()) {
                        console.log(`    - "${word.content}"`);
                    }
                }
            }
        }
    }

    if (languages.length <= 0) {
        console.log("No language spans were extracted from the document.");
    } else {
        console.log("Languages:");
        for (const languageEntry of languages) {
            console.log(
                `- Found language: ${languageEntry.languageCode} (confidence: ${languageEntry.confidence})`
            );
            for (const text of getTextOfSpans(content, languageEntry.spans)) {
                const escapedText = text.replace(/\r?\n/g, "\\n").replace(/"/g, '\\"');
                console.log(`  - "${escapedText}"`);
            }
        }
    }

    if (styles.length <= 0) {
        console.log("No text styles were extracted from the document.");
    } else {
        console.log("Styles:");
        for (const style of styles) {
            console.log(
                `- Handwritten: ${style.isHandwritten ? "yes" : "no"} (confidence=${style.confidence})`
            );

            for (const word of getTextOfSpans(content, style.spans)) {
                console.log(`  - "${word}"`);
            }
        }
    }
}

main().catch((error) => {
    console.error("An error occurred:", error);
    process.exit(1);
});

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные read данные модели.

Использование модели макета

const { AzureKeyCredential, DocumentAnalysisClient } = require("@azure/ai-form-recognizer");

//use your `key` and `endpoint` environment variables
const key = process.env['FR_KEY'];
const endpoint = process.env['FR_ENDPOINT'];

// sample document
const layoutUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/layout.png"

async function main() {
    const client = new DocumentAnalysisClient(endpoint, new AzureKeyCredential(key));

    const poller = await client.beginAnalyzeDocumentFromUrl(
      "prebuilt-layout", layoutUrl);

    // Layout extraction produces basic elements such as pages, words, lines, etc. as well as information about the
    // appearance (styles) of textual elements.
    const { pages, tables } = await poller.pollUntilDone();

    if (!pages || pages.length <= 0) {
      console.log("No pages were extracted from the document.");
    } else {
      console.log("Pages:");
      for (const page of pages) {
        console.log("- Page", page.pageNumber, `(unit: ${page.unit})`);
        console.log(`  ${page.width}x${page.height}, angle: ${page.angle}`);
        console.log(
          `  ${page.lines && page.lines.length} lines, ${page.words && page.words.length} words`
        );

        if (page.lines && page.lines.length > 0) {
          console.log("  Lines:");

          for (const line of page.lines) {
            console.log(`  - "${line.content}"`);

            // The words of the line can also be iterated independently. The words are computed based on their
            // corresponding spans.
            for (const word of line.words()) {
              console.log(`    - "${word.content}"`);
            }
          }
        }
      }
    }

    if (!tables || tables.length <= 0) {
      console.log("No tables were extracted from the document.");
    } else {
      console.log("Tables:");
      for (const table of tables) {
        console.log(
          `- Extracted table: ${table.columnCount} columns, ${table.rowCount} rows (${table.cells.length} cells)`
        );
      }
    }
  }

  main().catch((error) => {
    console.error("An error occurred:", error);
    process.exit(1);
  });

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные данные модели макета.

Использование модели общего документа

const { AzureKeyCredential, DocumentAnalysisClient } = require("@azure/ai-form-recognizer");

//use your `key` and `endpoint` environment variables
const key = process.env['FR_KEY'];
const endpoint = process.env['FR_ENDPOINT'];

// sample document
const documentUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/sample-layout.pdf"

async function main() {
    const client = new DocumentAnalysisClient(endpoint, new AzureKeyCredential(key));

    const poller = await client.beginAnalyzeDocumentFromUrl("prebuilt-document", documentUrl);

    const {
        keyValuePairs
    } = await poller.pollUntilDone();

    if (!keyValuePairs || keyValuePairs.length <= 0) {
        console.log("No key-value pairs were extracted from the document.");
    } else {
        console.log("Key-Value Pairs:");
        for (const {
                key,
                value,
                confidence
            } of keyValuePairs) {
            console.log("- Key  :", `"${key.content}"`);
            console.log("  Value:", `"${(value && value.content) || "<undefined>"}" (${confidence})`);
        }
    }

}

main().catch((error) => {
    console.error("An error occurred:", error);
    process.exit(1);
});

Посетите репозиторий примеров Azure на GitHub и просмотрите общие выходные данные модели документов.

Использование налоговой модели W-2

const { AzureKeyCredential, DocumentAnalysisClient } = require("@azure/ai-form-recognizer");

//use your `key` and `endpoint` environment variables
const key = process.env['FR_KEY'];
const endpoint = process.env['FR_ENDPOINT'];

const w2DocumentURL = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/w2.png"

async function main() {
 const client = new DocumentAnalysisClient(endpoint, new AzureKeyCredential(key));

 const poller = await client.beginAnalyzeDocument("prebuilt-tax.us.w2", w2DocumentURL);

 const {
   documents: [result]
 } = await poller.pollUntilDone();

  if (result) {
    const { Employee, Employer, ControlNumber, TaxYear, AdditionalInfo } = result.fields;

    if (Employee) {
      const { Name, Address, SocialSecurityNumber } = Employee.properties;
      console.log("Employee:");
      console.log("  Name:", Name && Name.content);
      console.log("  SSN/TIN:", SocialSecurityNumber && SocialSecurityNumber.content);
      if (Address && Address.value) {
        const { streetAddress, postalCode } = Address.value;
        console.log("  Address:");
        console.log("    Street Address:", streetAddress);
        console.log("    Postal Code:", postalCode);
      }
    } else {
      console.log("No employee information extracted.");
    }

    if (Employer) {
      const { Name, Address, IdNumber } = Employer.properties;
      console.log("Employer:");
      console.log("  Name:", Name && Name.content);
      console.log("  ID (EIN):", IdNumber && IdNumber.content);

      if (Address && Address.value) {
        const { streetAddress, postalCode } = Address.value;
        console.log("  Address:");
        console.log("    Street Address:", streetAddress);
        console.log("    Postal Code:", postalCode);
      }
    } else {
      console.log("No employer information extracted.");
    }

    console.log("Control Number:", ControlNumber && ControlNumber.content);
    console.log("Tax Year:", TaxYear && TaxYear.content);

    if (AdditionalInfo) {
      console.log("Additional Info:");

      for (const info of AdditionalInfo.values) {
        const { LetterCode, Amount } = info.properties;
        console.log(`- ${LetterCode && LetterCode.content}: ${Amount && Amount.content}`);
      }
    }
  } else {
    throw new Error("Expected at least one document in the result.");
  }
}

main().catch((error) => {
  console.error(error);
  process.exit(1);
});

Посетите репозиторий примеров Azure на сайте GitHub и просмотрите выходные данные налоговой модели W-2.

Использование модели счета

const { AzureKeyCredential, DocumentAnalysisClient } = require("@azure/ai-form-recognizer");

//use your `key` and `endpoint` environment variables
const key = process.env['FR_KEY'];
const endpoint = process.env['FR_ENDPOINT'];

// sample url
const invoiceUrl = "https://github.com/Azure-Samples/cognitive-services-REST-api-samples/raw/master/curl/form-recognizer/rest-api/invoice.pdf";

async function main() {

  const client = new DocumentAnalysisClient(endpoint, new AzureKeyCredential(key));

  const poller = await client.beginAnalyzeDocument("prebuilt-invoice", invoiceUrl);

  const {
      documents: [result]
  } = await poller.pollUntilDone();

  if (result) {
      const invoice = result.fields;

      console.log("Vendor Name:", invoice.VendorName?.content);
      console.log("Customer Name:", invoice.CustomerName?.content);
      console.log("Invoice Date:", invoice.InvoiceDate?.content);
      console.log("Due Date:", invoice.DueDate?.content);

      console.log("Items:");
      for (const {
              properties: item
          } of invoice.Items?.values ?? []) {
          console.log("-", item.ProductCode?.content ?? "<no product code>");
          console.log("  Description:", item.Description?.content);
          console.log("  Quantity:", item.Quantity?.content);
          console.log("  Date:", item.Date?.content);
          console.log("  Unit:", item.Unit?.content);
          console.log("  Unit Price:", item.UnitPrice?.content);
          console.log("  Tax:", item.Tax?.content);
          console.log("  Amount:", item.Amount?.content);
      }

      console.log("Subtotal:", invoice.SubTotal?.content);
      console.log("Previous Unpaid Balance:", invoice.PreviousUnpaidBalance?.content);
      console.log("Tax:", invoice.TotalTax?.content);
      console.log("Amount Due:", invoice.AmountDue?.content);
  } else {
      throw new Error("Expected at least one receipt in the result.");
  }
}

main().catch((error) => {
  console.error("An error occurred:", error);
  process.exit(1);
});

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные данные модели счета.

Использование модели квитанции

const { AzureKeyCredential, DocumentAnalysisClient } = require("@azure/ai-form-recognizer");

//use your `key` and `endpoint` environment variables
const key = process.env['FR_KEY'];
const endpoint = process.env['FR_ENDPOINT'];

// sample url
const receiptUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/receipt.png";

async function main() {

    const client = new DocumentAnalysisClient(endpoint, new AzureKeyCredential(key));

    const poller = await client.beginAnalyzeDocument("prebuilt-receipt", receiptUrl);

    const {
        documents: [result]
    } = await poller.pollUntilDone();

    if (result) {
        const {
            MerchantName,
            Items,
            Total
        } = result.fields;

        console.log("=== Receipt Information ===");
        console.log("Type:", result.docType);
        console.log("Merchant:", MerchantName && MerchantName.content);

        console.log("Items:");
        for (const item of (Items && Items.values) || []) {
            const {
                Description,
                TotalPrice
            } = item.properties;

            console.log("- Description:", Description && Description.content);
            console.log("  Total Price:", TotalPrice && TotalPrice.content);
        }

        console.log("Total:", Total && Total.content);
    } else {
        throw new Error("Expected at least one receipt in the result.");
    }

}

main().catch((err) => {
    console.error("The sample encountered an error:", err);
});

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные данные модели квитанций.

Использование модели удостоверения

const { AzureKeyCredential, DocumentAnalysisClient } = require("@azure/ai-form-recognizer");

//use your `key` and `endpoint` environment variables
const key = process.env['FR_KEY'];
const endpoint = process.env['FR_ENDPOINT'];

// sample document
const idDocumentURL = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/identity_documents.png"

async function main() {
 const client = new DocumentAnalysisClient(endpoint, new AzureKeyCredential(key));

 const poller = await client.beginAnalyzeDocument("prebuilt-idDocument", idDocumentURL);

 const {
   documents: [result]
 } = await poller.pollUntilDone();

  if (result) {
// The identity document model has multiple document types, so we need to know which document type was actually
    extracted.
    if (result.docType === "idDocument.driverLicense") {
      const { FirstName, LastName, DocumentNumber, DateOfBirth, DateOfExpiration, Height, Weight, EyeColor, Endorsements, Restrictions, VehicleClassifications} = result.fields;

// For the sake of the example, we'll only show a few of the fields that are produced.
      console.log("Extracted a Driver License:");
      console.log("  Name:", FirstName && FirstName.content, LastName && LastName.content);
      console.log("  License No.:", DocumentNumber && DocumentNumber.content);
      console.log("  Date of Birth:", DateOfBirth && DateOfBirth.content);
      console.log("  Expiration:", DateOfExpiration && DateOfExpiration.content);
      console.log("  Height:", Height && Height.content);
      console.log("  Weight:", Weight && Weight.content);
      console.log("  Eye color:", EyeColor && EyeColor.content);
      console.log("  Restrictions:", Restrictions && Restrictions.content);
      console.log("  Endorsements:", Endorsements && Endorsements.content);
      console.log("  Class:", VehicleClassifications && VehicleClassifications.content);
    } else if (result.docType === "idDocument.passport") {
// The passport document type extracts and parses the Passport's machine-readable zone
      if (!result.fields.machineReadableZone) {
        throw new Error("No Machine Readable Zone extracted from passport.");
      }

      const {
        FirstName,
        LastName,
        DateOfBirth,
        Nationality,
        DocumentNumber,
        CountryRegion,
        DateOfExpiration,
      } = result.fields.machineReadableZone.properties;

      console.log("Extracted a Passport:");
      console.log("  Name:", FirstName && FirstName.content, LastName && LastName.content);
      console.log("  Date of Birth:", DateOfBirth && DateOfBirth.content);
      console.log("  Nationality:", Nationality && natiNationalityonality.content);
      console.log("  Passport No.:", DocumentNumber && DocumentNumber.content);
      console.log("  Issuer:", CountryRegion && CountryRegion.content);
      console.log("  Expiration Date:", DateOfExpiration && DateOfExpiration.content);
    } else {
// The only reason this would happen is if the client library's schema for the prebuilt identity document model is
      out of date, and a new document type has been introduced.
      console.error("Unknown document type in result:", result);
    }
  } else {
    throw new Error("Expected at least one receipt in the result.");
  }
}

main().catch((error) => {
  console.error("An error occurred:", error);
  process.exit(1);
});

Посетите репозиторий примеров Azure на сайте GitHub и просмотрите выходные данные модели документов идентификатора.

Использование модели визитной карточки

const { AzureKeyCredential, DocumentAnalysisClient } = require("@azure/ai-form-recognizer");

//use your `key` and `endpoint` environment variables
const key = process.env['FR_KEY'];
const endpoint = process.env['FR_ENDPOINT'];

// sample document
const businessCardURL = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/de5e0d8982ab754823c54de47a47e8e499351523/curl/form-recognizer/rest-api/business_card.jpg"

async function main() {
    const client = new DocumentAnalysisClient(endpoint, new AzureKeyCredential(key));

    const poller = await client.beginAnalyzeDocument("prebuilt-businessCard", businessCardURL);

    const {
        documents: [result]
    } = await poller.pollUntilDone();

    if (result) {
        const businessCard = result.fields;
        console.log("=== Business Card Information ===");

        // There are more fields than just these few, and the model allows for multiple contact & company names as well as
        // phone numbers, though we'll only show the first extracted values here.
        const name = businessCard.ContactNames && businessCard.ContactNames.values[0];
        if (name) {
            const {
                FirstName,
                LastName
            } = name.properties;
            console.log("Name:", FirstName && FirstName.content, LastName && LastName.content);
        }

        const company = businessCard.CompanyNames && businessCard.CompanyNames.values[0];
        if (company) {
            console.log("Company:", company.content);
        }

        const address = businessCard.Addresses && businessCard.Addresses.values[0];
        if (address) {
            console.log("Address:", address.content);
        }
        const jobTitle = businessCard.JobTitles && businessCard.JobTitles.values[0];
        if (jobTitle) {
            console.log("Job title:", jobTitle.content);
        }
        const department = businessCard.Departments && businessCard.Departments.values[0];
        if (department) {
            console.log("Department:", department.content);
        }
        const email = businessCard.Emails && businessCard.Emails.values[0];
        if (email) {
            console.log("Email:", email.content);
        }
        const workPhone = businessCard.WorkPhones && businessCard.WorkPhones.values[0];
        if (workPhone) {
            console.log("Work phone:", workPhone.content);
        }
        const website = businessCard.Websites && businessCard.Websites.values[0];
        if (website) {
            console.log("Website:", website.content);
        }
    } else {
        throw new Error("Expected at least one business card in the result.");
    }
}

main().catch((error) => {
    console.error("An error occurred:", error);
    process.exit(1);
});

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные данные модели визитных карточек.

Справочник по | пакету REST API для | пакета SDK для клиентской библиотеки |(PyPi) | Samples | Rest API

Необходимые компоненты

  • Подписка Azure — создайте бесплатную учетную запись.

  • Python 3.7 или более поздней версии. Установка Python должна включать pip. Вы можете проверить, установлен ли pip, выполнив команду pip --version в командной строке. Чтобы использовать pip, установите последнюю версию Python.

  • Последняя версия Visual Studio Code или предпочтительная интегрированная среда разработки. См. статью "Начало работы с Python" в Visual Studio Code.

  • Служба ИИ Azure или ресурс аналитики документов. Создание одной службы или нескольких служб. Используйте бесплатную ценовую категорию (F0), чтобы опробовать службу, а затем выполните обновление до платного уровня для рабочей среды.

  • Ключ и конечная точка из ресурса, создаваемого для подключения приложения к службе аналитики документов Azure.

    1. После развертывания ресурса выберите Перейти к ресурсу.
    2. В меню навигации слева выберите "Ключи" и "Конечная точка".
    3. Скопируйте один из ключей и конечной точки для использования далее в этой статье.

    Снимок экрана: расположение ключей и конечной точки на портале Azure.

  • Файл документа по URL-адресу. Для этого проекта можно использовать примеры форм, указанных в следующей таблице для каждой функции:

    Функция modelID document-url
    Модель чтения prebuilt-read Пример брошюры
    Модель макета prebuilt-layout Пример подтверждения резервирования
    Модель с формой W-2 prebuilt-tax.us.w2 Пример формы W-2
    Модель накладных prebuilt-invoice Пример счета
    Модель получения prebuilt-receipt Пример квитанции
    Модель документа идентификатора prebuilt-idDocument Пример удостоверения

Настройка переменных среды

Чтобы взаимодействовать со службой аналитики DocumentAnalysisClient документов, необходимо создать экземпляр класса. Для этого создайте экземпляр клиента с портал Azure key endpoint. Для этого проекта используйте переменные среды для хранения и доступа к учетным данным.

Внимание

Если вы используете ключ API, сохраните его в другом месте, например в Azure Key Vault. Не включайте ключ API непосредственно в код и никогда не публикуйте его.

Дополнительные сведения о безопасности служб ИИ см. в статье "Проверка подлинности запросов к службам ИИ Azure".

Чтобы задать переменную среды для ключа ресурса Аналитики документов, откройте окно консоли и следуйте инструкциям в вашей операционной системе и среде разработки. Замените <yourKey> и <yourEndpoint> значениями из ресурса в портал Azure.

Переменные среды в Windows не учитывает регистр. Они обычно объявляются в верхнем регистре, с словами, присоединенными подчеркиванием. В командной строке выполните следующие команды:

  1. Задайте ключевую переменную:

    setx DI_KEY <yourKey>
    
  2. Настройка переменной конечной точки

    setx DI_ENDPOINT <yourEndpoint>
    
  3. Закройте окно командной строки после задания переменных среды. Значения остаются до тех пор, пока не измените их еще раз.

  4. Перезапустите все запущенные программы, которые считывают переменную среды. Например, если вы используете Visual Studio или Visual Studio Code в качестве редактора, перезапустите перед запуском примера кода.

Ниже приведены несколько дополнительных полезных команд для использования с переменными среды:

Команда Действие Пример
setx VARIABLE_NAME= Удалите переменную среды, задав значение пустой строке. setx DI_KEY=
setx VARIABLE_NAME=value Задайте или измените значение переменной среды. setx DI_KEY=<yourKey>
set VARIABLE_NAME Отображение значения определенной переменной среды. set DI_KEY
set Отображение всех переменных среды. set

Настройка среды программирования

Откройте окно консоли в локальной среде и установите клиентская библиотека Аналитики документов Azure для Python с помощью pip:

pip install azure-ai-documentintelligence==1.0.0b4

Создание приложения Python

Чтобы взаимодействовать со службой аналитики DocumentIntelligenceClient документов, необходимо создать экземпляр класса. Для этого создайте AzureKeyCredential ключ из портал Azure и DocumentIntelligenceClient экземпляра с AzureKeyCredential конечной точкой аналитики документов.

  1. Создайте файл Python с именем form_recognizer_quickstart.py в редакторе или интегрированной среде разработки.

  2. Откройте файл form_recognizer_quickstart.py и выберите один из следующих примеров кода и скопируйте и вставьте в приложение:

    • Предварительно созданная модель чтения находится в основе всех моделей аналитики документов и может обнаруживать строки, слова, расположения и языки. Макет, общие документы, предварительно созданные и пользовательские модели используют read модель в качестве основы для извлечения текстов из документов.
    • Предварительно созданная модель макета извлекает текстовые и текстовые расположения, таблицы, знаки выделения и сведения о структуре из документов и изображений.
    • Предварительно созданная модель tax.us.w2 извлекает информацию о налоговых формах внутренней налоговой службы США (IRS).
    • Предварительно созданная модель счета извлекает ключевые поля и элементы строк из счетов-фактур продаж в различных форматах.
    • Предварительно созданная модель квитанций извлекает ключевые сведения из печатных и рукописных квитанций о продажах.
    • Предварительно созданная модель idDocument извлекает ключевые сведения из лицензий водителей США; международные биографические страницы паспортов; Идентификаторы штатов США; карточки социального страхования; и постоянные карточки резидентов.
  3. Запустите код Python из командной строки.

    python form_recognizer_quickstart.py
    

Использование модели чтения

import os
from azure.core.credentials import AzureKeyCredential
from azure.ai.documentintelligence import DocumentIntelligenceClient
from azure.ai.documentintelligence.models import AnalyzeResult

# use your `key` and `endpoint` environment variables
key = os.environ.get('DI_KEY')
endpoint = os.environ.get('DI_ENDPOINT')

# helper functions
def get_words(page, line):
    result = []
    for word in page.words:
        if _in_span(word, line.spans):
            result.append(word)
    return result


def _in_span(word, spans):
    for span in spans:
        if word.span.offset >= span.offset and (word.span.offset + word.span.length) <= (span.offset + span.length):
            return True
    return False


def analyze_read():
    # sample document
    formUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/read.png"

    client = DocumentIntelligenceClient(
        endpoint=endpoint, credential=AzureKeyCredential(key)
    )

    poller = client.begin_analyze_document(
        "prebuilt-read", AnalyzeDocumentRequest(url_source=formUrl
    ))
    result: AnalyzeResult = poller.result()

    print("----Languages detected in the document----")
    if result.languages is not None:
        for language in result.languages:
            print(f"Language code: '{language.locale}' with confidence {language.confidence}")

    print("----Styles detected in the document----")
    if result.styles:
        for style in result.styles:
            if style.is_handwritten:
                print("Found the following handwritten content: ")
                print(",".join([result.content[span.offset : span.offset + span.length] for span in style.spans]))
            if style.font_style:
                print(f"The document contains '{style.font_style}' font style, applied to the following text: ")
                print(",".join([result.content[span.offset : span.offset + span.length] for span in style.spans]))

    for page in result.pages:
        print(f"----Analyzing document from page #{page.page_number}----")
        print(f"Page has width: {page.width} and height: {page.height}, measured with unit: {page.unit}")

        if page.lines:
            for line_idx, line in enumerate(page.lines):
                words = get_words(page, line)
                print(
                    f"...Line # {line_idx} has {len(words)} words and text '{line.content}' within bounding polygon '{line.polygon}'"
                )

                for word in words:
                    print(f"......Word '{word.content}' has a confidence of {word.confidence}")

        if page.selection_marks:
            for selection_mark in page.selection_marks:
                print(
                    f"...Selection mark is '{selection_mark.state}' within bounding polygon "
                    f"'{selection_mark.polygon}' and has a confidence of {selection_mark.confidence}"
                )

    if result.paragraphs:
        print(f"----Detected #{len(result.paragraphs)} paragraphs in the document----")
        for paragraph in result.paragraphs:
            print(f"Found paragraph with role: '{paragraph.role}' within {paragraph.bounding_regions} bounding region")
            print(f"...with content: '{paragraph.content}'")

        result.paragraphs.sort(key=lambda p: (p.spans.sort(key=lambda s: s.offset), p.spans[0].offset))
        print("-----Print sorted paragraphs-----")
        for idx, paragraph in enumerate(result.paragraphs):
            print(
                f"...paragraph:{idx} with offset: {paragraph.spans[0].offset} and length: {paragraph.spans[0].length}"
            )

    print("----------------------------------------")


if __name__ == "__main__":
    analyze_read()

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные read данные модели.

Использование модели макета

import os
from azure.core.credentials import AzureKeyCredential
from azure.ai.documentintelligence import DocumentIntelligenceClient
from azure.ai.documentintelligence.models import AnalyzeResult


# use your `key` and `endpoint` environment variables
key = os.environ.get('DI_KEY')
endpoint = os.environ.get('DI_ENDPOINT')


def analyze_layout():
    # sample document
    formUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/layout.png"

    client = DocumentIntelligenceClient(
        endpoint=endpoint, credential=AzureKeyCredential(key)
    )

    poller = client.begin_analyze_document(
        "prebuilt-layout", AnalyzeDocumentRequest(url_source=formUrl
    ))
    result: AnalyzeResult = poller.result()

    if result.styles and any([style.is_handwritten for style in result.styles]):
        print("Document contains handwritten content")
    else:
        print("Document does not contain handwritten content")

    for page in result.pages:
        print(f"----Analyzing layout from page #{page.page_number}----")
        print(f"Page has width: {page.width} and height: {page.height}, measured with unit: {page.unit}")

        if page.lines:
            for line_idx, line in enumerate(page.lines):
                words = get_words(page, line)
                print(
                    f"...Line # {line_idx} has word count {len(words)} and text '{line.content}' "
                    f"within bounding polygon '{line.polygon}'"
                )

                for word in words:
                    print(f"......Word '{word.content}' has a confidence of {word.confidence}")

        if page.selection_marks:
            for selection_mark in page.selection_marks:
                print(
                    f"Selection mark is '{selection_mark.state}' within bounding polygon "
                    f"'{selection_mark.polygon}' and has a confidence of {selection_mark.confidence}"
                )

    if result.tables:
        for table_idx, table in enumerate(result.tables):
            print(f"Table # {table_idx} has {table.row_count} rows and " f"{table.column_count} columns")
            if table.bounding_regions:
                for region in table.bounding_regions:
                    print(f"Table # {table_idx} location on page: {region.page_number} is {region.polygon}")
            for cell in table.cells:
                print(f"...Cell[{cell.row_index}][{cell.column_index}] has text '{cell.content}'")
                if cell.bounding_regions:
                    for region in cell.bounding_regions:
                        print(f"...content on page {region.page_number} is within bounding polygon '{region.polygon}'")

    print("----------------------------------------")



if __name__ == "__main__":
    analyze_layout()

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные данные модели макета.

Использование налоговой модели W-2

import os
from azure.core.credentials import AzureKeyCredential
from azure.ai.documentintelligence import DocumentIntelligenceClient
from azure.ai.documentintelligence.models import AnalyzeResult

# use your `key` and `endpoint` environment variables
key = os.environ.get('DI_KEY')
endpoint = os.environ.get('DI_ENDPOINT')

# formatting function
def format_address_value(address_value):
    return f"\n......House/building number: {address_value.house_number}\n......Road: {address_value.road}\n......City: {address_value.city}\n......State: {address_value.state}\n......Postal code: {address_value.postal_code}"


def analyze_tax_us_w2():
    # sample document
    formUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/w2.png"

    client = DocumentIntelligenceClient(
        endpoint=endpoint, credential=AzureKeyCredential(key)
    )

    poller = client.begin_analyze_document(
        "prebuilt-tax.us.w2",  AnalyzeDocumentRequest(url_source=formUrl
    ))

    w2s: AnalyzeResult =  poller.result()

        if w2s.documents:
        for idx, w2 in enumerate(w2s.documents):
            print(f"--------Analyzing US Tax W-2 Form #{idx + 1}--------")
            if w2.fields:
                form_variant = w2.fields.get("W2FormVariant")
                if form_variant:
                    print(
                        f"Form variant: {form_variant.get('valueString')} has confidence: " f"{form_variant.confidence}"
                    )
                tax_year = w2.fields.get("TaxYear")
                if tax_year:
                    print(f"Tax year: {tax_year.get('valueString')} has confidence: {tax_year.confidence}")
                w2_copy = w2.fields.get("W2Copy")
                if w2_copy:
                    print(f"W-2 Copy: {w2_copy.get('valueString')} has confidence: {w2_copy.confidence}")
                employee = w2.fields.get("Employee")
                if employee:
                    print("Employee data:")
                    employee_name = employee.get("valueObject").get("Name")
                    if employee_name:
                        f"confidence: {fed_income_tax_withheld.confidence}"
                    )
                social_security_wages = w2.fields.get("SocialSecurityWages")
                if social_security_wages:
                    print(
                        f"Social Security wages: {social_security_wages.get('valueNumber')} has confidence: "
                        f"{social_security_wages.confidence}"
                    )
                social_security_tax_withheld = w2.fields.get("SocialSecurityTaxWithheld")
                if social_security_tax_withheld:
                    print(
                        f"Social Security tax withheld: {social_security_tax_withheld.get('valueNumber')} "
                        f"has confidence: {social_security_tax_withheld.confidence}"
                    )
                medicare_wages_tips = w2.fields.get("MedicareWagesAndTips")
                if medicare_wages_tips:
                    print(
                        f"Medicare wages and tips: {medicare_wages_tips.get('valueNumber')} has confidence: "
                        f"{medicare_wages_tips.confidence}"
                    )
                medicare_tax_withheld = w2.fields.get("MedicareTaxWithheld")
                if medicare_tax_withheld:
                    print(
                        f"Medicare tax withheld: {medicare_tax_withheld.get('valueNumber')} has confidence: "
                        f"{medicare_tax_withheld.confidence}"
                    )
                social_security_tips = w2.fields.get("SocialSecurityTips")
                if social_security_tips:
                    print(
                        f"Social Security tips: {social_security_tips.get('valueNumber')} has confidence: "
                        f"{social_security_tips.confidence}"
                    )
                allocated_tips = w2.fields.get("AllocatedTips")
                if allocated_tips:
                    print(
                        f"Allocated tips: {allocated_tips.get('valueNumber')} has confidence: {allocated_tips.confidence}"
                    )
                verification_code = w2.fields.get("VerificationCode")
                if verification_code:
                    print(
                        f"Verification code: {verification_code.get('valueNumber')} has confidence: {verification_code.confidence}"
                    )
                dependent_care_benefits = w2.fields.get("DependentCareBenefits")
                if dependent_care_benefits:
                    print(
                        f"Dependent care benefits: {dependent_care_benefits.get('valueNumber')} has confidence: {dependent_care_benefits.confidence}"
                    )
                non_qualified_plans = w2.fields.get("NonQualifiedPlans")
                if non_qualified_plans:
                    print(
                        f"Non-qualified plans: {non_qualified_plans.get('valueNumber')} has confidence: {non_qualified_plans.confidence}"
                    )
                additional_info = w2.fields.get("AdditionalInfo")
                if additional_info:
                    print("Additional information:")
                    for item in additional_info.get("valueArray"):
                        letter_code = item.get("valueObject").get("LetterCode")
                        if letter_code:
                            print(
                                f"...Letter code: {letter_code.get('valueString')} has confidence: {letter_code.confidence}"
                            )
                        amount = item.get("valueObject").get("Amount")
                        if amount:
                            print(f"...Amount: {amount.get('valueNumber')} has confidence: {amount.confidence}")
                is_statutory_employee = w2.fields.get("IsStatutoryEmployee")
                if is_statutory_employee:
                    print(
                        f"Is statutory employee: {is_statutory_employee.get('valueString')} has confidence: {is_statutory_employee.confidence}"
                    )
                is_retirement_plan = w2.fields.get("IsRetirementPlan")
                if is_retirement_plan:
                    print(
                        f"Is retirement plan: {is_retirement_plan.get('valueString')} has confidence: {is_retirement_plan.confidence}"
                    )
                third_party_sick_pay = w2.fields.get("IsThirdPartySickPay")
                if third_party_sick_pay:
                    print(
                        f"Is third party sick pay: {third_party_sick_pay.get('valueString')} has confidence: {third_party_sick_pay.confidence}"
                    )
                other_info = w2.fields.get("Other")
                if other_info:
                    print(f"Other information: {other_info.get('valueString')} has confidence: {other_info.confidence}")
                state_tax_info = w2.fields.get("StateTaxInfos")
                if state_tax_info:
                    print("State Tax info:")
                    for tax in state_tax_info.get("valueArray"):
                        state = tax.get("valueObject").get("State")
                        if state:
                            print(f"...State: {state.get('valueString')} has confidence: {state.confidence}")
                        employer_state_id_number = tax.get("valueObject").get("EmployerStateIdNumber")
                        if employer_state_id_number:
                            print(
                                f"...Employer state ID number: {employer_state_id_number.get('valueString')} has "
                                f"confidence: {employer_state_id_number.confidence}"
                            )
                        state_wages_tips = tax.get("valueObject").get("StateWagesTipsEtc")
                        if state_wages_tips:
                            print(
                                f"...State wages, tips, etc: {state_wages_tips.get('valueNumber')} has confidence: "
                                f"{state_wages_tips.confidence}"
                            )
                        state_income_tax = tax.get("valueObject").get("StateIncomeTax")
                        if state_income_tax:
                            print(
                                f"...State income tax: {state_income_tax.get('valueNumber')} has confidence: "
                                f"{state_income_tax.confidence}"
                            )
                local_tax_info = w2.fields.get("LocalTaxInfos")
                if local_tax_info:
                    print("Local Tax info:")
                    for tax in local_tax_info.get("valueArray"):
                        local_wages_tips = tax.get("valueObject").get("LocalWagesTipsEtc")
                        if local_wages_tips:
                            print(
                                f"...Local wages, tips, etc: {local_wages_tips.get('valueNumber')} has confidence: "
                                f"{local_wages_tips.confidence}"
                            )
                        local_income_tax = tax.get("valueObject").get("LocalIncomeTax")
                        if local_income_tax:
                            print(
                                f"...Local income tax: {local_income_tax.get('valueNumber')} has confidence: "
                                f"{local_income_tax.confidence}"
                            )
                        locality_name = tax.get("valueObject").get("LocalityName")
                        if locality_name:
                            print(
                                f"...Locality name: {locality_name.get('valueString')} has confidence: "
                                f"{locality_name.confidence}"
                            )


                print("----------------------------------------")


if __name__ == "__main__":
    analyze_tax_us_w2()

Посетите репозиторий примеров Azure на сайте GitHub и просмотрите выходные данные налоговой модели W-2.

Использование модели счета

import os
from azure.core.credentials import AzureKeyCredential
from azure.ai.documentintelligence import DocumentIntelligenceClient
from azure.ai.documentintelligence.models import AnalyzeResult

# use your `key` and `endpoint` environment variables
key = os.environ.get('DI_KEY')
endpoint = os.environ.get('DI_ENDPOINT')

def analyze_invoice():

    invoiceUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/sample-invoice.pdf"

    client = DocumentIntelligenceClient(
        endpoint=endpoint, credential=AzureKeyCredential(key)
    )

    poller = client.begin_analyze_document(
        "prebuilt-invoice", AnalyzeDocumentRequest(url_source=formUrl), locale="en-US")

    result: AnalyzeResult = poller.result()

    if invoices.documents:
        for idx, invoice in enumerate(invoices.documents):
            print(f"--------Analyzing invoice #{idx + 1}--------")
            if invoice.fields:
                vendor_name = invoice.fields.get("VendorName")
                if vendor_name:
                    print(f"Vendor Name: {vendor_name.get('content')} has confidence: {vendor_name.get('confidence')}")
                vendor_address = invoice.fields.get("VendorAddress")
                if vendor_address:
                    print(
                        f"Vendor Address: {vendor_address.get('content')} has confidence: {vendor_address.get('confidence')}"
                    )
                vendor_address_recipient = invoice.fields.get("VendorAddressRecipient")
                if vendor_address_recipient:
                    print(
                        f"Vendor Address Recipient: {vendor_address_recipient.get('content')} has confidence: {vendor_address_recipient.get('confidence')}"
                    )
                customer_name = invoice.fields.get("CustomerName")
                if customer_name:
                    print(
                        f"Customer Name: {customer_name.get('content')} has confidence: {customer_name.get('confidence')}"
                    )
                customer_id = invoice.fields.get("CustomerId")
                if invoice_id:
                    print(f"Invoice Id: {invoice_id.get('content')} has confidence: {invoice_id.get('confidence')}")
                invoice_date = invoice.fields.get("InvoiceDate")
                if invoice_date:
                    print(
                        f"Invoice Date: {invoice_date.get('content')} has confidence: {invoice_date.get('confidence')}"
                    )
                invoice_total = invoice.fields.get("InvoiceTotal")
                if invoice_total:
                    print(
                        f"Invoice Total: {invoice_total.get('content')} has confidence: {invoice_total.get('confidence')}"
                    )
                due_date = invoice.fields.get("DueDate")
                if due_date:
                    print(f"Due Date: {due_date.get('content')} has confidence: {due_date.get('confidence')}")
                purchase_order = invoice.fields.get("PurchaseOrder")
                if purchase_order:
                    print(
                        f"Purchase Order: {purchase_order.get('content')} has confidence: {purchase_order.get('confidence')}"
                    )
                billing_address = invoice.fields.get("BillingAddress")
                if billing_address:
                    print(
                        f"Billing Address: {billing_address.get('content')} has confidence: {billing_address.get('confidence')}"
                    )
                billing_address_recipient = invoice.fields.get("BillingAddressRecipient")
                if billing_address_recipient:
                    print(
                        f"Billing Address Recipient: {billing_address_recipient.get('content')} has confidence: {billing_address_recipient.get('confidence')}"
                    )
                shipping_address = invoice.fields.get("ShippingAddress")
                if shipping_address:
                    print(
                        f"Shipping Address: {shipping_address.get('content')} has confidence: {shipping_address.get('confidence')}"
                    )
                shipping_address_recipient = invoice.fields.get("ShippingAddressRecipient")
                if shipping_address_recipient:
                    print(
                        f"Shipping Address Recipient: {shipping_address_recipient.get('content')} has confidence: {shipping_address_recipient.get('confidence')}"
                    )
                print("Invoice items:")
                items = invoice.fields.get("Items")
                if items:
                    for idx, item in enumerate(items.get("valueArray")):
                        print(f"...Item #{idx + 1}")
                        item_description = item.get("valueObject").get("Description")
                        if item_description:
                            print(
                                f"......Description: {item_description.get('content')} has confidence: {item_description.get('confidence')}"
                            )
                        item_quantity = item.get("valueObject").get("Quantity")
                        if item_quantity:
                            print(
                                f"......Quantity: {item_quantity.get('content')} has confidence: {item_quantity.get('confidence')}"
                            )
                        unit = item.get("valueObject").get("Unit")
                        if unit:
                            print(f"......Unit: {unit.get('content')} has confidence: {unit.get('confidence')}")
                        unit_price = item.get("valueObject").get("UnitPrice")
                        if unit_price:
                            unit_price_code = (
                                unit_price.get("valueCurrency").get("currencyCode")
                                if unit_price.get("valueCurrency").get("currencyCode")
                                else ""
                            )
                            print(
                                f"......Unit Price: {unit_price.get('content')}{unit_price_code} has confidence: {unit_price.get('confidence')}"
                            )
                        product_code = item.get("valueObject").get("ProductCode")
                        if product_code:
                            print(
                                f"......Product Code: {product_code.get('content')} has confidence: {product_code.get('confidence')}"
                            )
                        item_date = item.get("valueObject").get("Date")
                        if item_date:
                            print(
                                f"......Date: {item_date.get('content')} has confidence: {item_date.get('confidence')}"
                            )
                        tax = item.get("valueObject").get("Tax")
                        if tax:
                            print(f"......Tax: {tax.get('content')} has confidence: {tax.get('confidence')}")
                        amount = item.get("valueObject").get("Amount")
                        if amount:
                            print(f"......Amount: {amount.get('content')} has confidence: {amount.get('confidence')}")
                subtotal = invoice.fields.get("SubTotal")
                if subtotal:
                    print(f"Subtotal: {subtotal.get('content')} has confidence: {subtotal.get('confidence')}")
                total_tax = invoice.fields.get("TotalTax")
                if total_tax:
                    print(f"Total Tax: {total_tax.get('content')} has confidence: {total_tax.get('confidence')}")
                previous_unpaid_balance = invoice.fields.get("PreviousUnpaidBalance")
                if previous_unpaid_balance:
                    print(
                        f"Previous Unpaid Balance: {previous_unpaid_balance.get('content')} has confidence: {previous_unpaid_balance.get('confidence')}"
                    )
                amount_due = invoice.fields.get("AmountDue")
                if amount_due:
                    print(f"Amount Due: {amount_due.get('content')} has confidence: {amount_due.get('confidence')}")
                service_start_date = invoice.fields.get("ServiceStartDate")
                if service_start_date:
                    print(
                        f"Service Start Date: {service_start_date.get('content')} has confidence: {service_start_date.get('confidence')}"
                    )
                service_end_date = invoice.fields.get("ServiceEndDate")
                if service_end_date:
                    print(
                        f"Service End Date: {service_end_date.get('content')} has confidence: {service_end_date.get('confidence')}"
                    )
                service_address = invoice.fields.get("ServiceAddress")
                if service_address:
                    print(
                        f"Service Address: {service_address.get('content')} has confidence: {service_address.get('confidence')}"
                    )
                service_address_recipient = invoice.fields.get("ServiceAddressRecipient")
                if service_address_recipient:
                    print(
                        f"Service Address Recipient: {service_address_recipient.get('content')} has confidence: {service_address_recipient.get('confidence')}"
                    )
                remittance_address = invoice.fields.get("RemittanceAddress")
                if remittance_address:
                    print(
                        f"Remittance Address: {remittance_address.get('content')} has confidence: {remittance_address.get('confidence')}"
                    )
                remittance_address_recipient = invoice.fields.get("RemittanceAddressRecipient")
                if remittance_address_recipient:
                    print(
                        f"Remittance Address Recipient: {remittance_address_recipient.get('content')} has confidence: {remittance_address_recipient.get('confidence')}"
                    )


        print("----------------------------------------")

if __name__ == "__main__":
    analyze_invoice()

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные данные модели счета.

Использование модели квитанции

import os
from azure.core.credentials import AzureKeyCredential
from azure.ai.documentintelligence import DocumentIntelligenceClient
from azure.ai.documentintelligence.models import AnalyzeResult

# use your `key` and `endpoint` environment variables
key = os.environ.get('DI_KEY')
endpoint = os.environ.get('DI_ENDPOINT')

def analyze_receipts():
    # sample document
    receiptUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/receipt.png"

   client = DocumentIntelligenceClient(
        endpoint=endpoint, credential=AzureKeyCredential(key)
    )
    poller = client.begin_analyze_document(
        "prebuilt-receipt", AnalyzeDocumentRequest(url_source=receiptUrl), locale="en-US"
    )
    receipts: AnalyzeResult = poller.result()

    if receipts.documents:
        for idx, receipt in enumerate(receipts.documents):
            print(f"--------Analysis of receipt #{idx + 1}--------")
            print(f"Receipt type: {receipt.doc_type if receipt.doc_type else 'N/A'}")
            if receipt.fields:
                merchant_name = receipt.fields.get("MerchantName")
                if merchant_name:
                    print(
                        f"Merchant Name: {merchant_name.get('valueString')} has confidence: "
                        f"{merchant_name.confidence}"
                    )
                transaction_date = receipt.fields.get("TransactionDate")
                if transaction_date:
                    print(
                        f"Transaction Date: {transaction_date.get('valueDate')} has confidence: "
                        f"{transaction_date.confidence}"
                    )
                items = receipt.fields.get("Items")
                if items:
                    print("Receipt items:")
                    for idx, item in enumerate(items.get("valueArray")):
                        print(f"...Item #{idx + 1}")
                        item_description = item.get("valueObject").get("Description")
                        if item_description:
                            print(
                                f"......Item Description: {item_description.get('valueString')} has confidence: "
                                f"{item_description.confidence}"
                            )
                        item_quantity = item.get("valueObject").get("Quantity")
                        if item_quantity:
                            print(
                                f"......Item Quantity: {item_quantity.get('valueString')} has confidence: "
                                f"{item_quantity.confidence}"
                            )
                        item_total_price = item.get("valueObject").get("TotalPrice")
                        if item_total_price:
                            print(
                                f"......Total Item Price: {format_price(item_total_price.get('valueCurrency'))} has confidence: "
                                f"{item_total_price.confidence}"
                            )
                subtotal = receipt.fields.get("Subtotal")
                if subtotal:
                    print(
                        f"Subtotal: {format_price(subtotal.get('valueCurrency'))} has confidence: {subtotal.confidence}"
                    )
                tax = receipt.fields.get("TotalTax")
                if tax:
                    print(f"Total tax: {format_price(tax.get('valueCurrency'))} has confidence: {tax.confidence}")
                tip = receipt.fields.get("Tip")
                if tip:
                    print(f"Tip: {format_price(tip.get('valueCurrency'))} has confidence: {tip.confidence}")
                total = receipt.fields.get("Total")
                if total:
                    print(f"Total: {format_price(total.get('valueCurrency'))} has confidence: {total.confidence}")
            print("--------------------------------------")



if __name__ == "__main__":
    analyze_receipts()

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные данные модели квитанций.

Использование модели удостоверения

import os
from azure.core.credentials import AzureKeyCredential
from azure.ai.documentintelligence import DocumentIntelligenceClient
from azure.ai.documentintelligence.models import AnalyzeResult

# use your `key` and `endpoint` environment variables
key = os.environ.get('DI_KEY')
endpoint = os.environ.get('DI_ENDPOINT')

def analyze_identity_documents():
# sample document
    identityUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/identity_documents.png"

   client = DocumentIntelligenceClient(
        endpoint=endpoint, credential=AzureKeyCredential(key)
    )

    poller =client.begin_analyze_document(
            "prebuilt-idDocument", AnalyzeDocumentRequest(url_source=identityUrl)
        )
     id_documents: AnalyzeResult = poller.result()

    if id_documents.documents:
        for idx, id_document in enumerate(id_documents.documents):
            print(f"--------Analyzing ID document #{idx + 1}--------")
            if id_document.fields:
                first_name = id_document.fields.get("FirstName")
                if first_name:
                    print(f"First Name: {first_name.get('valueString')} has confidence: {first_name.confidence}")
                last_name = id_document.fields.get("LastName")
                if last_name:
                    print(f"Last Name: {last_name.get('valueString')} has confidence: {last_name.confidence}")
                document_number = id_document.fields.get("DocumentNumber")
                if document_number:
                    print(
                        f"Document Number: {document_number.get('valueString')} has confidence: {document_number.confidence}"
                    )
                dob = id_document.fields.get("DateOfBirth")
                if dob:
                    print(f"Date of Birth: {dob.get('valueDate')} has confidence: {dob.confidence}")
                doe = id_document.fields.get("DateOfExpiration")
                if doe:
                    print(f"Date of Expiration: {doe.get('valueDate')} has confidence: {doe.confidence}")
                sex = id_document.fields.get("Sex")
                if sex:
                    print(f"Sex: {sex.get('valueString')} has confidence: {sex.confidence}")
                address = id_document.fields.get("Address")
                if address:
                    print(f"Address: {address.get('valueString')} has confidence: {address.confidence}")
                country_region = id_document.fields.get("CountryRegion")
                if country_region:
                    print(
                        f"Country/Region: {country_region.get('valueCountryRegion')} has confidence: {country_region.confidence}"
                    )
                region = id_document.fields.get("Region")
                if region:
                    print(f"Region: {region.get('valueString')} has confidence: {region.confidence}")


        print("--------------------------------------")

if __name__ == "__main__":
    analyze_identity_documents()

Посетите репозиторий примеров Azure на сайте GitHub и просмотрите выходные данные модели документов идентификатора.

Необходимые компоненты

  • Подписка Azure — создайте бесплатную учетную запись.

  • Python 3.7 или более поздней версии. Установка Python должна включать pip. Вы можете проверить, установлен ли pip, выполнив команду pip --version в командной строке. Чтобы использовать pip, установите последнюю версию Python.

  • Последняя версия Visual Studio Code или предпочтительная интегрированная среда разработки. См. статью "Начало работы с Python" в Visual Studio Code.

  • Служба ИИ Azure или ресурс аналитики документов. Создание одной службы или нескольких служб. Используйте бесплатную ценовую категорию (F0), чтобы опробовать службу, а затем выполните обновление до платного уровня для рабочей среды.

  • Ключ и конечная точка из ресурса, создаваемого для подключения приложения к службе аналитики документов Azure.

    1. После развертывания ресурса выберите Перейти к ресурсу.
    2. В меню навигации слева выберите "Ключи" и "Конечная точка".
    3. Скопируйте один из ключей и конечной точки для использования далее в этой статье.

    Снимок экрана: расположение ключей и конечной точки на портале Azure.

  • Файл документа по URL-адресу. Для этого проекта можно использовать примеры форм, указанных в следующей таблице для каждой функции:

    Функция modelID document-url
    Модель чтения prebuilt-read Пример брошюры
    Модель макета prebuilt-layout Пример подтверждения резервирования
    Модель с формой W-2 prebuilt-tax.us.w2 Пример формы W-2
    Модель накладных prebuilt-invoice Пример счета
    Модель получения prebuilt-receipt Пример квитанции
    Модель документа идентификатора prebuilt-idDocument Пример удостоверения
    Модель визитных карточек prebuilt-businessCard Пример визитной карточки

Настройка переменных среды

Чтобы взаимодействовать со службой аналитики DocumentAnalysisClient документов, необходимо создать экземпляр класса. Для этого создайте экземпляр клиента с портал Azure key endpoint. Для этого проекта используйте переменные среды для хранения и доступа к учетным данным.

Внимание

Если вы используете ключ API, сохраните его в другом месте, например в Azure Key Vault. Не включайте ключ API непосредственно в код и никогда не публикуйте его.

Дополнительные сведения о безопасности служб ИИ см. в статье "Проверка подлинности запросов к службам ИИ Azure".

Чтобы задать переменную среды для ключа ресурса Аналитики документов, откройте окно консоли и следуйте инструкциям в вашей операционной системе и среде разработки. Замените <yourKey> и <yourEndpoint> значениями из ресурса в портал Azure.

Переменные среды в Windows не учитывает регистр. Они обычно объявляются в верхнем регистре, с словами, присоединенными подчеркиванием. В командной строке выполните следующие команды:

  1. Задайте ключевую переменную:

    setx DI_KEY <yourKey>
    
  2. Настройка переменной конечной точки

    setx DI_ENDPOINT <yourEndpoint>
    
  3. Закройте окно командной строки после задания переменных среды. Значения остаются до тех пор, пока не измените их еще раз.

  4. Перезапустите все запущенные программы, которые считывают переменную среды. Например, если вы используете Visual Studio или Visual Studio Code в качестве редактора, перезапустите перед запуском примера кода.

Ниже приведены несколько дополнительных полезных команд для использования с переменными среды:

Команда Действие Пример
setx VARIABLE_NAME= Удалите переменную среды, задав значение пустой строке. setx DI_KEY=
setx VARIABLE_NAME=value Задайте или измените значение переменной среды. setx DI_KEY=<yourKey>
set VARIABLE_NAME Отображение значения определенной переменной среды. set DI_KEY
set Отображение всех переменных среды. set

Настройка среды программирования

Откройте окно консоли в локальной среде и установите клиентская библиотека Аналитики документов Azure для Python с помощью pip:

pip install azure-ai-formrecognizer==3.2.0

Создание приложения Python

Чтобы взаимодействовать со службой аналитики DocumentAnalysisClient документов, необходимо создать экземпляр класса. Для этого создайте AzureKeyCredential ключ из портал Azure и DocumentAnalysisClient экземпляра с AzureKeyCredential конечной точкой аналитики документов.

  1. Создайте файл Python с именем form_recognizer_quickstart.py в редакторе или интегрированной среде разработки.

  2. Откройте файл form_recognizer_quickstart.py и выберите один из следующих примеров кода и скопируйте и вставьте в приложение:

    • Предварительно созданная модель чтения находится в основе всех моделей аналитики документов и может обнаруживать строки, слова, расположения и языки. Макет, общие документы, предварительно созданные и пользовательские модели используют read модель в качестве основы для извлечения текстов из документов.
    • Предварительно созданная модель макета извлекает текстовые и текстовые расположения, таблицы, знаки выделения и сведения о структуре из документов и изображений.
    • Предварительно созданная модель tax.us.w2 извлекает информацию о налоговых формах внутренней налоговой службы США (IRS).
    • Предварительно созданная модель счета извлекает ключевые поля и элементы строк из счетов-фактур продаж в различных форматах.
    • Предварительно созданная модель квитанций извлекает ключевые сведения из печатных и рукописных квитанций о продажах.
    • Предварительно созданная модель idDocument извлекает ключевые сведения из лицензий водителей США; международные биографические страницы паспортов; Идентификаторы штатов США; карточки социального страхования; и постоянные карточки резидентов.
  3. Запустите код Python из командной строки.

    python form_recognizer_quickstart.py
    

Использование модели чтения

import os
from azure.ai.formrecognizer import DocumentAnalysisClient
from azure.core.credentials import AzureKeyCredential

# use your `key` and `endpoint` environment variables
key = os.environ.get('FR_KEY')
endpoint = os.environ.get('FR_ENDPOINT')

# formatting function
def format_polygon(polygon):
    if not polygon:
        return "N/A"
    return ", ".join(["[{}, {}]".format(p.x, p.y) for p in polygon])


def analyze_read():
    # sample document
    formUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/read.png"

    document_analysis_client = DocumentAnalysisClient(
        endpoint=endpoint, credential=AzureKeyCredential(key)
    )

    poller = document_analysis_client.begin_analyze_document_from_url(
        "prebuilt-read", formUrl
    )
    result = poller.result()

    print("Document contains content: ", result.content)

    for idx, style in enumerate(result.styles):
        print(
            "Document contains {} content".format(
                "handwritten" if style.is_handwritten else "no handwritten"
            )
        )

    for page in result.pages:
        print("----Analyzing Read from page #{}----".format(page.page_number))
        print(
            "Page has width: {} and height: {}, measured with unit: {}".format(
                page.width, page.height, page.unit
            )
        )

        for line_idx, line in enumerate(page.lines):
            print(
                "...Line # {} has text content '{}' within bounding box '{}'".format(
                    line_idx,
                    line.content,
                    format_polygon(line.polygon),
                )
            )

        for word in page.words:
            print(
                "...Word '{}' has a confidence of {}".format(
                    word.content, word.confidence
                )
            )

    print("----------------------------------------")


if __name__ == "__main__":
    analyze_read()

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные read данные модели.

Использование модели макета

import os
from azure.ai.formrecognizer import DocumentAnalysisClient
from azure.core.credentials import AzureKeyCredential

# use your `key` and `endpoint` environment variables
key = os.environ.get('FR_KEY')
endpoint = os.environ.get('FR_ENDPOINT')

# formatting function
def format_polygon(polygon):
    if not polygon:
        return "N/A"
    return ", ".join(["[{}, {}]".format(p.x, p.y) for p in polygon])


def analyze_layout():
    # sample document
    formUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/layout.png"

    document_analysis_client = DocumentAnalysisClient(
        endpoint=endpoint, credential=AzureKeyCredential(key)
    )

    poller = document_analysis_client.begin_analyze_document_from_url(
        "prebuilt-layout", formUrl
    )
    result = poller.result()

    for idx, style in enumerate(result.styles):
        print(
            "Document contains {} content".format(
                "handwritten" if style.is_handwritten else "no handwritten"
            )
        )

    for page in result.pages:
        print("----Analyzing layout from page #{}----".format(page.page_number))
        print(
            "Page has width: {} and height: {}, measured with unit: {}".format(
                page.width, page.height, page.unit
            )
        )

        for line_idx, line in enumerate(page.lines):
            words = line.get_words()
            print(
                "...Line # {} has word count {} and text '{}' within bounding box '{}'".format(
                    line_idx,
                    len(words),
                    line.content,
                    format_polygon(line.polygon),
                )
            )

            for word in words:
                print(
                    "......Word '{}' has a confidence of {}".format(
                        word.content, word.confidence
                    )
                )

        for selection_mark in page.selection_marks:
            print(
                "...Selection mark is '{}' within bounding box '{}' and has a confidence of {}".format(
                    selection_mark.state,
                    format_polygon(selection_mark.polygon),
                    selection_mark.confidence,
                )
            )

    for table_idx, table in enumerate(result.tables):
        print(
            "Table # {} has {} rows and {} columns".format(
                table_idx, table.row_count, table.column_count
            )
        )
        for region in table.bounding_regions:
            print(
                "Table # {} location on page: {} is {}".format(
                    table_idx,
                    region.page_number,
                    format_polygon(region.polygon),
                )
            )
        for cell in table.cells:
            print(
                "...Cell[{}][{}] has content '{}'".format(
                    cell.row_index,
                    cell.column_index,
                    cell.content,
                )
            )
            for region in cell.bounding_regions:
                print(
                    "...content on page {} is within bounding box '{}'".format(
                        region.page_number,
                        format_polygon(region.polygon),
                    )
                )

    print("----------------------------------------")


if __name__ == "__main__":
    analyze_layout()

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные данные модели макета.

Использование модели общего документа

import os
from azure.ai.formrecognizer import DocumentAnalysisClient
from azure.core.credentials import AzureKeyCredential

# use your `key` and `endpoint` environment variables
key = os.environ.get('FR_KEY')
endpoint = os.environ.get('FR_ENDPOINT')

# formatting function
def format_bounding_region(bounding_regions):
    if not bounding_regions:
        return "N/A"
    return ", ".join("Page #{}: {}".format(region.page_number, format_polygon(region.polygon)) for region in bounding_regions)

# formatting function
def format_polygon(polygon):
    if not polygon:
        return "N/A"
    return ", ".join(["[{}, {}]".format(p.x, p.y) for p in polygon])


def analyze_general_documents():
    # sample document
    docUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/sample-layout.pdf"

    # create your `DocumentAnalysisClient` instance and `AzureKeyCredential` variable
    document_analysis_client = DocumentAnalysisClient(endpoint=endpoint, credential=AzureKeyCredential(key))

    poller = document_analysis_client.begin_analyze_document_from_url(
            "prebuilt-document", docUrl)
    result = poller.result()

    for style in result.styles:
        if style.is_handwritten:
            print("Document contains handwritten content: ")
            print(",".join([result.content[span.offset:span.offset + span.length] for span in style.spans]))

    print("----Key-value pairs found in document----")
    for kv_pair in result.key_value_pairs:
        if kv_pair.key:
            print(
                    "Key '{}' found within '{}' bounding regions".format(
                        kv_pair.key.content,
                        format_bounding_region(kv_pair.key.bounding_regions),
                    )
                )
        if kv_pair.value:
            print(
                    "Value '{}' found within '{}' bounding regions\n".format(
                        kv_pair.value.content,
                        format_bounding_region(kv_pair.value.bounding_regions),
                    )
                )

    for page in result.pages:
        print("----Analyzing document from page #{}----".format(page.page_number))
        print(
            "Page has width: {} and height: {}, measured with unit: {}".format(
                page.width, page.height, page.unit
            )
        )

        for line_idx, line in enumerate(page.lines):
            print(
                "...Line # {} has text content '{}' within bounding box '{}'".format(
                    line_idx,
                    line.content,
                    format_polygon(line.polygon),
                )
            )

        for word in page.words:
            print(
                "...Word '{}' has a confidence of {}".format(
                    word.content, word.confidence
                )
            )

        for selection_mark in page.selection_marks:
            print(
                "...Selection mark is '{}' within bounding box '{}' and has a confidence of {}".format(
                    selection_mark.state,
                    format_polygon(selection_mark.polygon),
                    selection_mark.confidence,
                )
            )

    for table_idx, table in enumerate(result.tables):
        print(
            "Table # {} has {} rows and {} columns".format(
                table_idx, table.row_count, table.column_count
            )
        )
        for region in table.bounding_regions:
            print(
                "Table # {} location on page: {} is {}".format(
                    table_idx,
                    region.page_number,
                    format_polygon(region.polygon),
                )
            )
        for cell in table.cells:
            print(
                "...Cell[{}][{}] has content '{}'".format(
                    cell.row_index,
                    cell.column_index,
                    cell.content,
                )
            )
            for region in cell.bounding_regions:
                print(
                    "...content on page {} is within bounding box '{}'\n".format(
                        region.page_number,
                        format_polygon(region.polygon),
                    )
                )
    print("----------------------------------------")


if __name__ == "__main__":
    analyze_general_documents()

Посетите репозиторий примеров Azure на GitHub и просмотрите общие выходные данные модели документов.

Использование налоговой модели W-2

import os
from azure.ai.formrecognizer import DocumentAnalysisClient
from azure.core.credentials import AzureKeyCredential

# use your `key` and `endpoint` environment variables
key = os.environ.get('FR_KEY')
endpoint = os.environ.get('FR_ENDPOINT')

# formatting function
def format_address_value(address_value):
    return f"\n......House/building number: {address_value.house_number}\n......Road: {address_value.road}\n......City: {address_value.city}\n......State: {address_value.state}\n......Postal code: {address_value.postal_code}"


def analyze_tax_us_w2():
    # sample document
    formUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/w2.png"

    document_analysis_client = DocumentAnalysisClient(
        endpoint=endpoint, credential=AzureKeyCredential(key)
    )

    poller = document_analysis_client.begin_analyze_document_from_url(
        "prebuilt-tax.us.w2", formUrl
    )
    w2s = poller.result()

    for idx, w2 in enumerate(w2s.documents):
         print("--------Analyzing US Tax W-2 Form #{}--------".format(idx   1))
        form_variant = w2.fields.get("W2FormVariant")
        if form_variant:
            print(
                "Form variant: {} has confidence: {}".format(
                    form_variant.value, form_variant.confidence
                )
            )
        tax_year = w2.fields.get("TaxYear")
        if tax_year:
            print(
                "Tax year: {} has confidence: {}".format(
                    tax_year.value, tax_year.confidence
                )
            )
        w2_copy = w2.fields.get("W2Copy")
        if w2_copy:
            print(
                "W-2 Copy: {} has confidence: {}".format(
                    w2_copy.value,
                    w2_copy.confidence,
                )
            )
        employee = w2.fields.get("Employee")
        if employee:
            print("Employee data:")
            employee_name = employee.value.get("Name")
            if employee_name:
                print(
                    "...Name: {} has confidence: {}".format(
                        employee_name.value, employee_name.confidence
                    )
                )
            employee_ssn = employee.value.get("SocialSecurityNumber")
            if employee_ssn:
                print(
                    "...SSN: {} has confidence: {}".format(
                        employee_ssn.value, employee_ssn.confidence
                    )
                )
            employee_address = employee.value.get("Address")
            if employee_address:
                print(
                    "...Address: {}\n......has confidence: {}".format(
                        format_address_value(employee_address.value),
                        employee_address.confidence,
                    )
                )
            employee_zipcode = employee.value.get("ZipCode")
            if employee_zipcode:
                print(
                    "...Zipcode: {} has confidence: {}".format(
                        employee_zipcode.value, employee_zipcode.confidence
                    )
                )
        control_number = w2.fields.get("ControlNumber")
        if control_number:
            print(
                "Control Number: {} has confidence: {}".format(
                    control_number.value, control_number.confidence
                )
            )
        employer = w2.fields.get("Employer")
        if employer:
            print("Employer data:")
            employer_name = employer.value.get("Name")
            if employer_name:
                print(
                    "...Name: {} has confidence: {}".format(
                        employer_name.value, employer_name.confidence
                    )
                )
            employer_id = employer.value.get("IdNumber")
            if employer_id:
                print(
                    "...ID Number: {} has confidence: {}".format(
                        employer_id.value, employer_id.confidence
                    )
                )
            employer_address = employer.value.get("Address")
            if employer_address:
                print(
                    "...Address: {}\n......has confidence: {}".format(
                        format_address_value(employer_address.value),
                        employer_address.confidence,
                    )
                )
            employer_zipcode = employer.value.get("ZipCode")
            if employer_zipcode:
                print(
                    "...Zipcode: {} has confidence: {}".format(
                        employer_zipcode.value, employer_zipcode.confidence
                    )
                )
        wages_tips = w2.fields.get("WagesTipsAndOtherCompensation")
        if wages_tips:
            print(
                "Wages, tips, and other compensation: {} has confidence: {}".format(
                    wages_tips.value,
                    wages_tips.confidence,
                )
            )
        fed_income_tax_withheld = w2.fields.get("FederalIncomeTaxWithheld")
        if fed_income_tax_withheld:
            print(
                "Federal income tax withheld: {} has confidence: {}".format(
                    fed_income_tax_withheld.value, fed_income_tax_withheld.confidence
                )
            )
        social_security_wages = w2.fields.get("SocialSecurityWages")
        if social_security_wages:
            print(
                "Social Security wages: {} has confidence: {}".format(
                    social_security_wages.value, social_security_wages.confidence
                )
            )
        social_security_tax_withheld = w2.fields.get("SocialSecurityTaxWithheld")
        if social_security_tax_withheld:
            print(
                "Social Security tax withheld: {} has confidence: {}".format(
                    social_security_tax_withheld.value,
                    social_security_tax_withheld.confidence,
                )
            )
        medicare_wages_tips = w2.fields.get("MedicareWagesAndTips")
        if medicare_wages_tips:
            print(
                "Medicare wages and tips: {} has confidence: {}".format(
                    medicare_wages_tips.value, medicare_wages_tips.confidence
                )
            )
        medicare_tax_withheld = w2.fields.get("MedicareTaxWithheld")
        if medicare_tax_withheld:
            print(
                "Medicare tax withheld: {} has confidence: {}".format(
                    medicare_tax_withheld.value, medicare_tax_withheld.confidence
                )
            )
        social_security_tips = w2.fields.get("SocialSecurityTips")
        if social_security_tips:
            print(
                "Social Security tips: {} has confidence: {}".format(
                    social_security_tips.value, social_security_tips.confidence
                )
            )
        allocated_tips = w2.fields.get("AllocatedTips")
        if allocated_tips:
            print(
                "Allocated tips: {} has confidence: {}".format(
                    allocated_tips.value,
                    allocated_tips.confidence,
                )
            )
        verification_code = w2.fields.get("VerificationCode")
        if verification_code:
            print(
                "Verification code: {} has confidence: {}".format(
                    verification_code.value, verification_code.confidence
                )
            )
        dependent_care_benefits = w2.fields.get("DependentCareBenefits")
        if dependent_care_benefits:
            print(
                "Dependent care benefits: {} has confidence: {}".format(
                    dependent_care_benefits.value,
                    dependent_care_benefits.confidence,
                )
            )
        non_qualified_plans = w2.fields.get("NonQualifiedPlans")
        if non_qualified_plans:
            print(
                "Non-qualified plans: {} has confidence: {}".format(
                    non_qualified_plans.value,
                    non_qualified_plans.confidence,
                )
            )
        additional_info = w2.fields.get("AdditionalInfo")
        if additional_info:
            print("Additional information:")
            for item in additional_info.value:
                letter_code = item.value.get("LetterCode")
                if letter_code:
                    print(
                        "...Letter code: {} has confidence: {}".format(
                            letter_code.value, letter_code.confidence
                        )
                    )
                amount = item.value.get("Amount")
                if amount:
                    print(
                        "...Amount: {} has confidence: {}".format(
                            amount.value, amount.confidence
                        )
                    )
        is_statutory_employee = w2.fields.get("IsStatutoryEmployee")
        if is_statutory_employee:
            print(
                "Is statutory employee: {} has confidence: {}".format(
                    is_statutory_employee.value, is_statutory_employee.confidence
                )
            )
        is_retirement_plan = w2.fields.get("IsRetirementPlan")
        if is_retirement_plan:
            print(
                "Is retirement plan: {} has confidence: {}".format(
                    is_retirement_plan.value, is_retirement_plan.confidence
                )
            )
        third_party_sick_pay = w2.fields.get("IsThirdPartySickPay")
        if third_party_sick_pay:
            print(
                "Is third party sick pay: {} has confidence: {}".format(
                    third_party_sick_pay.value, third_party_sick_pay.confidence
                )
            )
        other_info = w2.fields.get("Other")
        if other_info:
            print(
                "Other information: {} has confidence: {}".format(
                    other_info.value,
                    other_info.confidence,
                )
            )
        state_tax_info = w2.fields.get("StateTaxInfos")
        if state_tax_info:
            print("State Tax info:")
            for tax in state_tax_info.value:
                state = tax.value.get("State")
                if state:
                    print(
                        "...State: {} has confidence: {}".format(
                            state.value, state.confidence
                        )
                    )
                employer_state_id_number = tax.value.get("EmployerStateIdNumber")
                if employer_state_id_number:
                    print(
                        "...Employer state ID number: {} has confidence: {}".format(
                            employer_state_id_number.value,
                            employer_state_id_number.confidence,
                        )
                    )
                state_wages_tips = tax.value.get("StateWagesTipsEtc")
                if state_wages_tips:
                    print(
                        "...State wages, tips, etc: {} has confidence: {}".format(
                            state_wages_tips.value, state_wages_tips.confidence
                        )
                    )
                state_income_tax = tax.value.get("StateIncomeTax")
                if state_income_tax:
                    print(
                        "...State income tax: {} has confidence: {}".format(
                            state_income_tax.value, state_income_tax.confidence
                        )
                    )
        local_tax_info = w2.fields.get("LocalTaxInfos")
        if local_tax_info:
            print("Local Tax info:")
            for tax in local_tax_info.value:
                local_wages_tips = tax.value.get("LocalWagesTipsEtc")
                if local_wages_tips:
                    print(
                        "...Local wages, tips, etc: {} has confidence: {}".format(
                            local_wages_tips.value, local_wages_tips.confidence
                        )
                    )
                local_income_tax = tax.value.get("LocalIncomeTax")
                if local_income_tax:
                    print(
                        "...Local income tax: {} has confidence: {}".format(
                            local_income_tax.value, local_income_tax.confidence
                        )
                    )
                locality_name = tax.value.get("LocalityName")
                if locality_name:
                    print(
                        "...Locality name: {} has confidence: {}".format(
                            locality_name.value, locality_name.confidence
                        )
                    )

                print("----------------------------------------")


if __name__ == "__main__":
    analyze_tax_us_w2()

Посетите репозиторий примеров Azure на сайте GitHub и просмотрите выходные данные налоговой модели W-2.

Использование модели счета

import os
from azure.ai.formrecognizer import DocumentAnalysisClient
from azure.core.credentials import AzureKeyCredential

# use your `key` and `endpoint` environment variables
key = os.environ.get('FR_KEY')
endpoint = os.environ.get('FR_ENDPOINT')

# formatting function
def format_bounding_region(bounding_regions):
    if not bounding_regions:
        return "N/A"
    return ", ".join("Page #{}: {}".format(region.page_number, format_polygon(region.polygon)) for region in bounding_regions)

# formatting function
def format_polygon(polygon):
    if not polygon:
        return "N/A"
    return ", ".join(["[{}, {}]".format(p.x, p.y) for p in polygon])


def analyze_invoice():

    invoiceUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/sample-invoice.pdf"

    document_analysis_client = DocumentAnalysisClient(
        endpoint=endpoint, credential=AzureKeyCredential(key)
    )

    poller = document_analysis_client.begin_analyze_document_from_url(
            "prebuilt-invoice", invoiceUrl)
    invoices = poller.result()

    for idx, invoice in enumerate(invoices.documents):
        print("--------Recognizing invoice #{}--------".format(idx + 1))
        vendor_name = invoice.fields.get("VendorName")
        if vendor_name:
            print(
                "Vendor Name: {} has confidence: {}".format(
                    vendor_name.value, vendor_name.confidence
                )
            )
        vendor_address = invoice.fields.get("VendorAddress")
        if vendor_address:
            print(
                "Vendor Address: {} has confidence: {}".format(
                    vendor_address.value, vendor_address.confidence
                )
            )
        vendor_address_recipient = invoice.fields.get("VendorAddressRecipient")
        if vendor_address_recipient:
            print(
                "Vendor Address Recipient: {} has confidence: {}".format(
                    vendor_address_recipient.value, vendor_address_recipient.confidence
                )
            )
        customer_name = invoice.fields.get("CustomerName")
        if customer_name:
            print(
                "Customer Name: {} has confidence: {}".format(
                    customer_name.value, customer_name.confidence
                )
            )
        customer_id = invoice.fields.get("CustomerId")
        if customer_id:
            print(
                "Customer Id: {} has confidence: {}".format(
                    customer_id.value, customer_id.confidence
                )
            )
        customer_address = invoice.fields.get("CustomerAddress")
        if customer_address:
            print(
                "Customer Address: {} has confidence: {}".format(
                    customer_address.value, customer_address.confidence
                )
            )
        customer_address_recipient = invoice.fields.get("CustomerAddressRecipient")
        if customer_address_recipient:
            print(
                "Customer Address Recipient: {} has confidence: {}".format(
                    customer_address_recipient.value,
                    customer_address_recipient.confidence,
                )
            )
        invoice_id = invoice.fields.get("InvoiceId")
        if invoice_id:
            print(
                "Invoice Id: {} has confidence: {}".format(
                    invoice_id.value, invoice_id.confidence
                )
            )
        invoice_date = invoice.fields.get("InvoiceDate")
        if invoice_date:
            print(
                "Invoice Date: {} has confidence: {}".format(
                    invoice_date.value, invoice_date.confidence
                )
            )
        invoice_total = invoice.fields.get("InvoiceTotal")
        if invoice_total:
            print(
                "Invoice Total: {} has confidence: {}".format(
                    invoice_total.value, invoice_total.confidence
                )
            )
        due_date = invoice.fields.get("DueDate")
        if due_date:
            print(
                "Due Date: {} has confidence: {}".format(
                    due_date.value, due_date.confidence
                )
            )
        purchase_order = invoice.fields.get("PurchaseOrder")
        if purchase_order:
            print(
                "Purchase Order: {} has confidence: {}".format(
                    purchase_order.value, purchase_order.confidence
                )
            )
        billing_address = invoice.fields.get("BillingAddress")
        if billing_address:
            print(
                "Billing Address: {} has confidence: {}".format(
                    billing_address.value, billing_address.confidence
                )
            )
        billing_address_recipient = invoice.fields.get("BillingAddressRecipient")
        if billing_address_recipient:
            print(
                "Billing Address Recipient: {} has confidence: {}".format(
                    billing_address_recipient.value,
                    billing_address_recipient.confidence,
                )
            )
        shipping_address = invoice.fields.get("ShippingAddress")
        if shipping_address:
            print(
                "Shipping Address: {} has confidence: {}".format(
                    shipping_address.value, shipping_address.confidence
                )
            )
        shipping_address_recipient = invoice.fields.get("ShippingAddressRecipient")
        if shipping_address_recipient:
            print(
                "Shipping Address Recipient: {} has confidence: {}".format(
                    shipping_address_recipient.value,
                    shipping_address_recipient.confidence,
                )
            )
        print("Invoice items:")
        for idx, item in enumerate(invoice.fields.get("Items").value):
            print("...Item #{}".format(idx + 1))
            item_description = item.value.get("Description")
            if item_description:
                print(
                    "......Description: {} has confidence: {}".format(
                        item_description.value, item_description.confidence
                    )
                )
            item_quantity = item.value.get("Quantity")
            if item_quantity:
                print(
                    "......Quantity: {} has confidence: {}".format(
                        item_quantity.value, item_quantity.confidence
                    )
                )
            unit = item.value.get("Unit")
            if unit:
                print(
                    "......Unit: {} has confidence: {}".format(
                        unit.value, unit.confidence
                    )
                )
            unit_price = item.value.get("UnitPrice")
            if unit_price:
                print(
                    "......Unit Price: {} has confidence: {}".format(
                        unit_price.value, unit_price.confidence
                    )
                )
            product_code = item.value.get("ProductCode")
            if product_code:
                print(
                    "......Product Code: {} has confidence: {}".format(
                        product_code.value, product_code.confidence
                    )
                )
            item_date = item.value.get("Date")
            if item_date:
                print(
                    "......Date: {} has confidence: {}".format(
                        item_date.value, item_date.confidence
                    )
                )
            tax = item.value.get("Tax")
            if tax:
                print(
                    "......Tax: {} has confidence: {}".format(tax.value, tax.confidence)
                )
            amount = item.value.get("Amount")
            if amount:
                print(
                    "......Amount: {} has confidence: {}".format(
                        amount.value, amount.confidence
                    )
                )
        subtotal = invoice.fields.get("SubTotal")
        if subtotal:
            print(
                "Subtotal: {} has confidence: {}".format(
                    subtotal.value, subtotal.confidence
                )
            )
        total_tax = invoice.fields.get("TotalTax")
        if total_tax:
            print(
                "Total Tax: {} has confidence: {}".format(
                    total_tax.value, total_tax.confidence
                )
            )
        previous_unpaid_balance = invoice.fields.get("PreviousUnpaidBalance")
        if previous_unpaid_balance:
            print(
                "Previous Unpaid Balance: {} has confidence: {}".format(
                    previous_unpaid_balance.value, previous_unpaid_balance.confidence
                )
            )
        amount_due = invoice.fields.get("AmountDue")
        if amount_due:
            print(
                "Amount Due: {} has confidence: {}".format(
                    amount_due.value, amount_due.confidence
                )
            )
        service_start_date = invoice.fields.get("ServiceStartDate")
        if service_start_date:
            print(
                "Service Start Date: {} has confidence: {}".format(
                    service_start_date.value, service_start_date.confidence
                )
            )
        service_end_date = invoice.fields.get("ServiceEndDate")
        if service_end_date:
            print(
                "Service End Date: {} has confidence: {}".format(
                    service_end_date.value, service_end_date.confidence
                )
            )
        service_address = invoice.fields.get("ServiceAddress")
        if service_address:
            print(
                "Service Address: {} has confidence: {}".format(
                    service_address.value, service_address.confidence
                )
            )
        service_address_recipient = invoice.fields.get("ServiceAddressRecipient")
        if service_address_recipient:
            print(
                "Service Address Recipient: {} has confidence: {}".format(
                    service_address_recipient.value,
                    service_address_recipient.confidence,
                )
            )
        remittance_address = invoice.fields.get("RemittanceAddress")
        if remittance_address:
            print(
                "Remittance Address: {} has confidence: {}".format(
                    remittance_address.value, remittance_address.confidence
                )
            )
        remittance_address_recipient = invoice.fields.get("RemittanceAddressRecipient")
        if remittance_address_recipient:
            print(
                "Remittance Address Recipient: {} has confidence: {}".format(
                    remittance_address_recipient.value,
                    remittance_address_recipient.confidence,
                )
            )

        print("----------------------------------------")

if __name__ == "__main__":
    analyze_invoice()

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные данные модели счета.

Использование модели квитанции

import os
from azure.ai.formrecognizer import DocumentAnalysisClient
from azure.core.credentials import AzureKeyCredential

# use your `key` and `endpoint` environment variables
key = os.environ.get('FR_KEY')
endpoint = os.environ.get('FR_ENDPOINT')

def analyze_receipts():
    # sample document
    receiptUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/receipt.png"

    document_analysis_client = DocumentAnalysisClient(
        endpoint=endpoint, credential=AzureKeyCredential(key)
    )
    poller = document_analysis_client.begin_analyze_document_from_url(
        "prebuilt-receipt", receiptUrl, locale="en-US"
    )
    receipts = poller.result()
    for idx, receipt in enumerate(receipts.documents):
         print("--------Analysis of receipt #{}--------".format(idx   1))
        print("Receipt type: {}".format(receipt.doc_type or "N/A"))
        merchant_name = receipt.fields.get("MerchantName")
        if merchant_name:
            print(
                "Merchant Name: {} has confidence: {}".format(
                    merchant_name.value, merchant_name.confidence
                )
            )
        transaction_date = receipt.fields.get("TransactionDate")
        if transaction_date:
            print(
                "Transaction Date: {} has confidence: {}".format(
                    transaction_date.value, transaction_date.confidence
                )
            )
        if receipt.fields.get("Items"):
            print("Receipt items:")
            for idx, item in enumerate(receipt.fields.get("Items").value):
                 print("...Item #{}".format(idx   1))
                item_description = item.value.get("Description")
                if item_description:
                    print(
                        "......Item Description: {} has confidence: {}".format(
                            item_description.value, item_description.confidence
                        )
                    )
                item_quantity = item.value.get("Quantity")
                if item_quantity:
                    print(
                        "......Item Quantity: {} has confidence: {}".format(
                            item_quantity.value, item_quantity.confidence
                        )
                    )
                item_price = item.value.get("Price")
                if item_price:
                    print(
                        "......Individual Item Price: {} has confidence: {}".format(
                            item_price.value, item_price.confidence
                        )
                    )
                item_total_price = item.value.get("TotalPrice")
                if item_total_price:
                    print(
                        "......Total Item Price: {} has confidence: {}".format(
                            item_total_price.value, item_total_price.confidence
                        )
                    )
        subtotal = receipt.fields.get("Subtotal")
        if subtotal:
            print(
                "Subtotal: {} has confidence: {}".format(
                    subtotal.value, subtotal.confidence
                )
            )
        tax = receipt.fields.get("TotalTax")
        if tax:
            print("Total tax: {} has confidence: {}".format(tax.value, tax.confidence))
        tip = receipt.fields.get("Tip")
        if tip:
            print("Tip: {} has confidence: {}".format(tip.value, tip.confidence))
        total = receipt.fields.get("Total")
        if total:
            print("Total: {} has confidence: {}".format(total.value, total.confidence))
        print("--------------------------------------")


if __name__ == "__main__":
    analyze_receipts()

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные данные модели квитанций.

Использование модели удостоверения

import os
from azure.ai.formrecognizer import DocumentAnalysisClient
from azure.core.credentials import AzureKeyCredential

# use your `key` and `endpoint` environment variables
key = os.environ.get('FR_KEY')
endpoint = os.environ.get('FR_ENDPOINT')

def analyze_identity_documents():
# sample document
    identityUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/identity_documents.png"

    document_analysis_client = DocumentAnalysisClient(
        endpoint=endpoint, credential=AzureKeyCredential(key)
    )

    poller = document_analysis_client.begin_analyze_document_from_url(
            "prebuilt-idDocument", identityUrl
        )
    id_documents = poller.result()

    for idx, id_document in enumerate(id_documents.documents):
        print("--------Analyzing ID document #{}--------".format(idx + 1))
        first_name = id_document.fields.get("FirstName")
        if first_name:
            print(
                "First Name: {} has confidence: {}".format(
                    first_name.value, first_name.confidence
                )
            )
        last_name = id_document.fields.get("LastName")
        if last_name:
            print(
                "Last Name: {} has confidence: {}".format(
                    last_name.value, last_name.confidence
                )
            )
        document_number = id_document.fields.get("DocumentNumber")
        if document_number:
            print(
                "Document Number: {} has confidence: {}".format(
                    document_number.value, document_number.confidence
                )
            )
        dob = id_document.fields.get("DateOfBirth")
        if dob:
            print(
                "Date of Birth: {} has confidence: {}".format(dob.value, dob.confidence)
            )
        doe = id_document.fields.get("DateOfExpiration")
        if doe:
            print(
                "Date of Expiration: {} has confidence: {}".format(
                    doe.value, doe.confidence
                )
            )
        sex = id_document.fields.get("Sex")
        if sex:
            print("Sex: {} has confidence: {}".format(sex.value, sex.confidence))
        address = id_document.fields.get("Address")
        if address:
            print(
                "Address: {} has confidence: {}".format(
                    address.value, address.confidence
                )
            )
        country_region = id_document.fields.get("CountryRegion")
        if country_region:
            print(
                "Country/Region: {} has confidence: {}".format(
                    country_region.value, country_region.confidence
                )
            )
        region = id_document.fields.get("Region")
        if region:
            print(
                "Region: {} has confidence: {}".format(region.value, region.confidence)
            )

        print("--------------------------------------")

if __name__ == "__main__":
    analyze_identity_documents()

Посетите репозиторий примеров Azure на сайте GitHub и просмотрите выходные данные модели документов идентификатора.

Использование модели визитной карточки

import os
from azure.ai.formrecognizer import DocumentAnalysisClient
from azure.core.credentials import AzureKeyCredential

# use your `key` and `endpoint` environment variables
key = os.environ.get('FR_KEY')
endpoint = os.environ.get('FR_ENDPOINT')

def analyze_business_card():
      # sample document
    businessCardUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/de5e0d8982ab754823c54de47a47e8e499351523/curl/form-recognizer/rest-api/business_card.jpg"

    document_analysis_client = DocumentAnalysisClient(
        endpoint=endpoint, credential=AzureKeyCredential(key)
    )

    poller = document_analysis_client.begin_analyze_document_from_url(
            "prebuilt-businessCard", businessCardUrl, locale="en-US"
        )
    business_cards = poller.result()

    for idx, business_card in enumerate(business_cards.documents):
        print("--------Analyzing business card #{}--------".format(idx + 1))
        contact_names = business_card.fields.get("ContactNames")
        if contact_names:
            for contact_name in contact_names.value:
                print(
                    "Contact First Name: {} has confidence: {}".format(
                        contact_name.value["FirstName"].value,
                        contact_name.value[
                            "FirstName"
                        ].confidence,
                    )
                )
                print(
                    "Contact Last Name: {} has confidence: {}".format(
                        contact_name.value["LastName"].value,
                        contact_name.value[
                            "LastName"
                        ].confidence,
                    )
                )
        company_names = business_card.fields.get("CompanyNames")
        if company_names:
            for company_name in company_names.value:
                print(
                    "Company Name: {} has confidence: {}".format(
                        company_name.value, company_name.confidence
                    )
                )
        departments = business_card.fields.get("Departments")
        if departments:
            for department in departments.value:
                print(
                    "Department: {} has confidence: {}".format(
                        department.value, department.confidence
                    )
                )
        job_titles = business_card.fields.get("JobTitles")
        if job_titles:
            for job_title in job_titles.value:
                print(
                    "Job Title: {} has confidence: {}".format(
                        job_title.value, job_title.confidence
                    )
                )
        emails = business_card.fields.get("Emails")
        if emails:
            for email in emails.value:
                print(
                    "Email: {} has confidence: {}".format(email.value, email.confidence)
                )
        websites = business_card.fields.get("Websites")
        if websites:
            for website in websites.value:
                print(
                    "Website: {} has confidence: {}".format(
                        website.value, website.confidence
                    )
                )
        addresses = business_card.fields.get("Addresses")
        if addresses:
            for address in addresses.value:
                print(
                    "Address: {} has confidence: {}".format(
                        address.value, address.confidence
                    )
                )
        mobile_phones = business_card.fields.get("MobilePhones")
        if mobile_phones:
            for phone in mobile_phones.value:
                print(
                    "Mobile phone number: {} has confidence: {}".format(
                        phone.content, phone.confidence
                    )
                )
        faxes = business_card.fields.get("Faxes")
        if faxes:
            for fax in faxes.value:
                print(
                    "Fax number: {} has confidence: {}".format(
                        fax.content, fax.confidence
                    )
                )
        work_phones = business_card.fields.get("WorkPhones")
        if work_phones:
            for work_phone in work_phones.value:
                print(
                    "Work phone number: {} has confidence: {}".format(
                        work_phone.content, work_phone.confidence
                    )
                )
        other_phones = business_card.fields.get("OtherPhones")
        if other_phones:
            for other_phone in other_phones.value:
                print(
                    "Other phone number: {} has confidence: {}".format(
                        other_phone.value, other_phone.confidence
                    )
                )

        print("--------------------------------------")

if __name__ == "__main__":
    analyze_business_card()

Посетите репозиторий примеров Azure на GitHub и просмотрите выходные данные модели визитных карточек.

Примечание.

Этот проект использует средство командной строки cURL для выполнения вызовов REST API.

| REST API | аналитики документов, поддерживаемые azure SDK

Необходимые компоненты

  • Подписка Azure — создайте бесплатную учетную запись.

  • Установленное средство командной строки cURL. Windows 10 и Windows 11 поставляются с копией cURL. В командной строке введите следующую команду cURL. Если отображаются параметры справки, cURL устанавливается в среде Windows.

    curl -help
    

    Если cURL не установлен, его можно получить здесь:

  • Служба ИИ Azure или ресурс аналитики документов. Создание одной службы или нескольких служб. Используйте бесплатную ценовую категорию (F0), чтобы опробовать службу, а затем выполните обновление до платного уровня для рабочей среды.

  • Ключ и конечная точка из ресурса, создаваемого для подключения приложения к службе аналитики документов Azure.

    1. После развертывания ресурса выберите Перейти к ресурсу.
    2. В меню навигации слева выберите "Ключи" и "Конечная точка".
    3. Скопируйте один из ключей и конечной точки для использования далее в этой статье.

    Снимок экрана: расположение ключей и конечной точки на портале Azure.

Настройка переменных среды

Чтобы взаимодействовать со службой аналитики DocumentAnalysisClient документов, необходимо создать экземпляр класса. Для этого создайте экземпляр клиента с портал Azure key endpoint. Для этого проекта используйте переменные среды для хранения и доступа к учетным данным.

Внимание

Если вы используете ключ API, сохраните его в другом месте, например в Azure Key Vault. Не включайте ключ API непосредственно в код и никогда не публикуйте его.

Дополнительные сведения о безопасности служб ИИ см. в статье "Проверка подлинности запросов к службам ИИ Azure".

Чтобы задать переменную среды для ключа ресурса Аналитики документов, откройте окно консоли и следуйте инструкциям в вашей операционной системе и среде разработки. Замените <yourKey> и <yourEndpoint> значениями из ресурса в портал Azure.

Переменные среды в Windows не учитывает регистр. Они обычно объявляются в верхнем регистре, с словами, присоединенными подчеркиванием. В командной строке выполните следующие команды:

  1. Задайте ключевую переменную:

    setx DI_KEY <yourKey>
    
  2. Настройка переменной конечной точки

    setx DI_ENDPOINT <yourEndpoint>
    
  3. Закройте окно командной строки после задания переменных среды. Значения остаются до тех пор, пока не измените их еще раз.

  4. Перезапустите все запущенные программы, которые считывают переменную среды. Например, если вы используете Visual Studio или Visual Studio Code в качестве редактора, перезапустите перед запуском примера кода.

Ниже приведены несколько дополнительных полезных команд для использования с переменными среды:

Команда Действие Пример
setx VARIABLE_NAME= Удалите переменную среды, задав значение пустой строке. setx DI_KEY=
setx VARIABLE_NAME=value Задайте или измените значение переменной среды. setx DI_KEY=<yourKey>
set VARIABLE_NAME Отображение значения определенной переменной среды. set DI_KEY
set Отображение всех переменных среды. set

Анализ документов и получение результатов

Запрос POST используется для анализа документов с помощью предварительно созданной или пользовательской модели. Запрос GET используется для получения результата вызова анализа документов. Объект modelId используется для операций POST, а объект resultId — для операции GET.

Используйте следующую таблицу для справки. Замените <modelId> и <document-url> нужными значениями:

Модель modelId описание document-url
Модель чтения prebuilt-read Пример брошюры https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/read.png
Модель макета prebuilt-layout Пример подтверждения резервирования https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/layout.png
Модель с формой W-2 prebuilt-tax.us.w2 Пример формы W-2 https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/w2.png
Модель накладных prebuilt-invoice Пример счета https://github.com/Azure-Samples/cognitive-services-REST-api-samples/raw/master/curl/form-recognizer/rest-api/invoice.pdf
Модель получения prebuilt-receipt Пример квитанции https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/receipt.png
Модель документа идентификатора prebuilt-idDocument Пример удостоверения https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/identity_documents.png

Запрос POST

Откройте окно консоли и выполните следующую команду cURL. Команды включают переменные конечной точки и ключевой среды, созданные ранее в разделе переменных среды набора. Замените эти переменные, если имена переменных отличаются. Не забудьте заменить параметры modelId> и <document-url>.<

curl -i -X POST "%DI_ENDPOINT%/documentintelligence/documentModels/{modelId}:analyze?api-version=2024-02-29-preview" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: %DI_KEY%" --data-ascii "{'urlSource': '<document-url>'}"

Чтобы включить возможности надстройки, используйте features параметр запроса в запросе POST. Существует четыре возможности надстройки, доступные в 2023-07-31 выпусках (GA) и более поздних выпусках: ocr.highResolution, ocr.formula, ocr.font и queryFields.premium. Дополнительные сведения о каждой из возможностей см. в разделе "Пользовательские модели".

Вы можете вызывать только возможности highResolution, формулы и шрифта для модели чтения и макета, а также возможность queryFields для модели "Общие документы". В следующем примере показано, как вызвать возможности highResolution, формулы и шрифта для модели макета.

curl -i -X POST "%DI_ENDPOINT%documentintelligence/documentModels/prebuilt-layout:analyze?features=ocr.highResolution,ocr.formula,ocr.font?api-version=2024-02-29-preview" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: %DI_KEY%" --data-ascii "{'urlSource': '<document-url>'}"

Ответ POST

Вы получите 202 (Success) ответ, содержащий Operation-location заголовок. Используйте значение этого заголовка для получения результатов ответа.

Снимок экрана: ответ POST с выделенным расположением операции.

Получение результата анализа (запрос GET)

После вызова Analyze document API вызовите API [Get analyze result}(/rest/api/aiservices/document-models/get-analyze-result?view=rest-aiservices-2024-02-29-preview=true&tabs=HTTP) API, чтобы получить состояние операции и извлеченных данных.

Средство командной строки cURL не форматирует ответы API, содержащие содержимое JSON, что может затруднить чтение содержимого. Чтобы отформатировать ответ JSON, добавьте символ канала, за которым следует средство форматирования JSON с запросом GET.

Используйте средство json NodeJS в качестве средства форматирования JSON для cURL. Если у вас нет установленных Node.js , скачайте и установите последнюю версию.

  1. Откройте окно консоли и установите средство JSON с помощью следующей команды:

    npm install -g jsontool
    
  2. Довольно распечатайте выходные данные JSON, включив символ | json канала с запросами GET.

    curl -i -X GET "<endpoint>documentintelligence/documentModels/prebuilt-read/analyzeResults/0e49604a-2d8e-4b15-b6b8-bb456e5d3e0a?api-version=2024-02-29-preview"-H "Ocp-Apim-Subscription-Key: <subscription key>" | json
    

Запрос GET

Перед выполнением следующей команды внесите следующие изменения:

  • Замените ответ POST заголовком Operation-location из ответа> POST.<
  • Замените <DI_KEY переменной для переменной среды, если она отличается от имени в коде.
  • Замените *<json-tool> средством форматирования JSON.
curl -i -X GET "<POST response>" -H "Ocp-Apim-Subscription-Key: %DI_KEY%" | `<json-tool>`

Изучите ответ.

Вы получаете ответ с выходными данными 200 (Success) JSON. В первом поле, status, указывается состояние операции. Если операция не завершена, значение status равно running или notStarted. Снова вызовите API вручную или с помощью скрипта. Мы рекомендуем установить между вызовами интервал в одну секунду или более.

Посетите репозиторий примеров Azure на GitHub, чтобы просмотреть GET ответ для каждой из моделей аналитики документов:

Модель URL-адрес вывода
Модель чтения Чтение выходных данных модели
Модель макета Выходные данные модели макета
Модель налогообложения W-2 Выходные данные налоговой модели W-2
Модель накладных Выходные данные модели счета
Модель получения Выходные данные модели квитанций
Модель документа идентификатора Выходные данные модели документов идентификатора

Примечание.

Этот проект использует средство командной cURL строки для выполнения вызовов REST API.

Необходимые компоненты

  • Подписка Azure — создайте бесплатную учетную запись.

  • Установленное средство командной строки cURL. Windows 10 и Windows 11 поставляются с копией cURL. В командной строке введите следующую команду cURL. Если отображаются параметры справки, cURL устанавливается в среде Windows.

    curl -help
    

    Если cURL не установлен, его можно получить здесь:

  • Служба ИИ Azure или ресурс аналитики документов. Создание одной службы или нескольких служб. Используйте бесплатную ценовую категорию (F0), чтобы опробовать службу, а затем выполните обновление до платного уровня для рабочей среды.

  • Ключ и конечная точка из ресурса, создаваемого для подключения приложения к службе аналитики документов Azure.

    1. После развертывания ресурса выберите Перейти к ресурсу.
    2. В меню навигации слева выберите "Ключи" и "Конечная точка".
    3. Скопируйте один из ключей и конечной точки для использования далее в этой статье.

    Снимок экрана: расположение ключей и конечной точки на портале Azure.

Настройка переменных среды

Чтобы взаимодействовать со службой аналитики DocumentAnalysisClient документов, необходимо создать экземпляр класса. Для этого создайте экземпляр клиента с портал Azure key endpoint. Для этого проекта используйте переменные среды для хранения и доступа к учетным данным.

Внимание

Если вы используете ключ API, сохраните его в другом месте, например в Azure Key Vault. Не включайте ключ API непосредственно в код и никогда не публикуйте его.

Дополнительные сведения о безопасности служб ИИ см. в статье "Проверка подлинности запросов к службам ИИ Azure".

Чтобы задать переменную среды для ключа ресурса Аналитики документов, откройте окно консоли и следуйте инструкциям в вашей операционной системе и среде разработки. Замените <yourKey> и <yourEndpoint> значениями из ресурса в портал Azure.

Переменные среды в Windows не учитывает регистр. Они обычно объявляются в верхнем регистре, с словами, присоединенными подчеркиванием. В командной строке выполните следующие команды:

  1. Задайте ключевую переменную:

    setx DI_KEY <yourKey>
    
  2. Настройка переменной конечной точки

    setx DI_ENDPOINT <yourEndpoint>
    
  3. Закройте окно командной строки после задания переменных среды. Значения остаются до тех пор, пока не измените их еще раз.

  4. Перезапустите все запущенные программы, которые считывают переменную среды. Например, если вы используете Visual Studio или Visual Studio Code в качестве редактора, перезапустите перед запуском примера кода.

Ниже приведены несколько дополнительных полезных команд для использования с переменными среды:

Команда Действие Пример
setx VARIABLE_NAME= Удалите переменную среды, задав значение пустой строке. setx DI_KEY=
setx VARIABLE_NAME=value Задайте или измените значение переменной среды. setx DI_KEY=<yourKey>
set VARIABLE_NAME Отображение значения определенной переменной среды. set DI_KEY
set Отображение всех переменных среды. set

Анализ документов и получение результатов

Запрос POST используется для анализа документов с помощью предварительно созданной или пользовательской модели. Запрос GET используется для получения результата вызова анализа документов. Объект modelId используется для операций POST, а объект resultId — для операции GET.

Используйте следующую таблицу для справки. Замените <modelId> и <document-url> нужными значениями:

Модель modelId описание document-url
Модель чтения prebuilt-read Пример брошюры https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/read.png
Модель макета prebuilt-layout Пример подтверждения резервирования https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/layout.png
Модель с формой W-2 prebuilt-tax.us.w2 Пример формы W-2 https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/w2.png
Модель накладных prebuilt-invoice Пример счета https://github.com/Azure-Samples/cognitive-services-REST-api-samples/raw/master/curl/form-recognizer/rest-api/invoice.pdf
Модель получения prebuilt-receipt Пример квитанции https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/receipt.png
Модель документа идентификатора prebuilt-idDocument Пример удостоверения https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/identity_documents.png

Запрос POST

Откройте окно консоли и выполните следующую команду cURL. Команды включают переменные конечной точки и ключевой среды, созданные ранее в разделе переменных среды набора. Замените эти переменные, если имена переменных отличаются. Не забудьте заменить параметры modelId> и <document-url>.<

curl -i -X POST "%FR_ENDPOINT%formrecognizer/documentModels/<modelId>:analyze?api-version=2023-07-31" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: %FR_KEY%" --data-ascii "{'urlSource': '<document-url>'}"

Чтобы включить возможности надстройки, используйте features параметр запроса в запросе POST. Существует четыре возможности надстройки, доступные в выпуске 2023-07-31 (GA): ocr.highResolution, ocr.formula, ocr.font и queryFields.premium. Дополнительные сведения о каждой из возможностей см. в разделе "Пользовательские модели".

Вы можете вызывать только возможности highResolution, формулы и шрифта для модели чтения и макета, а также возможность queryFields для модели "Общие документы". В следующем примере показано, как вызвать возможности highResolution, формулы и шрифта для модели макета.

curl -i -X POST "%FR_ENDPOINT%formrecognizer/documentModels/prebuilt-layout:analyze?features=ocr.highResolution,ocr.formula,ocr.font?api-version=2023-07-31" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: %FR_KEY%" --data-ascii "{'urlSource': '<document-url>'}"

Ответ POST

Вы получите 202 (Success) ответ, содержащий Operation-location заголовок. Используйте значение этого заголовка для получения результатов ответа.

Снимок экрана: ответ POST с выделенным расположением операции.

Получение результата анализа (запрос GET)

После вызова Analyze document API вызовите API [Get analyze result}(/rest/api/aiservices/document-models/get-analyze-result?view=rest-aiservices-2023-07-31&preserve-view=true&tabs=HTTP), чтобы получить состояние операции и извлеченных данных.

Средство командной строки cURL не форматирует ответы API, содержащие содержимое JSON, что может затруднить чтение содержимого. Чтобы отформатировать ответ JSON, добавьте символ канала, за которым следует средство форматирования JSON с запросом GET.

Используйте средство json NodeJS в качестве средства форматирования JSON для cURL. Если у вас нет установленных Node.js , скачайте и установите последнюю версию.

  1. Откройте окно консоли и установите средство JSON с помощью следующей команды:

    npm install -g jsontool
    
  2. Довольно распечатайте выходные данные JSON, включив символ | json канала с запросами GET.

    curl -i -X GET "<endpoint>formrecognizer/documentModels/prebuilt-read/analyzeResults/0e49604a-2d8e-4b15-b6b8-bb456e5d3e0a?api-version=2023-07-31"-H "Ocp-Apim-Subscription-Key: <subscription key>" | json
    

Запрос GET

Перед выполнением следующей команды внесите следующие изменения:

  • Замените ответ POST заголовком Operation-location из ответа> POST.<
  • Замените <FR_KEY переменной среды, если она отличается от имени в коде.
  • Замените *<json-tool> средством форматирования JSON.
curl -i -X GET "<POST response>" -H "Ocp-Apim-Subscription-Key: %FR_KEY%" | `<json-tool>`

Изучите ответ.

Вы получаете ответ с выходными данными 200 (Success) JSON. В первом поле, status, указывается состояние операции. Если операция не завершена, значение status равно running или notStarted. Снова вызовите API вручную или с помощью скрипта. Мы рекомендуем установить между вызовами интервал в одну секунду или более.

Посетите репозиторий примеров Azure на GitHub, чтобы просмотреть GET ответ для каждой из моделей аналитики документов:

Модель URL-адрес вывода
Модель чтения Чтение выходных данных модели
Модель макета Выходные данные модели макета
Модель налогообложения W-2 Выходные данные налоговой модели W-2
Модель накладных Выходные данные модели счета
Модель получения Выходные данные модели квитанций
Модель документа идентификатора Выходные данные модели документов идентификатора

Следующие шаги

Поздравляем! Вы узнали, как использовать модели аналитики документов для анализа различных документов разными способами. Затем ознакомьтесь с документацией по Document Intelligence Studio и справочной документации.

В этом руководстве описано, как добавить аналитику документов в приложения и рабочие процессы. Используйте выбранный язык программирования или REST API. Azure AI Document Intelligence — это облачная служба ИИ Azure, которая использует машинное обучение для извлечения пар "ключ-значение", текста и таблиц из документов. Мы рекомендуем использовать бесплатную службу при изучении технологии. Имейте в виду, что количество бесплатных страниц ограничено до 500 страниц в месяц.

Для извлечения структурированных данных из форм и документов используются следующие API:

Внимание

Этот проект предназначен для REST API аналитики документов версии 2.1.

В коде этой статьи используются синхронные методы и незащищенное хранилище учетных данных.

Справочная документация | Исходный код библиотеки | Пакет (NuGet) | Примеры

Необходимые компоненты

  • Подписка Azure — создайте бесплатную учетную запись.

  • IDE Visual Studio или текущая версия .NET Core.

  • Набор данных для обучения в хранилище BLOB-объектов Azure. Ознакомьтесь со сборкой и обучением пользовательской модели , чтобы ознакомиться с советами и параметрами объединения набора данных для обучения. Для этого проекта можно использовать файлы в папке Train примера набора данных. Скачайте и разархивируйте файл sample_data.zip.

  • Ресурс аналитики. Используйте бесплатную ценовую категорию (F0), чтобы опробовать службу, а затем выполните обновление до платного уровня для рабочей среды.

  • Ключ и конечная точка из ресурса, создаваемого для подключения приложения к службе аналитики документов Azure.

    1. После развертывания ресурса выберите Перейти к ресурсу.
    2. В меню навигации слева выберите "Ключи" и "Конечная точка".
    3. Скопируйте один из ключей и конечной точки для использования далее в этой статье.

    Снимок экрана: расположение ключей и конечной точки на портале Azure.

Настройка среды программирования

В окне консоли выполните команду dotnet new, чтобы создать консольное приложение с именем formrecognizer-project. Эта команда создает простой проект "Hello World" на языке C# с одним файлом исходного кода: program.cs.

dotnet new console -n formrecognizer-project

Измените каталог на созданную папку приложения. Вы можете создать приложение с помощью следующей команды:

dotnet build

Выходные данные сборки не должны содержать предупреждений или ошибок.

...
Build succeeded.
 0 Warning(s)
 0 Error(s)
...

Установка клиентской библиотеки

В каталоге приложения установите клиентская библиотека Аналитики документов для .NET с помощью следующей команды:

dotnet add package Azure.AI.FormRecognizer --version 3.1.1

В каталоге проекта откройте файл Program.cs в редакторе или интегрированной среде разработки. Затем добавьте следующие using директивы:

using Azure;
using Azure.AI.FormRecognizer;  
using Azure.AI.FormRecognizer.Models;
using Azure.AI.FormRecognizer.Training;

using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;

В классе приложения Program создайте переменные для ключа и конечной точки вашего ресурса.

Внимание

Перейдите на портал Azure. Если ресурс аналитики документов, созданный в разделе предварительных требований, развернут успешно, нажмите кнопку "Перейти к ресурсу " в разделе "Дальнейшие действия". В меню навигации слева в разделе "Управление ресурсами" выберите "Ключи" и "Конечная точка".

Не забудьте удалить ключ из кода после завершения. Никогда не публикуйте его публично. В рабочей среде используйте безопасные методы для хранения учетных данных и доступа к ним. Дополнительные сведения см. в статье "Безопасность служб искусственного интеллекта Azure".

private static readonly string endpoint = "PASTE_YOUR_FORM_RECOGNIZER_ENDPOINT_HERE";
private static readonly string apiKey = "PASTE_YOUR_FORM_RECOGNIZER_SUBSCRIPTION_KEY_HERE";
private static readonly AzureKeyCredential credential = new AzureKeyCredential(apiKey);

В методе приложения Main добавьте вызов асинхронных задач, используемых в этом проекте:

static void Main(string[] args) {
  // new code:
  var recognizeContent = RecognizeContent(recognizerClient);
  Task.WaitAll(recognizeContent);

  var analyzeReceipt = AnalyzeReceipt(recognizerClient, receiptUrl);
  Task.WaitAll(analyzeReceipt);

  var analyzeBusinessCard = AnalyzeBusinessCard(recognizerClient, bcUrl);
  Task.WaitAll(analyzeBusinessCard);

  var analyzeInvoice = AnalyzeInvoice(recognizerClient, invoiceUrl);
  Task.WaitAll(analyzeInvoice);

  var analyzeId = AnalyzeId(recognizerClient, idUrl);
  Task.WaitAll(analyzeId);

  var trainModel = TrainModel(trainingClient, trainingDataUrl);
  Task.WaitAll(trainModel);

  var trainModelWithLabels = TrainModelWithLabels(trainingClient, trainingDataUrl);
  Task.WaitAll(trainModel);

  var analyzeForm = AnalyzePdfForm(recognizerClient, modelId, formUrl);
  Task.WaitAll(analyzeForm);

  var manageModels = ManageModels(trainingClient, trainingDataUrl);
  Task.WaitAll(manageModels);

}

Использование объектной модели

С помощью аналитики документов можно создать два разных типа клиента. Во-первых, FormRecognizerClientслужба запрашивает службу для распознавания полей формы и содержимого. Во-вторых, FormTrainingClientсоздает пользовательские модели и управляет ими для улучшения распознавания.

FormRecognizerClient предоставляет следующие операции:

  • Распознать поля формы и содержимое с помощью пользовательских моделей, обученных для анализа пользовательских форм. Эти значения возвращаются в коллекцию объектов RecognizedForm. См. статью "Анализ форм с помощью пользовательской модели".
  • Распознать содержимое формы, включая таблицы, строки и слова, без необходимости обучения модели. Содержимое форм возвращается в коллекцию объектов FormPage. См. раздел " Анализ макета".
  • Распознать распространенные поля из квитанций США, визитных карточек, счетов и документов идентификаторов с помощью предварительно обученной модели в службе аналитики документов.

FormTrainingClient предоставляет операции для:

  • Обучение пользовательских моделей для анализа всех полей и значений, найденных в пользовательских формах. Возвращается значение CustomFormModel , указывающее типы форм, которые анализирует модель и поля, извлеченные для каждого типа формы.
  • Обучение пользовательских моделей для анализа определенных полей и значений, заданных путем маркировки пользовательских форм. Возвращается значение CustomFormModel , указывающее поля, извлекаемые моделью и предполагаемую точность для каждого поля.
  • Управление моделями, созданными в вашей учетной записи.
  • Скопируйте пользовательскую модель из одного ресурса аналитики документов в другой.

Примеры см. в разделе "Обучение моделей и управление пользовательскими моделями".

Примечание.

Модели также можно обучены с помощью графического пользовательского интерфейса, например средства маркировки образца.

аутентификация клиента;

В разделе Mainсоздайте метод с именем AuthenticateClient. Используйте этот метод в других задачах для проверки подлинности запросов к службе аналитики документов. Этот метод использует объект AzureKeyCredential, чтобы при необходимости ключ можно было обновить без создания клиентских объектов.

private static FormRecognizerClient AuthenticateClient()
{
    var credential = new AzureKeyCredential(apiKey);
    var client = new FormRecognizerClient(new Uri(endpoint), credential);
    return client;
}

Повторите шаги для нового метода, который проходит проверку подлинности клиента обучения.

static private FormTrainingClient AuthenticateTrainingClient()
{
    var credential = new AzureKeyCredential(apiKey);
    var client = new FormTrainingClient(new Uri(endpoint), credential);
    return client;
}

Получение ресурсов для тестирования

Кроме того, необходимо добавить ссылки на URL-адреса для обучающих и тестовых данных. Добавьте эти ссылки в корневой каталог класса Program .

  1. Чтобы получить URL-адрес SAS для данных обучения пользовательской модели, перейдите к ресурсу хранилища в портал Azure и выберите контейнеры хранилища>данных.

  2. Перейдите к контейнеру, щелкните правой кнопкой мыши и выберите "Создать SAS".

    Получите SAS для контейнера, а не для самой учетной записи хранения.

  3. Убедитесь, что выбраны разрешения на чтение, запись, удаление и список, а затем выберите "Создать маркер SAS" и URL-адрес.

  4. Скопируйте значение в разделе URL-адреса во временное расположение. Оно должно быть в таком формате: https://<storage account>.blob.core.windows.net/<container name>?<SAS value>.

Повторите предыдущие действия, чтобы получить URL-адрес SAS отдельного документа в контейнере хранилища BLOB-объектов. Сохраните этот URL-адрес SAS во временном расположении, а также.

Сохраните URL-адрес включенного примера изображения. Этот образ также доступен на сайте GitHub).

string trainingDataUrl = "PASTE_YOUR_SAS_URL_OF_YOUR_FORM_FOLDER_IN_BLOB_STORAGE_HERE";
string formUrl = "PASTE_YOUR_FORM_RECOGNIZER_FORM_URL_HERE";
string receiptUrl = "https://docs.microsoft.com/azure/cognitive-services/form-recognizer/media" + "/contoso-allinone.jpg";
string bcUrl = "https://raw.githubusercontent.com/Azure/azure-sdk-for-python/master/sdk/formrecognizer/azure-ai-formrecognizer/samples/sample_forms/business_cards/business-card-english.jpg";
string invoiceUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/simple-invoice.png";

string idUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/id-license.jpg";

Анализ макета

Аналитика документов позволяет анализировать таблицы, строки и слова в документах без необходимости обучения модели. Возвращаемое значение — это коллекция объектов FormPage . Существует один объект для каждой страницы в отправленном документе. Дополнительные сведения об извлечении макета см . в модели макета аналитики документов.

Для анализа содержимого файла по указанному URL-адресу используйте метод StartRecognizeContentFromUri.

private static async Task RecognizeContent(FormRecognizerClient recognizerClient)
{
    var invoiceUri = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/simple-invoice.png";
    FormPageCollection formPages = await recognizerClient
        .StartRecognizeContentFromUri(new Uri(invoiceUri))
        .WaitForCompletionAsync();

Совет

Вы можете также получить содержимое из локального файла. Изучите информацию о методах класса FormRecognizerClient, например о StartRecognizeContent. Кроме того, ознакомьтесь с примером кода на GitHub для сценариев, в которых используются локальные образы.

Оставшаяся часть этой задачи выводит на консоль сведения о содержимом.

    foreach (FormPage page in formPages)
    {
        Console.WriteLine($"Form Page {page.PageNumber} has {page.Lines.Count} lines.");

        for (int i = 0; i < page.Lines.Count; i++)
        {
            FormLine line = page.Lines[i];
            Console.WriteLine($"    Line {i} has {line.Words.Count} word{(line.Words.Count > 1 ? "s" : "")}, and text: '{line.Text}'.");
        }

        for (int i = 0; i < page.Tables.Count; i++)
        {
            FormTable table = page.Tables[i];
            Console.WriteLine($"Table {i} has {table.RowCount} rows and {table.ColumnCount} columns.");
            foreach (FormTableCell cell in table.Cells)
            {
                Console.WriteLine($"    Cell ({cell.RowIndex}, {cell.ColumnIndex}) contains text: '{cell.Text}'.");
            }
        }
    }
}

Результат выглядит следующим образом.

Form Page 1 has 18 lines.
    Line 0 has 1 word, and text: 'Contoso'.
    Line 1 has 1 word, and text: 'Address:'.
    Line 2 has 3 words, and text: 'Invoice For: Microsoft'.
    Line 3 has 4 words, and text: '1 Redmond way Suite'.
    Line 4 has 3 words, and text: '1020 Enterprise Way'.
    Line 5 has 3 words, and text: '6000 Redmond, WA'.
    Line 6 has 3 words, and text: 'Sunnayvale, CA 87659'.
    Line 7 has 1 word, and text: '99243'.
    Line 8 has 2 words, and text: 'Invoice Number'.
    Line 9 has 2 words, and text: 'Invoice Date'.
    Line 10 has 3 words, and text: 'Invoice Due Date'.
    Line 11 has 1 word, and text: 'Charges'.
    Line 12 has 2 words, and text: 'VAT ID'.
    Line 13 has 1 word, and text: '34278587'.
    Line 14 has 1 word, and text: '6/18/2017'.
    Line 15 has 1 word, and text: '6/24/2017'.
    Line 16 has 1 word, and text: '$56,651.49'.
    Line 17 has 1 word, and text: 'PT'.
Table 0 has 2 rows and 6 columns.
    Cell (0, 0) contains text: 'Invoice Number'.
    Cell (0, 1) contains text: 'Invoice Date'.
    Cell (0, 2) contains text: 'Invoice Due Date'.
    Cell (0, 3) contains text: 'Charges'.
    Cell (0, 5) contains text: 'VAT ID'.
    Cell (1, 0) contains text: '34278587'.
    Cell (1, 1) contains text: '6/18/2017'.
    Cell (1, 2) contains text: '6/24/2017'.
    Cell (1, 3) contains text: '$56,651.49'.
    Cell (1, 5) contains text: 'PT'.

анализ квитанций;

В этом разделе показано, как анализировать и извлекать общие поля из квитанций США с помощью предварительно обученной модели получения. Дополнительные сведения об анализе квитанций см. в модели квитанций аналитики документов.

Для анализа квитанций по URL-адресу используйте метод StartRecognizeReceiptsFromUri.

private static async Task AnalyzeReceipt(
    FormRecognizerClient recognizerClient, string receiptUri)
{
    RecognizedFormCollection receipts = await recognizerClient.StartRecognizeReceiptsFromUri(new Uri(receiptUrl)).WaitForCompletionAsync();

Совет

Можно также проанализировать локальные изображения квитанций. Изучите информацию о методах класса FormRecognizerClient, например о StartRecognizeReceipts. Кроме того, ознакомьтесь с примером кода на GitHub для сценариев, в которых используются локальные образы.

Возвращаемое значение — это коллекция RecognizedForm объектов. Существует один объект для каждой страницы в отправленном документе. В следующем блоке кода обрабатывается квитанция с указанным универсальным кодом ресурса (URI) и все ее основные поля с соответствующими значениями выводятся в консоль.

    foreach (RecognizedForm receipt in receipts)
    {
        FormField merchantNameField;
        if (receipt.Fields.TryGetValue("MerchantName", out merchantNameField))
        {
            if (merchantNameField.Value.ValueType == FieldValueType.String)
            {
                string merchantName = merchantNameField.Value.AsString();

                Console.WriteLine($"Merchant Name: '{merchantName}', with confidence {merchantNameField.Confidence}");
            }
        }

        FormField transactionDateField;
        if (receipt.Fields.TryGetValue("TransactionDate", out transactionDateField))
        {
            if (transactionDateField.Value.ValueType == FieldValueType.Date)
            {
                DateTime transactionDate = transactionDateField.Value.AsDate();

                Console.WriteLine($"Transaction Date: '{transactionDate}', with confidence {transactionDateField.Confidence}");
            }
        }

        FormField itemsField;
        if (receipt.Fields.TryGetValue("Items", out itemsField))
        {
            if (itemsField.Value.ValueType == FieldValueType.List)
            {
                foreach (FormField itemField in itemsField.Value.AsList())
                {
                    Console.WriteLine("Item:");

                    if (itemField.Value.ValueType == FieldValueType.Dictionary)
                    {
                        IReadOnlyDictionary<string, FormField> itemFields = itemField.Value.AsDictionary();

                        FormField itemNameField;
                        if (itemFields.TryGetValue("Name", out itemNameField))
                        {
                            if (itemNameField.Value.ValueType == FieldValueType.String)
                            {
                                string itemName = itemNameField.Value.AsString();

                                Console.WriteLine($"    Name: '{itemName}', with confidence {itemNameField.Confidence}");
                            }
                        }

                        FormField itemTotalPriceField;
                        if (itemFields.TryGetValue("TotalPrice", out itemTotalPriceField))
                        {
                            if (itemTotalPriceField.Value.ValueType == FieldValueType.Float)
                            {
                                float itemTotalPrice = itemTotalPriceField.Value.AsFloat();

                                Console.WriteLine($"    Total Price: '{itemTotalPrice}', with confidence {itemTotalPriceField.Confidence}");
                            }
                        }
                    }
                }
            }
        }
        FormField totalField;
        if (receipt.Fields.TryGetValue("Total", out totalField))
        {
            if (totalField.Value.ValueType == FieldValueType.Float)
            {
                float total = totalField.Value.AsFloat();

                Console.WriteLine($"Total: '{total}', with confidence '{totalField.Confidence}'");
            }
        }
    }
}

Результат выглядит следующим образом.

Form Page 1 has 18 lines.
    Line 0 has 1 word, and text: 'Contoso'.
    Line 1 has 1 word, and text: 'Address:'.
    Line 2 has 3 words, and text: 'Invoice For: Microsoft'.
    Line 3 has 4 words, and text: '1 Redmond way Suite'.
    Line 4 has 3 words, and text: '1020 Enterprise Way'.
    Line 5 has 3 words, and text: '6000 Redmond, WA'.
    Line 6 has 3 words, and text: 'Sunnayvale, CA 87659'.
    Line 7 has 1 word, and text: '99243'.
    Line 8 has 2 words, and text: 'Invoice Number'.
    Line 9 has 2 words, and text: 'Invoice Date'.
    Line 10 has 3 words, and text: 'Invoice Due Date'.
    Line 11 has 1 word, and text: 'Charges'.
    Line 12 has 2 words, and text: 'VAT ID'.
    Line 13 has 1 word, and text: '34278587'.
    Line 14 has 1 word, and text: '6/18/2017'.
    Line 15 has 1 word, and text: '6/24/2017'.
    Line 16 has 1 word, and text: '$56,651.49'.
    Line 17 has 1 word, and text: 'PT'.
Table 0 has 2 rows and 6 columns.
    Cell (0, 0) contains text: 'Invoice Number'.
    Cell (0, 1) contains text: 'Invoice Date'.
    Cell (0, 2) contains text: 'Invoice Due Date'.
    Cell (0, 3) contains text: 'Charges'.
    Cell (0, 5) contains text: 'VAT ID'.
    Cell (1, 0) contains text: '34278587'.
    Cell (1, 1) contains text: '6/18/2017'.
    Cell (1, 2) contains text: '6/24/2017'.
    Cell (1, 3) contains text: '$56,651.49'.
    Cell (1, 5) contains text: 'PT'.
Merchant Name: 'Contoso Contoso', with confidence 0.516
Transaction Date: '6/10/2019 12:00:00 AM', with confidence 0.985
Item:
    Name: '8GB RAM (Black)', with confidence 0.916
    Total Price: '999', with confidence 0.559
Item:
    Name: 'SurfacePen', with confidence 0.858
    Total Price: '99.99', with confidence 0.386
Total: '1203.39', with confidence '0.774'

анализ визитных карточек;

В этом разделе показано, как анализировать и извлекать общие поля из английских визитных карточек с помощью предварительно обученной модели. Дополнительные сведения об анализе визитных карточек см. в модели бизнес-карты аналитики документов.

Для анализа визитных карточек по URL-адресу используйте метод StartRecognizeBusinessCardsFromUriAsync.

private static async Task AnalyzeBusinessCard(
FormRecognizerClient recognizerClient, string bcUrl) {
  RecognizedFormCollection businessCards = await recognizerClient.StartRecognizeBusinessCardsFromUriAsync(bcUrl).WaitForCompletionAsync();

Совет

Можно также проанализировать локальные изображения визитных карточек. Изучите информацию о методах класса FormRecognizerClient, например о StartRecognizeBusinessCards. Кроме того, ознакомьтесь с примером кода на GitHub для сценариев, в которых используются локальные образы.

В следующем блоке кода обрабатывается визитная карточка с указанным универсальным кодом ресурса (URI) и все ее основные поля с соответствующими значениями выводятся в консоль.

  foreach(RecognizedForm businessCard in businessCards) {
    FormField ContactNamesField;
    if (businessCard.Fields.TryGetValue("ContactNames", out ContactNamesField)) {
      if (ContactNamesField.Value.ValueType == FieldValueType.List) {
        foreach(FormField contactNameField in ContactNamesField.Value.AsList()) {
          Console.WriteLine($ "Contact Name: {contactNameField.ValueData.Text}");

          if (contactNameField.Value.ValueType == FieldValueType.Dictionary) {
            IReadOnlyDictionary < string,
            FormField > contactNameFields = contactNameField.Value.AsDictionary();

            FormField firstNameField;
            if (contactNameFields.TryGetValue("FirstName", out firstNameField)) {
              if (firstNameField.Value.ValueType == FieldValueType.String) {
                string firstName = firstNameField.Value.AsString();

                Console.WriteLine($ "    First Name: '{firstName}', with confidence {firstNameField.Confidence}");
              }
            }

            FormField lastNameField;
            if (contactNameFields.TryGetValue("LastName", out lastNameField)) {
              if (lastNameField.Value.ValueType == FieldValueType.String) {
                string lastName = lastNameField.Value.AsString();

                Console.WriteLine($ "    Last Name: '{lastName}', with confidence {lastNameField.Confidence}");
              }
            }
          }
        }
      }
    }

    FormField jobTitlesFields;
    if (businessCard.Fields.TryGetValue("JobTitles", out jobTitlesFields)) {
      if (jobTitlesFields.Value.ValueType == FieldValueType.List) {
        foreach(FormField jobTitleField in jobTitlesFields.Value.AsList()) {
          if (jobTitleField.Value.ValueType == FieldValueType.String) {
            string jobTitle = jobTitleField.Value.AsString();

            Console.WriteLine($ "  Job Title: '{jobTitle}', with confidence {jobTitleField.Confidence}");
          }
        }
      }
    }

    FormField departmentFields;
    if (businessCard.Fields.TryGetValue("Departments", out departmentFields)) {
      if (departmentFields.Value.ValueType == FieldValueType.List) {
        foreach(FormField departmentField in departmentFields.Value.AsList()) {
          if (departmentField.Value.ValueType == FieldValueType.String) {
            string department = departmentField.Value.AsString();

            Console.WriteLine($ "  Department: '{department}', with confidence {departmentField.Confidence}");
          }
        }
      }
    }

    FormField emailFields;
    if (businessCard.Fields.TryGetValue("Emails", out emailFields)) {
      if (emailFields.Value.ValueType == FieldValueType.List) {
        foreach(FormField emailField in emailFields.Value.AsList()) {
          if (emailField.Value.ValueType == FieldValueType.String) {
            string email = emailField.Value.AsString();

            Console.WriteLine($ "  Email: '{email}', with confidence {emailField.Confidence}");
          }
        }
      }
    }

    FormField websiteFields;
    if (businessCard.Fields.TryGetValue("Websites", out websiteFields)) {
      if (websiteFields.Value.ValueType == FieldValueType.List) {
        foreach(FormField websiteField in websiteFields.Value.AsList()) {
          if (websiteField.Value.ValueType == FieldValueType.String) {
            string website = websiteField.Value.AsString();

            Console.WriteLine($ "  Website: '{website}', with confidence {websiteField.Confidence}");
          }
        }
      }
    }

    FormField mobilePhonesFields;
    if (businessCard.Fields.TryGetValue("MobilePhones", out mobilePhonesFields)) {
      if (mobilePhonesFields.Value.ValueType == FieldValueType.List) {
        foreach(FormField mobilePhoneField in mobilePhonesFields.Value.AsList()) {
          if (mobilePhoneField.Value.ValueType == FieldValueType.PhoneNumber) {
            string mobilePhone = mobilePhoneField.Value.AsPhoneNumber();

            Console.WriteLine($ "  Mobile phone number: '{mobilePhone}', with confidence {mobilePhoneField.Confidence}");
          }
        }
      }
    }

    FormField otherPhonesFields;
    if (businessCard.Fields.TryGetValue("OtherPhones", out otherPhonesFields)) {
      if (otherPhonesFields.Value.ValueType == FieldValueType.List) {
        foreach(FormField otherPhoneField in otherPhonesFields.Value.AsList()) {
          if (otherPhoneField.Value.ValueType == FieldValueType.PhoneNumber) {
            string otherPhone = otherPhoneField.Value.AsPhoneNumber();

            Console.WriteLine($ "  Other phone number: '{otherPhone}', with confidence {otherPhoneField.Confidence}");
          }
        }
      }
    }

    FormField faxesFields;
    if (businessCard.Fields.TryGetValue("Faxes", out faxesFields)) {
      if (faxesFields.Value.ValueType == FieldValueType.List) {
        foreach(FormField faxField in faxesFields.Value.AsList()) {
          if (faxField.Value.ValueType == FieldValueType.PhoneNumber) {
            string fax = faxField.Value.AsPhoneNumber();

            Console.WriteLine($ "  Fax phone number: '{fax}', with confidence {faxField.Confidence}");
          }
        }
      }
    }

    FormField addressesFields;
    if (businessCard.Fields.TryGetValue("Addresses", out addressesFields)) {
      if (addressesFields.Value.ValueType == FieldValueType.List) {
        foreach(FormField addressField in addressesFields.Value.AsList()) {
          if (addressField.Value.ValueType == FieldValueType.String) {
            string address = addressField.Value.AsString();

            Console.WriteLine($ "  Address: '{address}', with confidence {addressField.Confidence}");
          }
        }
      }
    }

    FormField companyNamesFields;
    if (businessCard.Fields.TryGetValue("CompanyNames", out companyNamesFields)) {
      if (companyNamesFields.Value.ValueType == FieldValueType.List) {
        foreach(FormField companyNameField in companyNamesFields.Value.AsList()) {
          if (companyNameField.Value.ValueType == FieldValueType.String) {
            string companyName = companyNameField.Value.AsString();

            Console.WriteLine($ "  Company name: '{companyName}', with confidence {companyNameField.Confidence}");
          }
        }
      }
    }
  }
}

анализ счетов;

В этом разделе показано, как анализировать и извлекать общие поля из счетов по продажам с помощью предварительно обученной модели. Дополнительные сведения об анализе счетов см. в модели счета аналитики документов.

Для анализа счетов по URL-адресу используйте метод StartRecognizeInvoicesFromUriAsync.

private static async Task AnalyzeInvoice(
FormRecognizerClient recognizerClient, string invoiceUrl) {
  var options = new RecognizeInvoicesOptions() {
    Locale = "en-US"
  };
  RecognizedFormCollection invoices = await recognizerClient.StartRecognizeInvoicesFromUriAsync(invoiceUrl, options).WaitForCompletionAsync();

Совет

Можно также проанализировать локальные изображения счетов. Изучите информацию о методах класса FormRecognizerClient, например о StartRecognizeInvoices. Кроме того, ознакомьтесь с примером кода на GitHub для сценариев, в которых используются локальные образы.

В приведенном ниже блоке кода обрабатывается счет с указанным универсальным кодом ресурса (URI) и все ее основные поля с соответствующими значениями выводятся в консоль.

  RecognizedForm invoice = invoices.Single();

  FormField invoiceIdField;
  if (invoice.Fields.TryGetValue("InvoiceId", out invoiceIdField)) {
    if (invoiceIdField.Value.ValueType == FieldValueType.String) {
      string invoiceId = invoiceIdField.Value.AsString();
      Console.WriteLine($ "    Invoice Id: '{invoiceId}', with confidence {invoiceIdField.Confidence}");
    }
  }

  FormField invoiceDateField;
  if (invoice.Fields.TryGetValue("InvoiceDate", out invoiceDateField)) {
    if (invoiceDateField.Value.ValueType == FieldValueType.Date) {
      DateTime invoiceDate = invoiceDateField.Value.AsDate();
      Console.WriteLine($ "    Invoice Date: '{invoiceDate}', with confidence {invoiceDateField.Confidence}");
    }
  }

  FormField dueDateField;
  if (invoice.Fields.TryGetValue("DueDate", out dueDateField)) {
    if (dueDateField.Value.ValueType == FieldValueType.Date) {
      DateTime dueDate = dueDateField.Value.AsDate();
      Console.WriteLine($ "    Due Date: '{dueDate}', with confidence {dueDateField.Confidence}");
    }
  }

  FormField vendorNameField;
  if (invoice.Fields.TryGetValue("VendorName", out vendorNameField)) {
    if (vendorNameField.Value.ValueType == FieldValueType.String) {
      string vendorName = vendorNameField.Value.AsString();
      Console.WriteLine($ "    Vendor Name: '{vendorName}', with confidence {vendorNameField.Confidence}");
    }
  }

  FormField vendorAddressField;
  if (invoice.Fields.TryGetValue("VendorAddress", out vendorAddressField)) {
    if (vendorAddressField.Value.ValueType == FieldValueType.String) {
      string vendorAddress = vendorAddressField.Value.AsString();
      Console.WriteLine($ "    Vendor Address: '{vendorAddress}', with confidence {vendorAddressField.Confidence}");
    }
  }

  FormField customerNameField;
  if (invoice.Fields.TryGetValue("CustomerName", out customerNameField)) {
    if (customerNameField.Value.ValueType == FieldValueType.String) {
      string customerName = customerNameField.Value.AsString();
      Console.WriteLine($ "    Customer Name: '{customerName}', with confidence {customerNameField.Confidence}");
    }
  }

  FormField customerAddressField;
  if (invoice.Fields.TryGetValue("CustomerAddress", out customerAddressField)) {
    if (customerAddressField.Value.ValueType == FieldValueType.String) {
      string customerAddress = customerAddressField.Value.AsString();
      Console.WriteLine($ "    Customer Address: '{customerAddress}', with confidence {customerAddressField.Confidence}");
    }
  }

  FormField customerAddressRecipientField;
  if (invoice.Fields.TryGetValue("CustomerAddressRecipient", out customerAddressRecipientField)) {
    if (customerAddressRecipientField.Value.ValueType == FieldValueType.String) {
      string customerAddressRecipient = customerAddressRecipientField.Value.AsString();
      Console.WriteLine($ "    Customer address recipient: '{customerAddressRecipient}', with confidence {customerAddressRecipientField.Confidence}");
    }
  }

  FormField invoiceTotalField;
  if (invoice.Fields.TryGetValue("InvoiceTotal", out invoiceTotalField)) {
    if (invoiceTotalField.Value.ValueType == FieldValueType.Float) {
      float invoiceTotal = invoiceTotalField.Value.AsFloat();
      Console.WriteLine($ "    Invoice Total: '{invoiceTotal}', with confidence {invoiceTotalField.Confidence}");
    }
  }
}

Анализ документов, удостоверяющих личность

В этом разделе показано, как анализировать и извлекать ключевые сведения из документов идентификации, выданных правительством, — паспортов по всему миру и лицензий водителя США с помощью предварительно созданной модели идентификатора аналитики документов. Дополнительные сведения об анализе документов с идентификаторами см. в модели документов аналитики документов.

Для анализа удостоверений личности по URI используйте метод StartRecognizeIdentityDocumentsFromUriAsync.

private static async Task AnalyzeId(
FormRecognizerClient recognizerClient, string idUrl) {
  RecognizedFormCollection identityDocument = await recognizerClient.StartRecognizeIdDocumentsFromUriAsync(idUrl).WaitForCompletionAsync();

Совет

Можно также анализировать локальные изображения таких документов. Изучите информацию о методах класса FormRecognizerClient, например о StartRecognizeIdentityDocumentsAsync. Кроме того, ознакомьтесь с примером кода на сайте GitHub для сценариев, включающих локальные образы.

В приведенном ниже блоке кода обрабатывается удостоверение с указанным универсальным кодом ресурса (URI), и все его основные поля с соответствующими значениями выводятся в консоль.

RecognizedForm identityDocument = identityDocuments.Single();

if (identityDocument.Fields.TryGetValue("Address", out FormField addressField)) {
  if (addressField.Value.ValueType == FieldValueType.String) {
    string address = addressField.Value.AsString();
    Console.WriteLine($ "Address: '{address}', with confidence {addressField.Confidence}");
  }
}

if (identityDocument.Fields.TryGetValue("CountryRegion", out FormField countryRegionField)) {
  if (countryRegionField.Value.ValueType == FieldValueType.CountryRegion) {
    string countryRegion = countryRegionField.Value.AsCountryRegion();
    Console.WriteLine($ "CountryRegion: '{countryRegion}', with confidence {countryRegionField.Confidence}");
  }
}

if (identityDocument.Fields.TryGetValue("DateOfBirth", out FormField dateOfBirthField)) {
  if (dateOfBirthField.Value.ValueType == FieldValueType.Date) {
    DateTime dateOfBirth = dateOfBirthField.Value.AsDate();
    Console.WriteLine($ "Date Of Birth: '{dateOfBirth}', with confidence {dateOfBirthField.Confidence}");
  }
}

if (identityDocument.Fields.TryGetValue("DateOfExpiration", out FormField dateOfExpirationField)) {
  if (dateOfExpirationField.Value.ValueType == FieldValueType.Date) {
    DateTime dateOfExpiration = dateOfExpirationField.Value.AsDate();
    Console.WriteLine($ "Date Of Expiration: '{dateOfExpiration}', with confidence {dateOfExpirationField.Confidence}");
  }
}

if (identityDocument.Fields.TryGetValue("DocumentNumber", out FormField documentNumberField)) {
  if (documentNumberField.Value.ValueType == FieldValueType.String) {
    string documentNumber = documentNumberField.Value.AsString();
    Console.WriteLine($ "Document Number: '{documentNumber}', with confidence {documentNumberField.Confidence}");
  }
  RecognizedForm identityDocument = identityDocuments.Single();

  if (identityDocument.Fields.TryGetValue("Address", out FormField addressField)) {
    if (addressField.Value.ValueType == FieldValueType.String) {
      string address = addressField.Value.AsString();
      Console.WriteLine($ "Address: '{address}', with confidence {addressField.Confidence}");
    }
  }

  if (identityDocument.Fields.TryGetValue("CountryRegion", out FormField countryRegionField)) {
    if (countryRegionField.Value.ValueType == FieldValueType.CountryRegion) {
      string countryRegion = countryRegionField.Value.AsCountryRegion();
      Console.WriteLine($ "CountryRegion: '{countryRegion}', with confidence {countryRegionField.Confidence}");
    }
  }

  if (identityDocument.Fields.TryGetValue("DateOfBirth", out FormField dateOfBirthField)) {
    if (dateOfBirthField.Value.ValueType == FieldValueType.Date) {
      DateTime dateOfBirth = dateOfBirthField.Value.AsDate();
      Console.WriteLine($ "Date Of Birth: '{dateOfBirth}', with confidence {dateOfBirthField.Confidence}");
    }
  }

  if (identityDocument.Fields.TryGetValue("DateOfExpiration", out FormField dateOfExpirationField)) {
    if (dateOfExpirationField.Value.ValueType == FieldValueType.Date) {
      DateTime dateOfExpiration = dateOfExpirationField.Value.AsDate();
      Console.WriteLine($ "Date Of Expiration: '{dateOfExpiration}', with confidence {dateOfExpirationField.Confidence}");
    }
  }

  if (identityDocument.Fields.TryGetValue("DocumentNumber", out FormField documentNumberField)) {
    if (documentNumberField.Value.ValueType == FieldValueType.String) {
      string documentNumber = documentNumberField.Value.AsString();
      Console.WriteLine($ "Document Number: '{documentNumber}', with confidence {documentNumberField.Confidence}");
    }
  }

  if (identityDocument.Fields.TryGetValue("FirstName", out FormField firstNameField)) {
    if (firstNameField.Value.ValueType == FieldValueType.String) {
      string firstName = firstNameField.Value.AsString();
      Console.WriteLine($ "First Name: '{firstName}', with confidence {firstNameField.Confidence}");
    }
  }

  if (identityDocument.Fields.TryGetValue("LastName", out FormField lastNameField)) {
    if (lastNameField.Value.ValueType == FieldValueType.String) {
      string lastName = lastNameField.Value.AsString();
      Console.WriteLine($ "Last Name: '{lastName}', with confidence {lastNameField.Confidence}");
    }
  }

  if (identityDocument.Fields.TryGetValue("Region", out FormField regionfield)) {
    if (regionfield.Value.ValueType == FieldValueType.String) {
      string region = regionfield.Value.AsString();
      Console.WriteLine($ "Region: '{region}', with confidence {regionfield.Confidence}");
    }
  }

обучение пользовательской модели;

В этом разделе демонстрируется, как обучить модель на основе собственных данных. Обученная модель может выводить структурированные данные, которые включают связи "ключ-значение" в исходном документе. После обучения модели вы можете проверить ее, повторно обучить и, в конечном итоге, применить с целью надежного извлечения данных из нескольких форм в соответствии со своими потребностями.

Примечание.

Вы также можете обучить модели с графическим пользовательским интерфейсом, таким как средство создания меток для аналитики документов.

Обучение моделей без меток

Вы можете обучить свою модель анализировать все поля и значения в ваших формах без необходимости вручную помечать документы, которые вы будете использовать для обучения. Приведенный ниже метод обучает модель на основе заданного набора документов и выводит ее статус в консоль.

private static async Task<String> TrainModel(
    FormTrainingClient trainingClient, string trainingDataUrl)
{
    CustomFormModel model = await trainingClient
    .StartTrainingAsync(new Uri(trainingDataUrl), useTrainingLabels: false)
    .WaitForCompletionAsync();

    Console.WriteLine($"Custom Model Info:");
    Console.WriteLine($"    Model Id: {model.ModelId}");
    Console.WriteLine($"    Model Status: {model.Status}");
    Console.WriteLine($"    Training model started on: {model.TrainingStartedOn}");
    Console.WriteLine($"    Training model completed on: {model.TrainingCompletedOn}");

Возвращаемый объект CustomFormModel содержит сведения о типах форм, которые может анализировать модель, и полях, которые она способна извлечь из формы каждого типа. Приведенный ниже блок кода выводит эту информацию в консоль.

foreach (CustomFormSubmodel submodel in model.Submodels)
{
    Console.WriteLine($"Submodel Form Type: {submodel.FormType}");
    foreach (CustomFormModelField field in submodel.Fields.Values)
    {
        Console.Write($"    FieldName: {field.Name}");
        if (field.Label != null)
        {
            Console.Write($", FieldLabel: {field.Label}");
        }
        Console.WriteLine("");
    }
}

Наконец, возвратите идентификатор обученной модели для использования на следующих шагах.

    return model.ModelId;
}

Эти выходные данные усечены для удобства чтения.

Merchant Name: 'Contoso Contoso', with confidence 0.516
Transaction Date: '6/10/2019 12:00:00 AM', with confidence 0.985
Item:
    Name: '8GB RAM (Black)', with confidence 0.916
    Total Price: '999', with confidence 0.559
Item:
    Name: 'SurfacePen', with confidence 0.858
    Total Price: '99.99', with confidence 0.386
Total: '1203.39', with confidence '0.774'
Form Page 1 has 18 lines.
    Line 0 has 1 word, and text: 'Contoso'.
    Line 1 has 1 word, and text: 'Address:'.
    Line 2 has 3 words, and text: 'Invoice For: Microsoft'.
    Line 3 has 4 words, and text: '1 Redmond way Suite'.
    Line 4 has 3 words, and text: '1020 Enterprise Way'.
    ...
Table 0 has 2 rows and 6 columns.
    Cell (0, 0) contains text: 'Invoice Number'.
    Cell (0, 1) contains text: 'Invoice Date'.
    Cell (0, 2) contains text: 'Invoice Due Date'.
    Cell (0, 3) contains text: 'Charges'.
    ...
Custom Model Info:
    Model Id: 95035721-f19d-40eb-8820-0c806b42798b
    Model Status: Ready
    Training model started on: 8/24/2020 6:36:44 PM +00:00
    Training model completed on: 8/24/2020 6:36:50 PM +00:00
Submodel Form Type: form-95035721-f19d-40eb-8820-0c806b42798b
    FieldName: CompanyAddress
    FieldName: CompanyName
    FieldName: CompanyPhoneNumber
    ...
Custom Model Info:
    Model Id: e7a1181b-1fb7-40be-bfbe-1ee154183633
    Model Status: Ready
    Training model started on: 8/24/2020 6:36:44 PM +00:00
    Training model completed on: 8/24/2020 6:36:52 PM +00:00
Submodel Form Type: form-0
    FieldName: field-0, FieldLabel: Additional Notes:
    FieldName: field-1, FieldLabel: Address:
    FieldName: field-2, FieldLabel: Company Name:
    FieldName: field-3, FieldLabel: Company Phone:
    FieldName: field-4, FieldLabel: Dated As:
    FieldName: field-5, FieldLabel: Details
    FieldName: field-6, FieldLabel: Email:
    FieldName: field-7, FieldLabel: Hero Limited
    FieldName: field-8, FieldLabel: Name:
    FieldName: field-9, FieldLabel: Phone:
    ...

Обучение моделей с метками

Модели также можно обучать на документах, которые размечены вручную. В некоторых сценариях обучение по такой схеме приводит к лучшим результатам. Чтобы производить обучение с метками, в контейнере хранилища BLOB-объектов вместе с документами для обучения должны находиться особые файлы с информацией о метках (<имя_файла>.pdf.labels.json) Средство создания меток аналитики документов предоставляет пользовательский интерфейс для создания этих файлов меток. После их получения можно вызвать StartTrainingAsync метод с заданным параметром uselabels true.

private static async Task<Guid> TrainModelWithLabelsAsync(
    FormRecognizerClient trainingClient, string trainingDataUrl)
{
    CustomFormModel model = await trainingClient
    .StartTrainingAsync(new Uri(trainingDataUrl), useTrainingLabels: true)
    .WaitForCompletionAsync();
    Console.WriteLine($"Custom Model Info:");
    Console.WriteLine($"    Model Id: {model.ModelId}");
    Console.WriteLine($"    Model Status: {model.Status}");
    Console.WriteLine($"    Training model started on: {model.TrainingStartedOn}");
    Console.WriteLine($"    Training model completed on: {model.TrainingCompletedOn}");

Возвращаемый CustomFormModel объект указывает поля, которые модель может извлекать, а также ее оценочную точность в каждом поле. Приведенный ниже блок кода выводит эту информацию в консоль.

    foreach (CustomFormSubmodel submodel in model.Submodels)
    {
        Console.WriteLine($"Submodel Form Type: {submodel.FormType}");
        foreach (CustomFormModelField field in submodel.Fields.Values)
        {
            Console.Write($"    FieldName: {field.Name}");
            if (field.Label != null)
            {
                Console.Write($", FieldLabel: {field.Label}");
            }
            Console.WriteLine("");
        }
    }
    return model.ModelId;
}

Эти выходные данные усечены для удобства чтения.

Form Page 1 has 18 lines.
    Line 0 has 1 word, and text: 'Contoso'.
    Line 1 has 1 word, and text: 'Address:'.
    Line 2 has 3 words, and text: 'Invoice For: Microsoft'.
    Line 3 has 4 words, and text: '1 Redmond way Suite'.
    Line 4 has 3 words, and text: '1020 Enterprise Way'.
    Line 5 has 3 words, and text: '6000 Redmond, WA'.
    ...
Table 0 has 2 rows and 6 columns.
    Cell (0, 0) contains text: 'Invoice Number'.
    Cell (0, 1) contains text: 'Invoice Date'.
    Cell (0, 2) contains text: 'Invoice Due Date'.
    ...
Merchant Name: 'Contoso Contoso', with confidence 0.516
Transaction Date: '6/10/2019 12:00:00 AM', with confidence 0.985
Item:
    Name: '8GB RAM (Black)', with confidence 0.916
    Total Price: '999', with confidence 0.559
Item:
    Name: 'SurfacePen', with confidence 0.858
    Total Price: '99.99', with confidence 0.386
Total: '1203.39', with confidence '0.774'
Custom Model Info:
    Model Id: 63c013e3-1cab-43eb-84b0-f4b20cb9214c
    Model Status: Ready
    Training model started on: 8/24/2020 6:42:54 PM +00:00
    Training model completed on: 8/24/2020 6:43:01 PM +00:00
Submodel Form Type: form-63c013e3-1cab-43eb-84b0-f4b20cb9214c
    FieldName: CompanyAddress
    FieldName: CompanyName
    FieldName: CompanyPhoneNumber
    FieldName: DatedAs
    FieldName: Email
    FieldName: Merchant
    ...

анализ документов с помощью пользовательской модели;

В этом разделе показано, как извлечь сведения о ключе и значении и другое содержимое из пользовательских типов шаблонов с помощью моделей, обученных с помощью собственных форм.

Внимание

Чтобы реализовать этот сценарий, необходимо уже обучить модель, чтобы передать его идентификатор в следующий метод.

Используйте метод StartRecognizeCustomFormsFromUri.

// Analyze PDF form data
private static async Task AnalyzePdfForm(
    FormRecognizerClient recognizerClient, String modelId, string formUrl)
{
    RecognizedFormCollection forms = await recognizerClient
    .StartRecognizeCustomFormsFromUri(modelId, new Uri(formUrl))
    .WaitForCompletionAsync();

Совет

Вы можете также проанализировать локальные файлы. Изучите информацию о методах класса FormRecognizerClient, например о StartRecognizeCustomForms. Кроме того, ознакомьтесь с примером кода на GitHub для сценариев, в которых используются локальные образы.

Возвращаемое значение — это коллекция RecognizedForm объектов. Существует один объект для каждой страницы в отправленном документе. Следующий код выводит в консоль результаты анализа. Он отображает каждое из распознанных полей с соответствующим значением и коэффициентом достоверности.

    foreach (RecognizedForm form in forms)
    {
        Console.WriteLine($"Form of type: {form.FormType}");
        foreach (FormField field in form.Fields.Values)
        {
            Console.WriteLine($"Field '{field.Name}: ");

            if (field.LabelData != null)
            {
                Console.WriteLine($"    Label: '{field.LabelData.Text}");
            }

            Console.WriteLine($"    Value: '{field.ValueData.Text}");
            Console.WriteLine($"    Confidence: '{field.Confidence}");
        }
        Console.WriteLine("Table data:");
        foreach (FormPage page in form.Pages)
        {
            for (int i = 0; i < page.Tables.Count; i++)
            {
                FormTable table = page.Tables[i];
                Console.WriteLine($"Table {i} has {table.RowCount} rows and {table.ColumnCount} columns.");
                foreach (FormTableCell cell in table.Cells)
                {
                    Console.WriteLine($"    Cell ({cell.RowIndex}, {cell.ColumnIndex}) contains {(cell.IsHeader ? "header" : "text")}: '{cell.Text}'");
                }
            }
        }
    }
}

Этот выходной ответ усечен для удобства чтения.

Custom Model Info:
    Model Id: 9b0108ee-65c8-450e-b527-bb309d054fc4
    Model Status: Ready
    Training model started on: 8/24/2020 7:00:31 PM +00:00
    Training model completed on: 8/24/2020 7:00:32 PM +00:00
Submodel Form Type: form-9b0108ee-65c8-450e-b527-bb309d054fc4
    FieldName: CompanyAddress
    FieldName: CompanyName
    FieldName: CompanyPhoneNumber
    ...
Form Page 1 has 18 lines.
    Line 0 has 1 word, and text: 'Contoso'.
    Line 1 has 1 word, and text: 'Address:'.
    Line 2 has 3 words, and text: 'Invoice For: Microsoft'.
    Line 3 has 4 words, and text: '1 Redmond way Suite'.
    ...

Table 0 has 2 rows and 6 columns.
    Cell (0, 0) contains text: 'Invoice Number'.
    Cell (0, 1) contains text: 'Invoice Date'.
    Cell (0, 2) contains text: 'Invoice Due Date'.
    ...
Merchant Name: 'Contoso Contoso', with confidence 0.516
Transaction Date: '6/10/2019 12:00:00 AM', with confidence 0.985
Item:
    Name: '8GB RAM (Black)', with confidence 0.916
    Total Price: '999', with confidence 0.559
Item:
    Name: 'SurfacePen', with confidence 0.858
    Total Price: '99.99', with confidence 0.386
Total: '1203.39', with confidence '0.774'
Custom Model Info:
    Model Id: dc115156-ce0e-4202-bbe4-7426e7bee756
    Model Status: Ready
    Training model started on: 8/24/2020 7:00:31 PM +00:00
    Training model completed on: 8/24/2020 7:00:41 PM +00:00
Submodel Form Type: form-0
    FieldName: field-0, FieldLabel: Additional Notes:
    FieldName: field-1, FieldLabel: Address:
    FieldName: field-2, FieldLabel: Company Name:
    FieldName: field-3, FieldLabel: Company Phone:
    FieldName: field-4, FieldLabel: Dated As:
    ...
Form of type: custom:form
Field 'Azure.AI.FormRecognizer.Models.FieldValue:
    Value: '$56,651.49
    Confidence: '0.249
Field 'Azure.AI.FormRecognizer.Models.FieldValue:
    Value: 'PT
    Confidence: '0.245
Field 'Azure.AI.FormRecognizer.Models.FieldValue:
    Value: '99243
    Confidence: '0.114
   ...

Управление настраиваемыми моделями.

В этом разделе показано, как управлять пользовательскими моделями, которые хранятся в вашей учетной записи. Выполняется несколько операций в следующем методе:

private static async Task ManageModels(
    FormTrainingClient trainingClient, string trainingFileUrl)
{

Проверка числа моделей в учетной записи ресурсов FormRecognizer

В следующем блоке кода проверяется количество моделей, сохраненных в учетной записи аналитики документов, и сравнивается с ограничением учетной записи.

// Check number of models in the FormRecognizer account, 
// and the maximum number of models that can be stored.
AccountProperties accountProperties = trainingClient.GetAccountProperties();
Console.WriteLine($"Account has {accountProperties.CustomModelCount} models.");
Console.WriteLine($"It can have at most {accountProperties.CustomModelLimit} models.");

Выходные данные

Account has 20 models.
It can have at most 5000 models.

Вывод списка моделей, которые хранятся в учетной записи ресурсов

Приведенный ниже блок кода выводит в консоль список текущих моделей в вашей учетной записи с подробными сведениями о них.

Pageable<CustomFormModelInfo> models = trainingClient.GetCustomModels();

foreach (CustomFormModelInfo modelInfo in models)
{
    Console.WriteLine($"Custom Model Info:");
    Console.WriteLine($"    Model Id: {modelInfo.ModelId}");
    Console.WriteLine($"    Model Status: {modelInfo.Status}");
    Console.WriteLine($"    Training model started on: {modelInfo.TrainingStartedOn}");
    Console.WriteLine($"    Training model completed on: {modelInfo.TrainingCompletedOn}");
}

Эти выходные данные усечены для удобства чтения.

Custom Model Info:
    Model Id: 05932d5a-a2f8-4030-a2ef-4e5ed7112515
    Model Status: Creating
    Training model started on: 8/24/2020 7:35:02 PM +00:00
    Training model completed on: 8/24/2020 7:35:02 PM +00:00
Custom Model Info:
    Model Id: 150828c4-2eb2-487e-a728-60d5d504bd16
    Model Status: Ready
    Training model started on: 8/24/2020 7:33:25 PM +00:00
    Training model completed on: 8/24/2020 7:33:27 PM +00:00
Custom Model Info:
    Model Id: 3303e9de-6cec-4dfb-9e68-36510a6ecbb2
    Model Status: Ready
    Training model started on: 8/24/2020 7:29:27 PM +00:00
    Training model completed on: 8/24/2020 7:29:36 PM +00:00

Получение определенной модели по ее идентификатору

Следующий блок кода обучает новую модель так же, как в Обучении модели без меток , а затем получает вторую ссылку на нее с помощью его идентификатора.

// Create a new model to store in the account
CustomFormModel model = await trainingClient.StartTrainingAsync(
    new Uri(trainingFileUrl)).WaitForCompletionAsync();

// Get the model that was just created
CustomFormModel modelCopy = trainingClient.GetCustomModel(model.ModelId);

Console.WriteLine($"Custom Model {modelCopy.ModelId} recognizes the following form types:");

foreach (CustomFormSubmodel submodel in modelCopy.Submodels)
{
    Console.WriteLine($"Submodel Form Type: {submodel.FormType}");
    foreach (CustomFormModelField field in submodel.Fields.Values)
    {
        Console.Write($"    FieldName: {field.Name}");
        if (field.Label != null)
        {
            Console.Write($", FieldLabel: {field.Label}");
        }
        Console.WriteLine("");
    }
}

Эти выходные данные усечены для удобства чтения.

Custom Model Info:
    Model Id: 150828c4-2eb2-487e-a728-60d5d504bd16
    Model Status: Ready
    Training model started on: 8/24/2020 7:33:25 PM +00:00
    Training model completed on: 8/24/2020 7:33:27 PM +00:00
Submodel Form Type: form-150828c4-2eb2-487e-a728-60d5d504bd16
    FieldName: CompanyAddress
    FieldName: CompanyName
    FieldName: CompanyPhoneNumber
    FieldName: DatedAs
    FieldName: Email
    FieldName: Merchant
    FieldName: PhoneNumber
    FieldName: PurchaseOrderNumber
    FieldName: Quantity
    FieldName: Signature
    FieldName: Subtotal
    FieldName: Tax
    FieldName: Total
    FieldName: VendorName
    FieldName: Website
...

Удаление модели из учетной записи ресурсов

Модель можно удалить из учетной записи ресурсов по ее идентификатору. В рамках этого шага мы также закроем метод.

    // Delete the model from the account.
    trainingClient.DeleteModel(model.ModelId);
}

Выполнение приложения

Запустите приложение из каталога приложения с помощью команды dotnet run.

dotnet run

Очистка ресурсов

Если вы хотите очистить и удалить подписку на службы искусственного интеллекта Azure, можно удалить ресурс или группу ресурсов. При удалении группы ресурсов также удаляются все связанные с ней ресурсы.

Устранение неполадок

При взаимодействии с клиентской библиотекой azure AI Document Intelligence с помощью пакета SDK для .NET ошибки, возвращаемые службой, приводят к RequestFailedExceptionвозникновению ошибок. Они включают тот же код состояния HTTP, что возвращает запрос REST API.

Например, если вы отправляете изображение квитанции с недопустимым универсальным кодом ресурса (URI), 400 возвращается ошибка, указывающая на недопустимый запрос.

try
{
    RecognizedReceiptCollection receipts = await client.StartRecognizeReceiptsFromUri(new Uri(receiptUri)).WaitForCompletionAsync();
}
catch (RequestFailedException e)
{
    Console.WriteLine(e.ToString());
}

Обратите внимание, что регистрируется дополнительная информация, например идентификатор запроса клиента операции.


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

Content:
    {"error":{"code":"FailedToDownloadImage","innerError":
    {"requestId":"8ca04feb-86db-4552-857c-fde903251518"},
    "message":"Failed to download image from input URL."}}

Headers:
    Transfer-Encoding: chunked
    x-envoy-upstream-service-time: REDACTED
    apim-request-id: REDACTED
    Strict-Transport-Security: REDACTED
    X-Content-Type-Options: REDACTED
    Date: Mon, 20 Apr 2020 22:48:35 GMT
    Content-Type: application/json; charset=utf-8

Следующие шаги

Для этого проекта вы использовали клиентская библиотека .NET Для обучения моделей и анализа форм различными способами. Теперь следует изучить советы по созданию лучшего набора данных для обучения и созданию более точных моделей.

Внимание

Этот проект предназначен для REST API Аналитики документов версии 2.1.

Справочная документация | Исходный код библиотеки | Пакет (Maven) | Примеры

Необходимые компоненты

  • Подписка Azure — создайте бесплатную учетную запись.

  • Текущая версия пакета средств разработки Java (JDK).

  • Средство сборки Gradle или другой диспетчер зависимостей.

  • Ресурс аналитики документов. Используйте бесплатную ценовую категорию (F0), чтобы опробовать службу, а затем выполните обновление до платного уровня для рабочей среды.

  • Ключ и конечная точка из ресурса, создаваемого для подключения приложения к службе аналитики документов Azure.

    1. После развертывания ресурса выберите Перейти к ресурсу.
    2. В меню навигации слева выберите "Ключи" и "Конечная точка".
    3. Скопируйте один из ключей и конечной точки для использования далее в этой статье.

    Снимок экрана: расположение ключей и конечной точки на портале Azure.

  • Набор данных для обучения в хранилище BLOB-объектов Azure. Ознакомьтесь со сборкой и обучением пользовательской модели , чтобы ознакомиться с советами и параметрами объединения набора данных для обучения. Для этого проекта можно использовать файлы в папке Train для примера набора данных. Скачайте и разархивируйте файл sample_data.zip.

Настройка среды программирования

Чтобы настроить среду программирования, создайте проект Gradle и установите клиентская библиотека.

Создание проекта Gradle

В окне консоли создайте каталог для приложения и перейдите к нему.

mkdir myapp
cd myapp

Выполните команду gradle init из рабочей папки. Эта команда создает основные файлы сборки для Gradle, включая build.gradle.kts, который используется во время выполнения для создания и настройки приложения.

gradle init --type basic

При появлении запроса на выбор DSL выберите Kotlin.

Установка клиентской библиотеки

В этом проекте используется диспетчер зависимостей Gradle. Клиентскую библиотеку и информацию для других диспетчеров зависимостей можно найти в центральном репозитории Maven.

В файле проекта build.gradle.kts включите клиентскую библиотеку в качестве оператора implementation наряду с требуемыми подключаемыми модулями и параметрами.

plugins {
    java
    application
}
application {
    mainClass.set("FormRecognizer")
}
repositories {
    mavenCentral()
}
dependencies {
    implementation(group = "com.azure", name = "azure-ai-formrecognizer", version = "3.1.1")
}

Создание файла Java

Выполните следующие команды из рабочего каталога:

mkdir -p src/main/java

Перейдите к новой папке и создайте файл с именем FormRecognizer.java. Откройте его в редакторе или интегрированной среде разработки и добавьте следующие import инструкции:

import com.azure.ai.formrecognizer.*;
import com.azure.ai.formrecognizer.training.*;
import com.azure.ai.formrecognizer.models.*;
import com.azure.ai.formrecognizer.training.models.*;

import java.util.concurrent.atomic.AtomicReference;
import java.util.List;
import java.util.Map;
import java.time.LocalDate;

import com.azure.core.credential.AzureKeyCredential;
import com.azure.core.http.rest.PagedIterable;
import com.azure.core.util.Context;
import com.azure.core.util.polling.SyncPoller;

В классе FormRecognizer приложения создайте переменные для ключа и конечной точки ресурса.

static final String key = "PASTE_YOUR_FORM_RECOGNIZER_SUBSCRIPTION_KEY_HERE";
static final String endpoint = "PASTE_YOUR_FORM_RECOGNIZER_ENDPOINT_HERE";

Внимание

Перейдите на портал Azure. Если ресурс аналитики документов, созданный в разделе "Предварительные требования", развернут успешно, в разделе "Дальнейшие действия " выберите "Перейти к ресурсу". Ключ и конечная точка можно найти в разделе " Ключи" и " Конечная точка".

Не забудьте удалить ключ из кода после завершения. Никогда не публикуйте его публично. В рабочей среде используйте безопасные методы для хранения учетных данных и доступа к ним. Дополнительные сведения см. в статье "Безопасность служб искусственного интеллекта Azure".

В методе приложения main добавьте вызовы методов, используемых в этом проекте. Вы определите эти вызовы позже. Кроме того, необходимо добавить ссылки на URL-адреса для обучающих и тестовых данных.

  1. Чтобы получить URL-адрес SAS для данных обучения пользовательской модели, перейдите к ресурсу хранилища в портал Azure и выберите контейнеры хранилища>данных.

  2. Перейдите к контейнеру, щелкните правой кнопкой мыши и выберите "Создать SAS".

    Получите SAS для контейнера, а не для самой учетной записи хранения.

  3. Убедитесь, что выбраны разрешения на чтение, запись, удаление и список, а затем выберите "Создать маркер SAS" и URL-адрес.

  4. Скопируйте значение в разделе URL-адреса во временное расположение. Оно должно быть в таком формате: https://<storage account>.blob.core.windows.net/<container name>?<SAS value>.

Чтобы получить URL-адрес формы для тестирования, можно воспользоваться приведенными выше инструкциями, чтобы получить URL-адрес SAS отдельного документа в хранилище BLOB-объектов. Также можно взять URL-адрес документа, расположенного в другом месте.

Используйте предыдущий метод, чтобы получить URL-адрес изображения квитанции.

String trainingDataUrl = "PASTE_YOUR_SAS_URL_OF_YOUR_FORM_FOLDER_IN_BLOB_STORAGE_HERE";
String formUrl = "PASTE_YOUR_FORM_RECOGNIZER_FORM_URL_HERE";
String receiptUrl = "https://docs.microsoft.com/azure/cognitive-services/form-recognizer/media" + "/contoso-allinone.jpg";
String bcUrl = "https://raw.githubusercontent.com/Azure/azure-sdk-for-python/master/sdk/formrecognizer/azure-ai-formrecognizer/samples/sample_forms/business_cards/business-card-english.jpg";
String invoiceUrl = "https://raw.githubusercontent.com/Azure/azure-sdk-for-python/master/sdk/formrecognizer/azure-ai-formrecognizer/samples/sample_forms/forms/Invoice_1.pdf";
String idUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/id-license.jpg"
// Call Form Recognizer scenarios:
System.out.println("Get form content...");
GetContent(recognizerClient, formUrl);

System.out.println("Analyze receipt...");
AnalyzeReceipt(recognizerClient, receiptUrl);

System.out.println("Analyze business card...");
AnalyzeBusinessCard(recognizerClient, bcUrl);

System.out.println("Analyze invoice...");
AnalyzeInvoice(recognizerClient, invoiceUrl);

System.out.println("Analyze id...");
AnalyzeId(recognizerClient, idUrl);

System.out.println("Train Model with training data...");
String modelId = TrainModel(trainingClient, trainingDataUrl);

System.out.println("Analyze PDF form...");
AnalyzePdfForm(recognizerClient, modelId, formUrl);

System.out.println("Manage models...");
ManageModels(trainingClient, trainingDataUrl);

Использование объектной модели

С помощью аналитики документов можно создать два разных типа клиента. Во-первых, FormRecognizerClientслужба запрашивает службу для распознанных полей формы и содержимого. Во-вторых, FormTrainingClientсоздает пользовательские модели и управляет ими для улучшения распознавания.

FormRecognizerClient предоставляет операции для выполнения следующих задач:

  • Распознать поля формы и содержимое с помощью пользовательских моделей, обученных для анализа пользовательских форм. Эти значения возвращаются в коллекцию объектов RecognizedForm. См. раздел " Анализ пользовательских форм".
  • Распознать содержимое формы, включая таблицы, строки и слова, без необходимости обучения модели. Содержимое форм возвращается в коллекцию объектов FormPage. См. раздел " Анализ макета".
  • Распознать распространенные поля из квитанций США, визитных карточек, счетов и документов идентификаторов с помощью предварительно обученной модели в службе аналитики документов.

FormTrainingClient предоставляет операции для:

  • Обучение пользовательских моделей для анализа всех полей и значений, найденных в пользовательских формах. Возвращается значение CustomFormModel , указывающее типы форм, которые анализирует модель и поля, которые он извлекает для каждого типа формы.
  • Обучение пользовательских моделей для анализа определенных полей и значений, заданных путем маркировки пользовательских форм. Возвращается значение CustomFormModel , указывающее поля, извлекаемые моделью и предполагаемую точность для каждого поля.
  • Управление моделями, созданными в вашей учетной записи.
  • Скопируйте пользовательскую модель из одного ресурса аналитики документов в другой.

Примечание.

Модели также можно обучены с помощью графического пользовательского интерфейса, например средства маркировки образца.

аутентификация клиента;

В верхней части main метода добавьте следующий код. Выполняется проверка подлинности двух клиентских объектов с помощью определенных ранее переменных подписки. Вы используете AzureKeyCredential объект, чтобы при необходимости можно обновить ключ без создания новых клиентских объектов.

FormRecognizerClient recognizerClient = new FormRecognizerClientBuilder()
        .credential(new AzureKeyCredential(key)).endpoint(endpoint).buildClient();

FormTrainingClient trainingClient = new FormTrainingClientBuilder().credential(new AzureKeyCredential(key))
        .endpoint(endpoint).buildClient();

Анализ макета

Аналитика документов позволяет анализировать таблицы, строки и слова в документах без необходимости обучения модели. Дополнительные сведения об извлечении макета см. в модели макета аналитики документов.

Для анализа содержимого файла по указанному URL-адресу используйте метод beginRecognizeContentFromUrl.

private static void GetContent(FormRecognizerClient recognizerClient, String invoiceUri) {
    String analyzeFilePath = invoiceUri;
    SyncPoller<FormRecognizerOperationResult, List<FormPage>> recognizeContentPoller = recognizerClient
            .beginRecognizeContentFromUrl(analyzeFilePath);

    List<FormPage> contentResult = recognizeContentPoller.getFinalResult();

Совет

Вы можете также получить содержимое из локального файла. Изучите информацию о методах класса FormRecognizerClient, например о beginRecognizeContent. Кроме того, ознакомьтесь с примером кода на GitHub для сценариев, в которых используются локальные образы.

Возвращаемое значение — это коллекция FormPage объектов. Существует один объект для каждой страницы в отправленном документе. Приведенный ниже код обрабатывает эти объекты в цикле и выводит извлеченные из документа пары ключей и значений, а также табличные данные.

    contentResult.forEach(formPage -> {
        // Table information
        System.out.println("----Recognizing content ----");
        System.out.printf("Has width: %f and height: %f, measured with unit: %s.%n", formPage.getWidth(),
                formPage.getHeight(), formPage.getUnit());
        formPage.getTables().forEach(formTable -> {
            System.out.printf("Table has %d rows and %d columns.%n", formTable.getRowCount(),
                    formTable.getColumnCount());
            formTable.getCells().forEach(formTableCell -> {
                System.out.printf("Cell has text %s.%n", formTableCell.getText());
            });
            System.out.println();
        });
    });
}

Результат выглядит следующим образом.

Get form content...
----Recognizing content ----
Has width: 8.500000 and height: 11.000000, measured with unit: inch.
Table has 2 rows and 6 columns.
Cell has text Invoice Number.
Cell has text Invoice Date.
Cell has text Invoice Due Date.
Cell has text Charges.
Cell has text VAT ID.
Cell has text 458176.
Cell has text 3/28/2018.
Cell has text 4/16/2018.
Cell has text $89,024.34.
Cell has text ET.

анализ квитанций;

В этом разделе показано, как анализировать и извлекать общие поля из квитанций США с помощью предварительно обученной модели получения. Дополнительные сведения об анализе квитанций см. в модели квитанций аналитики документов.

Для анализа чеков по URI используйте метод beginRecognizeReceiptsFromUrl.

private static void AnalyzeReceipt(FormRecognizerClient recognizerClient, String receiptUri) {
    SyncPoller<FormRecognizerOperationResult, List<RecognizedForm>> syncPoller = recognizerClient
            .beginRecognizeReceiptsFromUrl(receiptUri);
    List<RecognizedForm> receiptPageResults = syncPoller.getFinalResult();

Совет

Можно также проанализировать локальные изображения квитанций. Изучите информацию о методах класса FormRecognizerClient, например о beginRecognizeReceipts. Кроме того, ознакомьтесь с примером кода на GitHub для сценариев, в которых используются локальные образы.

Возвращаемое значение — это коллекция RecognizedReceipt объектов. Существует один объект для каждой страницы в отправленном документе. Следующий блок кода обрабатывает квитанции в цикле и выводит их данные в консоль.

for (int i = 0; i < receiptPageResults.size(); i++) {
    RecognizedForm recognizedForm = receiptPageResults.get(i);
    Map<String, FormField> recognizedFields = recognizedForm.getFields();
    System.out.printf("----------- Recognized Receipt page %d -----------%n", i);
    FormField merchantNameField = recognizedFields.get("MerchantName");
    if (merchantNameField != null) {
        if (FieldValueType.STRING == merchantNameField.getValue().getValueType()) {
            String merchantName = merchantNameField.getValue().asString();
            System.out.printf("Merchant Name: %s, confidence: %.2f%n", merchantName,
                    merchantNameField.getConfidence());
        }
    }
    FormField merchantAddressField = recognizedFields.get("MerchantAddress");
    if (merchantAddressField != null) {
        if (FieldValueType.STRING == merchantAddressField.getValue().getValueType()) {
            String merchantAddress = merchantAddressField.getValue().asString();
            System.out.printf("Merchant Address: %s, confidence: %.2f%n", merchantAddress,
                    merchantAddressField.getConfidence());
        }
    }
    FormField transactionDateField = recognizedFields.get("TransactionDate");
    if (transactionDateField != null) {
        if (FieldValueType.DATE == transactionDateField.getValue().getValueType()) {
            LocalDate transactionDate = transactionDateField.getValue().asDate();
            System.out.printf("Transaction Date: %s, confidence: %.2f%n", transactionDate,
                    transactionDateField.getConfidence());
        }
    }

Следующий блок кода обрабатывает в цикле отдельные объекты, обнаруженные в квитанции, и выводит их данные в консоль.

        FormField receiptItemsField = recognizedFields.get("Items");
        if (receiptItemsField != null) {
            System.out.printf("Receipt Items: %n");
            if (FieldValueType.LIST == receiptItemsField.getValue().getValueType()) {
                List<FormField> receiptItems = receiptItemsField.getValue().asList();
                receiptItems.stream()
                        .filter(receiptItem -> FieldValueType.MAP == receiptItem.getValue().getValueType())
                        .map(formField -> formField.getValue().asMap())
                        .forEach(formFieldMap -> formFieldMap.forEach((key, formField) -> {
                            if ("Name".equals(key)) {
                                if (FieldValueType.STRING == formField.getValue().getValueType()) {
                                    String name = formField.getValue().asString();
                                    System.out.printf("Name: %s, confidence: %.2fs%n", name,
                                            formField.getConfidence());
                                }
                            }
                            if ("Quantity".equals(key)) {
                                if (FieldValueType.FLOAT == formField.getValue().getValueType()) {
                                    Float quantity = formField.getValue().asFloat();
                                    System.out.printf("Quantity: %f, confidence: %.2f%n", quantity,
                                            formField.getConfidence());
                                }
                            }
                            if ("Price".equals(key)) {
                                if (FieldValueType.FLOAT == formField.getValue().getValueType()) {
                                    Float price = formField.getValue().asFloat();
                                    System.out.printf("Price: %f, confidence: %.2f%n", price,
                                            formField.getConfidence());
                                }
                            }
                            if ("TotalPrice".equals(key)) {
                                if (FieldValueType.FLOAT == formField.getValue().getValueType()) {
                                    Float totalPrice = formField.getValue().asFloat();
                                    System.out.printf("Total Price: %f, confidence: %.2f%n", totalPrice,
                                            formField.getConfidence());
                                }
                            }
                        }));
            }
        }
    }
}

Результат выглядит следующим образом.

Analyze receipt...
----------- Recognized Receipt page 0 -----------
Merchant Name: Contoso Contoso, confidence: 0.62
Merchant Address: 123 Main Street Redmond, WA 98052, confidence: 0.99
Transaction Date: 2020-06-10, confidence: 0.90
Receipt Items:
Name: Cappuccino, confidence: 0.96s
Quantity: null, confidence: 0.957s]
Total Price: 2.200000, confidence: 0.95
Name: BACON & EGGS, confidence: 0.94s
Quantity: null, confidence: 0.927s]
Total Price: null, confidence: 0.93

анализ визитных карточек;

В этом разделе показано, как анализировать и извлекать общие поля из английских визитных карточек с помощью предварительно обученной модели. Дополнительные сведения об анализе визитных карточек см. в модели бизнес-карты аналитики документов.

Для анализа визитных карточек по URL-адресу используйте метод beginRecognizeBusinessCardsFromUrl.

private static void AnalyzeBusinessCard(FormRecognizerClient recognizerClient, String bcUrl) {
    SyncPoller < FormRecognizerOperationResult,
    List < RecognizedForm >> recognizeBusinessCardPoller = client.beginRecognizeBusinessCardsFromUrl(businessCardUrl);

    List < RecognizedForm > businessCardPageResults = recognizeBusinessCardPoller.getFinalResult();

Совет

Можно также проанализировать локальные изображения визитных карточек. Изучите информацию о методах класса FormRecognizerClient, например о beginRecognizeBusinessCards. Кроме того, ознакомьтесь с примером кода на GitHub для сценариев, в которых используются локальные образы.

Возвращаемое значение — это коллекция RecognizedForm объектов. В документе есть один объект для каждой карточки. В следующем блоке кода обрабатывается визитная карточка с указанным универсальным кодом ресурса (URI) и все ее основные поля с соответствующими значениями выводятся в консоль.

    for (int i = 0; i < businessCardPageResults.size(); i++) {
        RecognizedForm recognizedForm = businessCardPageResults.get(i);
        Map < String,
        FormField > recognizedFields = recognizedForm.getFields();
        System.out.printf("----------- Recognized business card info for page %d -----------%n", i);
        FormField contactNamesFormField = recognizedFields.get("ContactNames");
        if (contactNamesFormField != null) {
            if (FieldValueType.LIST == contactNamesFormField.getValue().getValueType()) {
                List < FormField > contactNamesList = contactNamesFormField.getValue().asList();
                contactNamesList.stream().filter(contactName - >FieldValueType.MAP == contactName.getValue().getValueType()).map(contactName - >{
                    System.out.printf("Contact name: %s%n", contactName.getValueData().getText());
                    return contactName.getValue().asMap();
                }).forEach(contactNamesMap - >contactNamesMap.forEach((key, contactName) - >{
                    if ("FirstName".equals(key)) {
                        if (FieldValueType.STRING == contactName.getValue().getValueType()) {
                            String firstName = contactName.getValue().asString();
                            System.out.printf("\tFirst Name: %s, confidence: %.2f%n", firstName, contactName.getConfidence());
                        }
                    }
                    if ("LastName".equals(key)) {
                        if (FieldValueType.STRING == contactName.getValue().getValueType()) {
                            String lastName = contactName.getValue().asString();
                            System.out.printf("\tLast Name: %s, confidence: %.2f%n", lastName, contactName.getConfidence());
                        }
                    }
                }));
            }
        }

        FormField jobTitles = recognizedFields.get("JobTitles");
        if (jobTitles != null) {
            if (FieldValueType.LIST == jobTitles.getValue().getValueType()) {
                List < FormField > jobTitlesItems = jobTitles.getValue().asList();
                jobTitlesItems.stream().forEach(jobTitlesItem - >{
                    if (FieldValueType.STRING == jobTitlesItem.getValue().getValueType()) {
                        String jobTitle = jobTitlesItem.getValue().asString();
                        System.out.printf("Job Title: %s, confidence: %.2f%n", jobTitle, jobTitlesItem.getConfidence());
                    }
                });
            }
        }

        FormField departments = recognizedFields.get("Departments");
        if (departments != null) {
            if (FieldValueType.LIST == departments.getValue().getValueType()) {
                List < FormField > departmentsItems = departments.getValue().asList();
                departmentsItems.stream().forEach(departmentsItem - >{
                    if (FieldValueType.STRING == departmentsItem.getValue().getValueType()) {
                        String department = departmentsItem.getValue().asString();
                        System.out.printf("Department: %s, confidence: %.2f%n", department, departmentsItem.getConfidence());
                    }
                });
            }
        }

        FormField emails = recognizedFields.get("Emails");
        if (emails != null) {
            if (FieldValueType.LIST == emails.getValue().getValueType()) {
                List < FormField > emailsItems = emails.getValue().asList();
                emailsItems.stream().forEach(emailsItem - >{
                    if (FieldValueType.STRING == emailsItem.getValue().getValueType()) {
                        String email = emailsItem.getValue().asString();
                        System.out.printf("Email: %s, confidence: %.2f%n", email, emailsItem.getConfidence());
                    }
                });
            }
        }

        FormField websites = recognizedFields.get("Websites");
        if (websites != null) {
            if (FieldValueType.LIST == websites.getValue().getValueType()) {
                List < FormField > websitesItems = websites.getValue().asList();
                websitesItems.stream().forEach(websitesItem - >{
                    if (FieldValueType.STRING == websitesItem.getValue().getValueType()) {
                        String website = websitesItem.getValue().asString();
                        System.out.printf("Web site: %s, confidence: %.2f%n", website, websitesItem.getConfidence());
                    }
                });
            }
        }

        FormField mobilePhones = recognizedFields.get("MobilePhones");
        if (mobilePhones != null) {
            if (FieldValueType.LIST == mobilePhones.getValue().getValueType()) {
                List < FormField > mobilePhonesItems = mobilePhones.getValue().asList();
                mobilePhonesItems.stream().forEach(mobilePhonesItem - >{
                    if (FieldValueType.PHONE_NUMBER == mobilePhonesItem.getValue().getValueType()) {
                        String mobilePhoneNumber = mobilePhonesItem.getValue().asPhoneNumber();
                        System.out.printf("Mobile phone number: %s, confidence: %.2f%n", mobilePhoneNumber, mobilePhonesItem.getConfidence());
                    }
                });
            }
        }

        FormField otherPhones = recognizedFields.get("OtherPhones");
        if (otherPhones != null) {
            if (FieldValueType.LIST == otherPhones.getValue().getValueType()) {
                List < FormField > otherPhonesItems = otherPhones.getValue().asList();
                otherPhonesItems.stream().forEach(otherPhonesItem - >{
                    if (FieldValueType.PHONE_NUMBER == otherPhonesItem.getValue().getValueType()) {
                        String otherPhoneNumber = otherPhonesItem.getValue().asPhoneNumber();
                        System.out.printf("Other phone number: %s, confidence: %.2f%n", otherPhoneNumber, otherPhonesItem.getConfidence());
                    }
                });
            }
        }

        FormField faxes = recognizedFields.get("Faxes");
        if (faxes != null) {
            if (FieldValueType.LIST == faxes.getValue().getValueType()) {
                List < FormField > faxesItems = faxes.getValue().asList();
                faxesItems.stream().forEach(faxesItem - >{
                    if (FieldValueType.PHONE_NUMBER == faxesItem.getValue().getValueType()) {
                        String faxPhoneNumber = faxesItem.getValue().asPhoneNumber();
                        System.out.printf("Fax phone number: %s, confidence: %.2f%n", faxPhoneNumber, faxesItem.getConfidence());
                    }
                });
            }
        }

        FormField addresses = recognizedFields.get("Addresses");
        if (addresses != null) {
            if (FieldValueType.LIST == addresses.getValue().getValueType()) {
                List < FormField > addressesItems = addresses.getValue().asList();
                addressesItems.stream().forEach(addressesItem - >{
                    if (FieldValueType.STRING == addressesItem.getValue().getValueType()) {
                        String address = addressesItem.getValue().asString();
                        System.out.printf("Address: %s, confidence: %.2f%n", address, addressesItem.getConfidence());
                    }
                });
            }
        }

        FormField companyName = recognizedFields.get("CompanyNames");
        if (companyName != null) {
            if (FieldValueType.LIST == companyName.getValue().getValueType()) {
                List < FormField > companyNameItems = companyName.getValue().asList();
                companyNameItems.stream().forEach(companyNameItem - >{
                    if (FieldValueType.STRING == companyNameItem.getValue().getValueType()) {
                        String companyNameValue = companyNameItem.getValue().asString();
                        System.out.printf("Company name: %s, confidence: %.2f%n", companyNameValue, companyNameItem.getConfidence());
                    }
                });
            }
        }
    }
}

анализ счетов;

В этом разделе показано, как анализировать и извлекать общие поля из счетов по продажам с помощью предварительно обученной модели. Дополнительные сведения об анализе счетов см. в модели счета аналитики документов.

Для анализа счетов по URL-адресу используйте метод beginRecognizeInvoicesFromUrl.

private static void AnalyzeInvoice(FormRecognizerClient recognizerClient, String invoiceUrl) {
    SyncPoller < FormRecognizerOperationResult,
    List < RecognizedForm >> recognizeInvoicesPoller = client.beginRecognizeInvoicesFromUrl(invoiceUrl);

    List < RecognizedForm > recognizedInvoices = recognizeInvoicesPoller.getFinalResult();

Совет

Можно также проанализировать счета, сохраненные локально. Изучите информацию о методах класса FormRecognizerClient, например о beginRecognizeInvoices. Кроме того, ознакомьтесь с примером кода на GitHub для сценариев, в которых используются локальные образы.

Возвращаемое значение — это коллекция RecognizedForm объектов. В документе есть один объект для каждого счета. В приведенном ниже блоке кода обрабатывается счет с указанным универсальным кодом ресурса (URI) и все ее основные поля с соответствующими значениями выводятся в консоль.

    for (int i = 0; i < recognizedInvoices.size(); i++) {
        RecognizedForm recognizedInvoice = recognizedInvoices.get(i);
        Map < String,
        FormField > recognizedFields = recognizedInvoice.getFields();
        System.out.printf("----------- Recognized invoice info for page %d -----------%n", i);
        FormField vendorNameField = recognizedFields.get("VendorName");
        if (vendorNameField != null) {
            if (FieldValueType.STRING == vendorNameField.getValue().getValueType()) {
                String merchantName = vendorNameField.getValue().asString();
                System.out.printf("Vendor Name: %s, confidence: %.2f%n", merchantName, vendorNameField.getConfidence());
            }
        }

        FormField vendorAddressField = recognizedFields.get("VendorAddress");
        if (vendorAddressField != null) {
            if (FieldValueType.STRING == vendorAddressField.getValue().getValueType()) {
                String merchantAddress = vendorAddressField.getValue().asString();
                System.out.printf("Vendor address: %s, confidence: %.2f%n", merchantAddress, vendorAddressField.getConfidence());
            }
        }

        FormField customerNameField = recognizedFields.get("CustomerName");
        if (customerNameField != null) {
            if (FieldValueType.STRING == customerNameField.getValue().getValueType()) {
                String merchantAddress = customerNameField.getValue().asString();
                System.out.printf("Customer Name: %s, confidence: %.2f%n", merchantAddress, customerNameField.getConfidence());
            }
        }

        FormField customerAddressRecipientField = recognizedFields.get("CustomerAddressRecipient");
        if (customerAddressRecipientField != null) {
            if (FieldValueType.STRING == customerAddressRecipientField.getValue().getValueType()) {
                String customerAddr = customerAddressRecipientField.getValue().asString();
                System.out.printf("Customer Address Recipient: %s, confidence: %.2f%n", customerAddr, customerAddressRecipientField.getConfidence());
            }
        }

        FormField invoiceIdField = recognizedFields.get("InvoiceId");
        if (invoiceIdField != null) {
            if (FieldValueType.STRING == invoiceIdField.getValue().getValueType()) {
                String invoiceId = invoiceIdField.getValue().asString();
                System.out.printf("Invoice Id: %s, confidence: %.2f%n", invoiceId, invoiceIdField.getConfidence());
            }
        }

        FormField invoiceDateField = recognizedFields.get("InvoiceDate");
        if (customerNameField != null) {
            if (FieldValueType.DATE == invoiceDateField.getValue().getValueType()) {
                LocalDate invoiceDate = invoiceDateField.getValue().asDate();
                System.out.printf("Invoice Date: %s, confidence: %.2f%n", invoiceDate, invoiceDateField.getConfidence());
            }
        }

        FormField invoiceTotalField = recognizedFields.get("InvoiceTotal");
        if (customerAddressRecipientField != null) {
            if (FieldValueType.FLOAT == invoiceTotalField.getValue().getValueType()) {
                Float invoiceTotal = invoiceTotalField.getValue().asFloat();
                System.out.printf("Invoice Total: %.2f, confidence: %.2f%n", invoiceTotal, invoiceTotalField.getConfidence());
            }
        }
    }
}

Анализ документов, удостоверяющих личность

В этом разделе показано, как анализировать и извлекать ключевые сведения из документов идентификации, выданных правительством, — паспортов по всему миру и лицензий водителя США с помощью предварительно созданной модели идентификатора аналитики документов. Дополнительные сведения об анализе документов с идентификаторами см. в модели документов аналитики документов.

Для анализа удостоверений личности по URI используйте метод beginRecognizeIdentityDocumentsFromUrl.

private static void AnalyzeId(FormRecognizerClient client, String idUrl) {
    SyncPoller < FormRecognizerOperationResult,
    List < RecognizedForm >> analyzeIdentityDocumentPoller = client.beginRecognizeIdentityDocumentsFromUrl(licenseDocumentUrl);

    List < RecognizedForm > identityDocumentResults = analyzeIdentityDocumentPoller.getFinalResult();

Совет

Можно также анализировать локальные изображения таких документов. Изучите информацию о методах класса FormRecognizerClient, например о beginRecognizeIdentityDocuments. Кроме того, ознакомьтесь с примером кода на сайте GitHub для сценариев, включающих локальные образы.

В приведенном ниже блоке кода обрабатывается удостоверение с указанным универсальным кодом ресурса (URI), и все его основные поля с соответствующими значениями выводятся в консоль.

for (int i = 0; i < identityDocumentResults.size(); i++) {
    RecognizedForm recognizedForm = identityDocumentResults.get(i);
    Map < String,
    FormField > recognizedFields = recognizedForm.getFields();
    System.out.printf("----------- Recognized license info for page %d -----------%n", i);
    FormField addressField = recognizedFields.get("Address");
    if (addressField != null) {
        if (FieldValueType.STRING == addressField.getValue().getValueType()) {
            String address = addressField.getValue().asString();
            System.out.printf("Address: %s, confidence: %.2f%n", address, addressField.getConfidence());
        }
    }

    FormField countryRegionFormField = recognizedFields.get("CountryRegion");
    if (countryRegionFormField != null) {
        if (FieldValueType.STRING == countryRegionFormField.getValue().getValueType()) {
            String countryRegion = countryRegionFormField.getValue().asCountryRegion();
            System.out.printf("Country or region: %s, confidence: %.2f%n", countryRegion, countryRegionFormField.getConfidence());
        }
    }

    FormField dateOfBirthField = recognizedFields.get("DateOfBirth");
    if (dateOfBirthField != null) {
        if (FieldValueType.DATE == dateOfBirthField.getValue().getValueType()) {
            LocalDate dateOfBirth = dateOfBirthField.getValue().asDate();
            System.out.printf("Date of Birth: %s, confidence: %.2f%n", dateOfBirth, dateOfBirthField.getConfidence());
        }
    }

    FormField dateOfExpirationField = recognizedFields.get("DateOfExpiration");
    if (dateOfExpirationField != null) {
        if (FieldValueType.DATE == dateOfExpirationField.getValue().getValueType()) {
            LocalDate expirationDate = dateOfExpirationField.getValue().asDate();
            System.out.printf("Document date of expiration: %s, confidence: %.2f%n", expirationDate, dateOfExpirationField.getConfidence());
        }
    }

    FormField documentNumberField = recognizedFields.get("DocumentNumber");
    if (documentNumberField != null) {
        if (FieldValueType.STRING == documentNumberField.getValue().getValueType()) {
            String documentNumber = documentNumberField.getValue().asString();
            System.out.printf("Document number: %s, confidence: %.2f%n", documentNumber, documentNumberField.getConfidence());
        }
    }

    FormField firstNameField = recognizedFields.get("FirstName");
    if (firstNameField != null) {
        if (FieldValueType.STRING == firstNameField.getValue().getValueType()) {
            String firstName = firstNameField.getValue().asString();
            System.out.printf("First Name: %s, confidence: %.2f%n", firstName, documentNumberField.getConfidence());
        }
    }

    FormField lastNameField = recognizedFields.get("LastName");
    if (lastNameField != null) {
        if (FieldValueType.STRING == lastNameField.getValue().getValueType()) {
            String lastName = lastNameField.getValue().asString();
            System.out.printf("Last name: %s, confidence: %.2f%n", lastName, lastNameField.getConfidence());
        }
    }

    FormField regionField = recognizedFields.get("Region");
    if (regionField != null) {
        if (FieldValueType.STRING == regionField.getValue().getValueType()) {
            String region = regionField.getValue().asString();
            System.out.printf("Region: %s, confidence: %.2f%n", region, regionField.getConfidence());
        }
    }
}

обучение пользовательской модели;

В этом разделе демонстрируется, как обучить модель на основе собственных данных. Обученная модель может выводить структурированные данные, которые включают связи "ключ-значение" в исходном документе. После обучения модели вы можете проверить ее, повторно обучить и, в конечном итоге, применить с целью надежного извлечения данных из нескольких форм в соответствии со своими потребностями.

Примечание.

Вы также можете обучить модели с графическим пользовательским интерфейсом, таким как средство создания меток для аналитики документов.

Обучение моделей без меток

Вы можете обучить свою модель анализировать все поля и значения в ваших формах без необходимости вручную помечать документы, которые вы будете использовать для обучения.

Приведенный ниже метод обучает модель на основе заданного набора документов и выводит ее статус в консоль.

private static String TrainModel(FormTrainingClient trainingClient, String trainingDataUrl) {
    SyncPoller<FormRecognizerOperationResult, CustomFormModel> trainingPoller = trainingClient
            .beginTraining(trainingDataUrl, false);

    CustomFormModel customFormModel = trainingPoller.getFinalResult();

    // Model Info
    System.out.printf("Model Id: %s%n", customFormModel.getModelId());
    System.out.printf("Model Status: %s%n", customFormModel.getModelStatus());
    System.out.printf("Training started on: %s%n", customFormModel.getTrainingStartedOn());
    System.out.printf("Training completed on: %s%n%n", customFormModel.getTrainingCompletedOn());

Возвращаемый объект CustomFormModel содержит сведения о типах форм, которые может анализировать модель, и полях, которые она способна извлечь из формы каждого типа. Приведенный ниже блок кода выводит эту информацию в консоль.

System.out.println("Recognized Fields:");
// looping through the subModels, which contains the fields they were trained on
// Since the given training documents are unlabeled, we still group them but
// they do not have a label.
customFormModel.getSubmodels().forEach(customFormSubmodel -> {
    // Since the training data is unlabeled, we are unable to return the accuracy of
    // this model
    System.out.printf("The subModel has form type %s%n", customFormSubmodel.getFormType());
    customFormSubmodel.getFields().forEach((field, customFormModelField) -> System.out
            .printf("The model found field '%s' with label: %s%n", field, customFormModelField.getLabel()));
});

Наконец, этот метод возвращает уникальный идентификатор модели.

    return customFormModel.getModelId();
}

Результат выглядит следующим образом.

Train Model with training data...
Model Id: 20c3544d-97b4-49d9-b39b-dc32d85f1358
Model Status: ready
Training started on: 2020-08-31T16:52:09Z
Training completed on: 2020-08-31T16:52:23Z

Recognized Fields:
The subModel has form type form-0
The model found field 'field-0' with label: Address:
The model found field 'field-1' with label: Charges
The model found field 'field-2' with label: Invoice Date
The model found field 'field-3' with label: Invoice Due Date
The model found field 'field-4' with label: Invoice For:
The model found field 'field-5' with label: Invoice Number
The model found field 'field-6' with label: VAT ID

Обучение моделей с метками

Модели также можно обучать на документах, которые размечены вручную. В некоторых сценариях обучение по такой схеме приводит к лучшим результатам. Чтобы производить обучение с метками, в контейнере хранилища BLOB-объектов вместе с документами для обучения должны находиться особые файлы с информацией о метках (<имя_файла>.pdf.labels.json) Средство создания меток аналитики документов предоставляет пользовательский интерфейс для создания этих файлов меток. После их получения можно вызвать beginTraining метод с заданным параметром useTrainingLabels true.

private static String TrainModelWithLabels(FormTrainingClient trainingClient, String trainingDataUrl) {
    // Train custom model
    String trainingSetSource = trainingDataUrl;
    SyncPoller<FormRecognizerOperationResult, CustomFormModel> trainingPoller = trainingClient
            .beginTraining(trainingSetSource, true);

    CustomFormModel customFormModel = trainingPoller.getFinalResult();

    // Model Info
    System.out.printf("Model Id: %s%n", customFormModel.getModelId());
    System.out.printf("Model Status: %s%n", customFormModel.getModelStatus());
    System.out.printf("Training started on: %s%n", customFormModel.getTrainingStartedOn());
    System.out.printf("Training completed on: %s%n%n", customFormModel.getTrainingCompletedOn());

Возвращенный CustomFormModel указывает, что поля, которые модель может извлекать, а также ее оценочную точность в каждом поле. Приведенный ниже блок кода выводит эту информацию в консоль.

    // looping through the subModels, which contains the fields they were trained on
    // The labels are based on the ones you gave the training document.
    System.out.println("Recognized Fields:");
    // Since the data is labeled, we are able to return the accuracy of the model
    customFormModel.getSubmodels().forEach(customFormSubmodel -> {
        System.out.printf("The subModel with form type %s has accuracy: %.2f%n", customFormSubmodel.getFormType(),
                customFormSubmodel.getAccuracy());
        customFormSubmodel.getFields()
                .forEach((label, customFormModelField) -> System.out.printf(
                        "The model found field '%s' to have name: %s with an accuracy: %.2f%n", label,
                        customFormModelField.getName(), customFormModelField.getAccuracy()));
    });
    return customFormModel.getModelId();
}

Результат выглядит следующим образом.

Train Model with training data...
Model Id: 20c3544d-97b4-49d9-b39b-dc32d85f1358
Model Status: ready
Training started on: 2020-08-31T16:52:09Z
Training completed on: 2020-08-31T16:52:23Z

Recognized Fields:
The subModel has form type form-0
The model found field 'field-0' with label: Address:
The model found field 'field-1' with label: Charges
The model found field 'field-2' with label: Invoice Date
The model found field 'field-3' with label: Invoice Due Date
The model found field 'field-4' with label: Invoice For:
The model found field 'field-5' with label: Invoice Number
The model found field 'field-6' with label: VAT ID

анализ документов с помощью пользовательской модели;

В этом разделе показано, как извлекать данные вида "ключ/значение" и другое содержимое из пользовательских шаблонов с помощью обученных на них моделей.

Внимание

Для реализации этого сценария необходимо уже обучить модель, чтобы передать его идентификатор в операцию метода. См. статью "Обучение модели с помощью меток".

Используйте метод beginRecognizeCustomFormsFromUrl.

// Analyze PDF form data
private static void AnalyzePdfForm(FormRecognizerClient formClient, String modelId, String pdfFormUrl) {
    SyncPoller<FormRecognizerOperationResult, List<RecognizedForm>> recognizeFormPoller = formClient
            .beginRecognizeCustomFormsFromUrl(modelId, pdfFormUrl);

    List<RecognizedForm> recognizedForms = recognizeFormPoller.getFinalResult();

Совет

Вы можете также проанализировать локальные файлы. Изучите информацию о методах класса FormRecognizerClient, например о beginRecognizeCustomForms. Кроме того, ознакомьтесь с примером кода на GitHub для сценариев, в которых используются локальные образы.

Возвращаемое значение — это коллекция RecognizedForm объектов. Существует один объект для каждой страницы в отправленном документе. Следующий код выводит в консоль результаты анализа. Он отображает каждое из распознанных полей с соответствующим значением и коэффициентом достоверности.

    for (int i = 0; i < recognizedForms.size(); i++) {
        final RecognizedForm form = recognizedForms.get(i);
        System.out.printf("----------- Recognized custom form info for page %d -----------%n", i);
        System.out.printf("Form type: %s%n", form.getFormType());
        form.getFields().forEach((label, formField) ->
        // label data is populated if you are using a model trained with unlabeled data,
        // since the service needs to make predictions for labels if not explicitly
        // given to it.
        System.out.printf("Field '%s' has label '%s' with a confidence " + "score of %.2f.%n", label,
                formField.getLabelData().getText(), formField.getConfidence()));
    }
}

Результат выглядит следующим образом.

Analyze PDF form...
----------- Recognized custom template info for page 0 -----------
Form type: form-0
Field 'field-0' has label 'Address:' with a confidence score of 0.91.
Field 'field-1' has label 'Invoice For:' with a confidence score of 1.00.
Field 'field-2' has label 'Invoice Number' with a confidence score of 1.00.
Field 'field-3' has label 'Invoice Date' with a confidence score of 1.00.
Field 'field-4' has label 'Invoice Due Date' with a confidence score of 1.00.
Field 'field-5' has label 'Charges' with a confidence score of 1.00.
Field 'field-6' has label 'VAT ID' with a confidence score of 1.00.

Управление настраиваемыми моделями.

В этом разделе показано, как управлять пользовательскими моделями, которые хранятся в вашей учетной записи. Приведенный ниже код выполняет все задачи по управлению моделями в одном методе (в качестве примера). Сначала скопируйте следующую подпись метода:

private static void ManageModels(FormTrainingClient trainingClient, String trainingFileUrl) {

Проверка числа моделей в учетной записи ресурсов FormRecognizer

В следующем блоке кода проверяется количество моделей, сохраненных в учетной записи аналитики документов, и сравнивается с ограничением учетной записи.

AtomicReference<String> modelId = new AtomicReference<>();

// First, we see how many custom models we have, and what our limit is
AccountProperties accountProperties = trainingClient.getAccountProperties();
System.out.printf("The account has %s custom models, and we can have at most %s custom models",
        accountProperties.getCustomModelCount(), accountProperties.getCustomModelLimit());

Результат выглядит следующим образом.

The account has 12 custom models, and we can have at most 250 custom models

Вывод списка моделей, которые хранятся в учетной записи ресурсов

Приведенный ниже блок кода выводит в консоль список текущих моделей в вашей учетной записи с подробными сведениями о них.

// Next, we get a paged list of all of our custom models
PagedIterable<CustomFormModelInfo> customModels = trainingClient.listCustomModels();
System.out.println("We have following models in the account:");
customModels.forEach(customFormModelInfo -> {
    System.out.printf("Model Id: %s%n", customFormModelInfo.getModelId());
    // get custom model info
    modelId.set(customFormModelInfo.getModelId());
    CustomFormModel customModel = trainingClient.getCustomModel(customFormModelInfo.getModelId());
    System.out.printf("Model Id: %s%n", customModel.getModelId());
    System.out.printf("Model Status: %s%n", customModel.getModelStatus());
    System.out.printf("Training started on: %s%n", customModel.getTrainingStartedOn());
    System.out.printf("Training completed on: %s%n", customModel.getTrainingCompletedOn());
    customModel.getSubmodels().forEach(customFormSubmodel -> {
        System.out.printf("Custom Model Form type: %s%n", customFormSubmodel.getFormType());
        System.out.printf("Custom Model Accuracy: %.2f%n", customFormSubmodel.getAccuracy());
        if (customFormSubmodel.getFields() != null) {
            customFormSubmodel.getFields().forEach((fieldText, customFormModelField) -> {
                System.out.printf("Field Text: %s%n", fieldText);
                System.out.printf("Field Accuracy: %.2f%n", customFormModelField.getAccuracy());
            });
        }
    });
});

Результат выглядит следующим образом.

Этот ответ усечен для удобства чтения.

We have following models in the account:
Model Id: 0b048b60-86cc-47ec-9782-ad0ffaf7a5ce
Model Id: 0b048b60-86cc-47ec-9782-ad0ffaf7a5ce
Model Status: ready
Training started on: 2020-06-04T18:33:08Z
Training completed on: 2020-06-04T18:33:10Z
Custom Model Form type: form-0b048b60-86cc-47ec-9782-ad0ffaf7a5ce
Custom Model Accuracy: 1.00
Field Text: invoice date
Field Accuracy: 1.00
Field Text: invoice number
Field Accuracy: 1.00
...

Удаление модели из учетной записи ресурсов

Модель можно удалить из учетной записи ресурсов по ее идентификатору.

    // Delete Custom Model
    System.out.printf("Deleted model with model Id: %s, operation completed with status: %s%n", modelId.get(),
            trainingClient.deleteModelWithResponse(modelId.get(), Context.NONE).getStatusCode());
}

Выполнение приложения

Вернитесь к главному каталогу проекта. Затем создайте приложение с помощью следующей команды:

gradle build

Запустите приложение, выполнив цель run:

gradle run

Очистка ресурсов

Если вы хотите очистить и удалить подписку на службы искусственного интеллекта Azure, можно удалить ресурс или группу ресурсов. При удалении группы ресурсов также удаляются все связанные с ней ресурсы.

Устранение неполадок

Клиенты Аналитики документов вызывают ErrorResponseException исключения. Например, если вы попытаетесь указать недопустимый URL-адрес источника файла, ErrorResponseException будет возникать ошибка, указывающая на причину сбоя. В следующем фрагменте кода ошибка корректно обрабатывается путем перехвата исключения с выводом дополнительной информации.

try {
    formRecognizerClient.beginRecognizeContentFromUrl("invalidSourceUrl");
} catch (ErrorResponseException e) {
    System.out.println(e.getMessage());
}

Включение ведения журнала клиента

Пакеты SDK Azure для Java поддерживают возможность ведения подробных журналов, которые помогают находить ошибки в приложениях и ускоряют их устранение. Журналы вызвали запись потока приложения, прежде чем достичь состояния терминала, чтобы помочь найти корневую проблему. Дополнительные сведения о включении ведения журнала см. вики-сайте ведения журнала.

Следующие шаги

Для этого проекта вы использовали клиентская библиотека Java для аналитики документов для обучения моделей и анализа форм различными способами. Теперь следует изучить советы по созданию лучшего набора данных для обучения и созданию более точных моделей.

Внимание

Этот проект предназначен для REST API Аналитики документов версии 2.1.

Справочная документация | Исходный код библиотеки | Пакет (npm) | Примеры

Необходимые компоненты

  • Подписка Azure — создайте бесплатную учетную запись.

  • Последняя версия Visual Studio Code.

  • Последняя версия LTS Node.js.

  • Набор данных для обучения в хранилище BLOB-объектов Azure. Ознакомьтесь со сборкой и обучением пользовательской модели , чтобы ознакомиться с советами и параметрами объединения набора данных для обучения. Для этого проекта можно использовать файлы в папке Train примера набора данных. Скачайте и разархивируйте файл sample_data.zip.

  • Служба ИИ Azure или ресурс аналитики документов. Создайте ресурс аналитики документов. Используйте бесплатную ценовую категорию (F0), чтобы опробовать службу, а затем выполните обновление до платного уровня для рабочей среды.

  • Ключ и конечная точка из ресурса, создаваемого для подключения приложения к службе аналитики документов Azure.

    1. После развертывания ресурса выберите Перейти к ресурсу.
    2. В меню навигации слева выберите "Ключи" и "Конечная точка".
    3. Скопируйте один из ключей и конечной точки для использования далее в этой статье.

    Снимок экрана: расположение ключей и конечной точки на портале Azure.

Настройка среды программирования

Создайте приложение и установите клиентская библиотека.

Создание нового приложения Node.js

  1. В окне консоли создайте каталог для приложения и перейдите к нему.

    mkdir myapp
    cd myapp
    
  2. npm init Выполните команду, чтобы создать приложение узла с помощью файла package.json.

    npm init
    

Установка клиентской библиотеки

  1. Установите пакет npm ai-form-recognizer:

    npm install @azure/ai-form-recognizer
    

    Файл package.json приложения обновляется с помощью зависимостей.

  2. Создайте файл с именем index.js, откройте его и импортируйте следующие библиотеки:

    const { FormRecognizerClient, FormTrainingClient, AzureKeyCredential } = require("@azure/ai-form-recognizer");
    const fs = require("fs");
    
  3. Создайте переменные для конечной точки Azure и ключа ресурса.

    const apiKey = "PASTE_YOUR_FORM_RECOGNIZER_SUBSCRIPTION_KEY_HERE";
    const endpoint = "PASTE_YOUR_FORM_RECOGNIZER_ENDPOINT_HERE";
    

Внимание

Перейдите на портал Azure. Если ресурс аналитики документов, созданный в разделе "Предварительные требования", развернут успешно, в разделе "Дальнейшие действия " выберите "Перейти к ресурсу". Ключ и конечная точка можно найти в разделе " Ключи" и " Конечная точка".

Не забудьте удалить ключ из кода после завершения. Никогда не публикуйте его публично. В рабочей среде используйте безопасные методы для хранения учетных данных и доступа к ним. Дополнительные сведения см. в статье "Безопасность служб искусственного интеллекта Azure".

Использование объектной модели

С помощью аналитики документов можно создать два разных типа клиента. Во-первых, FormRecognizerClientслужба запрашивает службу для распознанных полей формы и содержимого. Во-вторых, FormTrainingClientсоздает пользовательские модели и управляет ими для улучшения распознавания.

FormRecognizerClient предоставляет следующие операции:

  • Распознать поля формы и содержимое с помощью пользовательских моделей, обученных для анализа пользовательских форм. Эти значения возвращаются в коллекцию объектов RecognizedForm.
  • Распознавание содержимого форм, в том числе таблиц, строк и слов, без необходимости обучения модели. Содержимое форм возвращается в коллекцию объектов FormPage.
  • Распознайте распространенные поля из квитанций США, визитных карточек, счетов и документов идентификаторов с помощью предварительно обученной модели в службе аналитики документов.

FormTrainingClient предоставляет операции для:

  • Обучение пользовательских моделей для анализа всех полей и значений, найденных в пользовательских формах. Возвращается значение CustomFormModel , указывающее типы форм, которые модель анализирует и извлекает поля для каждого типа формы. Дополнительные сведения см . в документации службы по обучению неназначенных моделей.
  • Обучение пользовательских моделей для анализа определенных полей и значений, заданных путем маркировки пользовательских форм. Возвращается значение CustomFormModel , указывающее поля, извлекаемые моделью и предполагаемую точность для каждого поля. Дополнительные сведения см. в разделе "Обучение модели с помощью меток " в этой статье.
  • Управление моделями, созданными в вашей учетной записи.
  • Скопируйте пользовательскую модель из одного ресурса аналитики документов в другой.

Примечание.

Модели также можно обучить с помощью графического пользовательского интерфейса, например средства маркировки образца.

аутентификация клиента;

Проверка подлинности клиентского объекта с помощью определенных переменных подписки. AzureKeyCredential Используйте объект, чтобы при необходимости можно обновить ключ без создания новых клиентских объектов. Вы также создаете объект клиента обучения.

const trainingClient = new FormTrainingClient(endpoint, new AzureKeyCredential(apiKey));
const client = new FormRecognizerClient(endpoint, new AzureKeyCredential(apiKey));

Получение ресурсов для тестирования

Кроме того, необходимо добавить ссылки на URL-адреса для обучающих и тестовых данных.

  1. Чтобы получить URL-адрес SAS для данных обучения пользовательской модели, перейдите к ресурсу хранилища в портал Azure и выберите контейнеры хранилища>данных.

  2. Перейдите к контейнеру, щелкните правой кнопкой мыши и выберите "Создать SAS".

    Получите SAS для контейнера, а не для самой учетной записи хранения.

  3. Убедитесь, что выбраны разрешения на чтение, запись, удаление и список, а затем выберите "Создать маркер SAS" и URL-адрес.

  4. Скопируйте значение в разделе URL-адреса во временное расположение. Оно должно быть в таком формате: https://<storage account>.blob.core.windows.net/<container name>?<SAS value>.

Используйте пример из образов квитанций, включенных в примеры. Эти изображения также доступны на сайте GitHub. Приведенные выше действия можно использовать для получения URL-адреса SAS отдельного документа в хранилище BLOB-объектов.

Анализ макета

Аналитика документов позволяет анализировать таблицы, строки и слова в документах без необходимости обучения модели. Дополнительные сведения об извлечении макета см. в модели макета аналитики документов. Для анализа содержимого файла по указанному URI используйте метод beginRecognizeContentFromUrl.

async function recognizeContent() {
    const formUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/simple-invoice.png";
    const poller = await client.beginRecognizeContentFromUrl(formUrl);
    const pages = await poller.pollUntilDone();

    if (!pages || pages.length === 0) {
        throw new Error("Expecting non-empty list of pages!");
    }

    for (const page of pages) {
        console.log(
            `Page ${page.pageNumber}: width ${page.width} and height ${page.height} with unit ${page.unit}`
        );
        for (const table of page.tables) {
            for (const cell of table.cells) {
                console.log(`cell [${cell.rowIndex},${cell.columnIndex}] has text ${cell.text}`);
            }
        }
    }
}

recognizeContent().catch((err) => {
    console.error("The sample encountered an error:", err);
});

Совет

Вы также можете получить содержимое из локального файла с помощью методов FormRecognizerClient , таких как beginRecognizeContent.

Page 1: width 8.5 and height 11 with unit inch
cell [0,0] has text Invoice Number
cell [0,1] has text Invoice Date
cell [0,2] has text Invoice Due Date
cell [0,3] has text Charges
cell [0,5] has text VAT ID
cell [1,0] has text 34278587
cell [1,1] has text 6/18/2017
cell [1,2] has text 6/24/2017
cell [1,3] has text $56,651.49
cell [1,5] has text PT

анализ квитанций;

В этом разделе показано, как анализировать и извлекать общие поля из квитанций США с помощью предварительно обученной модели получения. Дополнительные сведения об анализе квитанций см. в модели квитанций аналитики документов.

Для анализа чеков по URI используйте метод beginRecognizeReceiptsFromUrl. В следующем блоке кода обрабатывается квитанция с указанным универсальным кодом ресурса (URI) и в консоль выводятся все ее основные поля с соответствующими значениями.

async function recognizeReceipt() {
    receiptUrl = "https://raw.githubusercontent.com/Azure/azure-sdk-for-python/master/sdk/formrecognizer/azure-ai-formrecognizer/tests/sample_forms/receipt/contoso-receipt.png";
    const poller = await client.beginRecognizeReceiptsFromUrl(receiptUrl, {
        onProgress: (state) => { console.log(`status: ${state.status}`); }
    });

    const receipts = await poller.pollUntilDone();

    if (!receipts || receipts.length <= 0) {
        throw new Error("Expecting at lease one receipt in analysis result");
    }

    const receipt = receipts[0];
    console.log("First receipt:");
    const receiptTypeField = receipt.fields["ReceiptType"];
    if (receiptTypeField.valueType === "string") {
        console.log(`  Receipt Type: '${receiptTypeField.value || "<missing>"}', with confidence of ${receiptTypeField.confidence}`);
    }
    const merchantNameField = receipt.fields["MerchantName"];
    if (merchantNameField.valueType === "string") {
        console.log(`  Merchant Name: '${merchantNameField.value || "<missing>"}', with confidence of ${merchantNameField.confidence}`);
    }
    const transactionDate = receipt.fields["TransactionDate"];
    if (transactionDate.valueType === "date") {
        console.log(`  Transaction Date: '${transactionDate.value || "<missing>"}', with confidence of ${transactionDate.confidence}`);
    }
    const itemsField = receipt.fields["Items"];
    if (itemsField.valueType === "array") {
        for (const itemField of itemsField.value || []) {
            if (itemField.valueType === "object") {
                const itemNameField = itemField.value["Name"];
                if (itemNameField.valueType === "string") {
                    console.log(`    Item Name: '${itemNameField.value || "<missing>"}', with confidence of ${itemNameField.confidence}`);
                }
            }
        }
    }
    const totalField = receipt.fields["Total"];
    if (totalField.valueType === "number") {
        console.log(`  Total: '${totalField.value || "<missing>"}', with confidence of ${totalField.confidence}`);
    }
}

recognizeReceipt().catch((err) => {
    console.error("The sample encountered an error:", err);
});

Совет

Вы также можете анализировать локальные образы квитанций с помощью методов FormRecognizerClient , таких как beginRecognizeReceipts.

status: notStarted
status: running
status: succeeded
First receipt:
  Receipt Type: 'Itemized', with confidence of 0.659
  Merchant Name: 'Contoso Contoso', with confidence of 0.516
  Transaction Date: 'Sun Jun 09 2019 17:00:00 GMT-0700 (Pacific Daylight Time)', with confidence of 0.985
    Item Name: '8GB RAM (Black)', with confidence of 0.916
    Item Name: 'SurfacePen', with confidence of 0.858
  Total: '1203.39', with confidence of 0.774

анализ визитных карточек;

В этом разделе показано, как анализировать и извлекать общие поля из визитных карточек английского языка с помощью предварительно обученной модели. Дополнительные сведения об анализе визитных карточек см. в модели бизнес-карты аналитики документов.

Для анализа визитных карточек по URL-адресу используйте метод beginRecognizeBusinessCardsFromURL.

async function recognizeBusinessCards() {
    bcUrl = "https://github.com/Azure-Samples/cognitive-services-REST-api-samples/curl/form-recognizer/businessCard.png";
    const poller = await client.beginRecognizeBusinessCardsFromUrl(bcUrl, {
        onProgress: (state) => {
            console.log(`status: ${state.status}`);
        }
    });

    const [businessCard] = await poller.pollUntilDone();

    if (businessCard === undefined) {
        throw new Error("Failed to extract data from at least one business card.");
    }

    const contactNames = businessCard.fields["ContactNames"].value;
    if (Array.isArray(contactNames)) {
        console.log("- Contact Names:");
        for (const contactName of contactNames) {
            if (contactName.valueType === "object") {
                const firstName = contactName.value?.["FirstName"].value ?? "<no first name>";
                const lastName = contactName.value?.["LastName"].value ?? "<no last name>";
                console.log(`  - ${firstName} ${lastName} (${contactName.confidence} confidence)`);
            }
        }
    }

    printSimpleArrayField(businessCard, "CompanyNames");
    printSimpleArrayField(businessCard, "Departments");
    printSimpleArrayField(businessCard, "JobTitles");
    printSimpleArrayField(businessCard, "Emails");
    printSimpleArrayField(businessCard, "Websites");
    printSimpleArrayField(businessCard, "Addresses");
    printSimpleArrayField(businessCard, "MobilePhones");
    printSimpleArrayField(businessCard, "Faxes");
    printSimpleArrayField(businessCard, "WorkPhones");
    printSimpleArrayField(businessCard, "OtherPhones");
}

// Helper function to print array field values. 
function printSimpleArrayField(businessCard, fieldName) {
    const fieldValues = businessCard.fields[fieldName]?.value;
    if (Array.isArray(fieldValues)) {
        console.log(`- ${fieldName}:`);
        for (const item of fieldValues) {
            console.log(`  - ${item.value ?? "<no value>"} (${item.confidence} confidence)`);
        }
    } else if (fieldValues === undefined) {
        console.log(`No ${fieldName} were found in the document.`);
    } else {
        console.error(
            `Error: expected field "${fieldName}" to be an Array, but it was a(n) ${businessCard.fields[fieldName].valueType}`
        );
    }
}

recognizeBusinessCards().catch((err) => {
    console.error("The sample encountered an error:", err);
});

Совет

Вы также можете анализировать изображения локальных визитных карточек с помощью методов FormRecognizerClient , таких как beginRecognizeBusinessCards.

анализ счетов;

В этом разделе показано, как анализировать и извлекать общие поля из счетов по продажам с помощью предварительно обученной модели. Дополнительные сведения об анализе счетов см. в модели счета аналитики документов.

Для анализа счетов по URL-адресу используйте метод beginRecognizeInvoicesFromUrl.

async function recognizeInvoices() {
    invoiceUrl = "https://github.com/Azure-Samples/cognitive-services-REST-api-samples/curl/form-recognizer/invoice_sample.jpg";

    const poller = await client.beginRecognizeInvoicesFromUrl(invoiceUrl, {
        onProgress: (state) => {
            console.log(`status: ${state.status}`);
        }
    });

    const [invoice] = await poller.pollUntilDone();
    if (invoice === undefined) {
        throw new Error("Failed to extract data from at least one invoice.");
    }

    // Helper function to print fields.
    function fieldToString(field) {
        const {
            name,
            valueType,
            value,
            confidence
        } = field;
        return `${name} (${valueType}): '${value}' with confidence ${confidence}'`;
    }

    console.log("Invoice fields:");

    for (const [name, field] of Object.entries(invoice.fields)) {
        if (field.valueType !== "array" && field.valueType !== "object") {
            console.log(`- ${name} ${fieldToString(field)}`);
        }
    }

    let idx = 0;

    console.log("- Items:");

    const items = invoice.fields["Items"]?.value;
    for (const item of items ?? []) {
        const value = item.value;

        const subFields = [
            "Description",
            "Quantity",
            "Unit",
            "UnitPrice",
            "ProductCode",
            "Date",
            "Tax",
            "Amount"
        ]
            .map((fieldName) => value[fieldName])
            .filter((field) => field !== undefined);

        console.log(
            [
                `  - Item #${idx}`,
                // Now we will convert those fields into strings to display
                ...subFields.map((field) => `    - ${fieldToString(field)}`)
            ].join("\n")
        );
    }
}

recognizeInvoices().catch((err) => {
    console.error("The sample encountered an error:", err);
});

Совет

Вы также можете анализировать локальные образы квитанций с помощью методов FormRecognizerClient , таких как beginRecognizeInvoices.

Анализ документов, удостоверяющих личность

В этом разделе показано, как анализировать и извлекать ключевые сведения из документов идентификации, выданных правительством, включая паспорта по всему миру и лицензии водителя США, с помощью предварительно созданной модели идентификатора аналитики документов. Дополнительные сведения об анализе документов с идентификаторами см. в модели документов аналитики документов.

Для анализа удостоверений личности по URL-адресу используйте метод beginRecognizeIdDocumentsFromUrl.

async function recognizeIdDocuments() {
    idUrl = "https://github.com/Azure-Samples/cognitive-services-REST-api-samples/curl/form-recognizer/id-license.jpg";
    const poller = await client.beginRecognizeIdDocumentsFromUrl(idUrl, {
        onProgress: (state) => {
            console.log(`status: ${state.status}`);
        }
    });

    const [idDocument] = await poller.pollUntilDone();

    if (idDocument === undefined) {
        throw new Error("Failed to extract data from at least one identity document.");
    }

    console.log("Document Type:", idDocument.formType);

    console.log("Identity Document Fields:");

    function printField(fieldName) {
        // Fields are extracted from the `fields` property of the document result
        const field = idDocument.fields[fieldName];
        console.log(
            `- ${fieldName} (${field?.valueType}): '${field?.value ?? "<missing>"}', with confidence ${field?.confidence
            }`
        );
    }

    printField("FirstName");
    printField("LastName");
    printField("DocumentNumber");
    printField("DateOfBirth");
    printField("DateOfExpiration");
    printField("Sex");
    printField("Address");
    printField("Country");
    printField("Region");
}

recognizeIdDocuments().catch((err) => {
    console.error("The sample encountered an error:", err);
});

обучение пользовательской модели;

В этом разделе демонстрируется, как обучить модель на основе собственных данных. Обученная модель может выводить структурированные данные, которые включают связи "ключ-значение" в исходном документе. После обучения модели вы можете проверить ее, повторно обучить и, в конечном итоге, применить с целью надежного извлечения данных из нескольких форм в соответствии со своими потребностями.

Примечание.

Вы также можете обучить модели с графическим пользовательским интерфейсом (GUI), например инструментом создания меток для аналитики документов.

Обучение моделей без меток

Вы можете обучить свою модель анализировать все поля и значения в ваших формах без необходимости вручную помечать документы, которые вы будете использовать для обучения.

Приведенная ниже функция обучает модель на основе заданного набора документов и выводит ее статус в консоль.

async function trainModel() {

    const containerSasUrl = "<SAS-URL-of-your-form-folder-in-blob-storage>";

    const poller = await trainingClient.beginTraining(containerSasUrl, false, {
        onProgress: (state) => { console.log(`training status: ${state.status}`); }
    });
    const model = await poller.pollUntilDone();

    if (!model) {
        throw new Error("Expecting valid training result!");
    }

    console.log(`Model ID: ${model.modelId}`);
    console.log(`Status: ${model.status}`);
    console.log(`Training started on: ${model.trainingStartedOn}`);
    console.log(`Training completed on: ${model.trainingCompletedOn}`);

    if (model.submodels) {
        for (const submodel of model.submodels) {
            // since the training data is unlabeled, we are unable to return the accuracy of this model
            console.log("We have recognized the following fields");
            for (const key in submodel.fields) {
                const field = submodel.fields[key];
                console.log(`The model found field '${field.name}'`);
            }
        }
    }
    // Training document information
    if (model.trainingDocuments) {
        for (const doc of model.trainingDocuments) {
            console.log(`Document name: ${doc.name}`);
            console.log(`Document status: ${doc.status}`);
            console.log(`Document page count: ${doc.pageCount}`);
            console.log(`Document errors: ${doc.errors}`);
        }
    }
}

trainModel().catch((err) => {
    console.error("The sample encountered an error:", err);
});

Ниже приведены выходные данные для модели, обученной с данными обучения, доступными в пакете SDK для JavaScript. Этот пример результата был усечен для удобства чтения.

training status: creating
training status: ready
Model ID: 9d893595-1690-4cf2-a4b1-fbac0fb11909
Status: ready
Training started on: Thu Aug 20 2020 20:27:26 GMT-0700 (Pacific Daylight Time)
Training completed on: Thu Aug 20 2020 20:27:37 GMT-0700 (Pacific Daylight Time)
We have recognized the following fields
The model found field 'field-0'
The model found field 'field-1'
The model found field 'field-2'
The model found field 'field-3'
The model found field 'field-4'
The model found field 'field-5'
The model found field 'field-6'
The model found field 'field-7'
...
Document name: Form_1.jpg
Document status: succeeded
Document page count: 1
Document errors:
Document name: Form_2.jpg
Document status: succeeded
Document page count: 1
Document errors:
Document name: Form_3.jpg
Document status: succeeded
Document page count: 1
Document errors:
...

Обучение моделей с метками

Модели также можно обучать на документах, которые размечены вручную. В некоторых сценариях обучение по такой схеме приводит к лучшим результатам. Чтобы производить обучение с метками, в контейнере хранилища BLOB-объектов вместе с документами для обучения должны находиться особые файлы с информацией о метках (<имя_файла>.pdf.labels.json) Средство создания меток аналитики документов предоставляет пользовательский интерфейс для создания этих файлов меток. После их получения можно вызвать beginTraining метод с заданным параметром uselabels true.

async function trainModelLabels() {

    const containerSasUrl = "<SAS-URL-of-your-form-folder-in-blob-storage>";

    const poller = await trainingClient.beginTraining(containerSasUrl, true, {
        onProgress: (state) => { console.log(`training status: ${state.status}`); }
    });
    const model = await poller.pollUntilDone();

    if (!model) {
        throw new Error("Expecting valid training result!");
    }

    console.log(`Model ID: ${model.modelId}`);
    console.log(`Status: ${model.status}`);
    console.log(`Training started on: ${model.trainingStartedOn}`);
    console.log(`Training completed on: ${model.trainingCompletedOn}`);

    if (model.submodels) {
        for (const submodel of model.submodels) {
            // since the training data is unlabeled, we are unable to return the accuracy of this model
            console.log("We have recognized the following fields");
            for (const key in submodel.fields) {
                const field = submodel.fields[key];
                console.log(`The model found field '${field.name}'`);
            }
        }
    }
    // Training document information
    if (model.trainingDocuments) {
        for (const doc of model.trainingDocuments) {
            console.log(`Document name: ${doc.name}`);
            console.log(`Document status: ${doc.status}`);
            console.log(`Document page count: ${doc.pageCount}`);
            console.log(`Document errors: ${doc.errors}`);
        }
    }
}

trainModelLabels().catch((err) => {
    console.error("The sample encountered an error:", err);
});

Ниже приведены выходные данные для модели, обученной с данными обучения, доступными в пакете SDK для JavaScript. Этот пример результата был усечен для удобства чтения.

training status: creating
training status: ready
Model ID: 789b1b37-4cc3-4e36-8665-9dde68618072
Status: ready
Training started on: Thu Aug 20 2020 20:30:37 GMT-0700 (Pacific Daylight Time)
Training completed on: Thu Aug 20 2020 20:30:43 GMT-0700 (Pacific Daylight Time)
We have recognized the following fields
The model found field 'CompanyAddress'
The model found field 'CompanyName'
The model found field 'CompanyPhoneNumber'
The model found field 'DatedAs'
...
Document name: Form_1.jpg
Document status: succeeded
Document page count: 1
Document errors: undefined
Document name: Form_2.jpg
Document status: succeeded
Document page count: 1
Document errors: undefined
Document name: Form_3.jpg
Document status: succeeded
Document page count: 1
Document errors: undefined
...

анализ документов с помощью пользовательской модели;

В этом разделе показано, как извлекать данные вида "ключ/значение" и другое содержимое из пользовательских шаблонов с помощью обученных на них моделей.

Внимание

Для реализации этого сценария необходимо уже обучить модель, чтобы передать его идентификатор в операцию метода. См. раздел Обучение модели.

Воспользуйтесь методом beginRecognizeCustomFormsFromUrl. Возвращаемое значение — это коллекция RecognizedForm объектов. Существует один объект для каждой страницы в отправленном документе.

async function recognizeCustom() {
    // Model ID from when you trained your model.
    const modelId = "<modelId>";
    const formUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/simple-invoice.png";

    const poller = await client.beginRecognizeCustomForms(modelId, formUrl, {
        onProgress: (state) => { console.log(`status: ${state.status}`); }
    });
    const forms = await poller.pollUntilDone();

    console.log("Forms:");
    for (const form of forms || []) {
        console.log(`${form.formType}, page range: ${form.pageRange}`);
        console.log("Pages:");
        for (const page of form.pages || []) {
            console.log(`Page number: ${page.pageNumber}`);
            console.log("Tables");
            for (const table of page.tables || []) {
                for (const cell of table.cells) {
                    console.log(`cell (${cell.rowIndex},${cell.columnIndex}) ${cell.text}`);
                }
            }
        }

        console.log("Fields:");
        for (const fieldName in form.fields) {
            // each field is of type FormField
            const field = form.fields[fieldName];
            console.log(
                `Field ${fieldName} has value '${field.value}' with a confidence score of ${field.confidence}`
            );
        }
    }
}

recognizeCustom().catch((err) => {
    console.error("The sample encountered an error:", err);
});

Совет

Вы также можете анализировать локальные файлы с помощью методов FormRecognizerClient , таких как beginRecognizeCustomForms.

status: notStarted
status: succeeded
Forms:
custom:form, page range: [object Object]
Pages:
Page number: 1
Tables
cell (0,0) Invoice Number
cell (0,1) Invoice Date
cell (0,2) Invoice Due Date
cell (0,3) Charges
cell (0,5) VAT ID
cell (1,0) 34278587
cell (1,1) 6/18/2017
cell (1,2) 6/24/2017
cell (1,3) $56,651.49
cell (1,5) PT
Fields:
Field Merchant has value 'Invoice For:' with a confidence score of 0.116
Field CompanyPhoneNumber has value '$56,651.49' with a confidence score of 0.249
Field VendorName has value 'Charges' with a confidence score of 0.145
Field CompanyAddress has value '1 Redmond way Suite 6000 Redmond, WA' with a confidence score of 0.258
Field CompanyName has value 'PT' with a confidence score of 0.245
Field Website has value '99243' with a confidence score of 0.114
Field DatedAs has value 'undefined' with a confidence score of undefined
Field Email has value 'undefined' with a confidence score of undefined
Field PhoneNumber has value 'undefined' with a confidence score of undefined
Field PurchaseOrderNumber has value 'undefined' with a confidence score of undefined
Field Quantity has value 'undefined' with a confidence score of undefined
Field Signature has value 'undefined' with a confidence score of undefined
Field Subtotal has value 'undefined' with a confidence score of undefined
Field Tax has value 'undefined' with a confidence score of undefined
Field Total has value 'undefined' with a confidence score of undefined

Управление настраиваемыми моделями.

В этом разделе показано, как управлять пользовательскими моделями, которые хранятся в вашей учетной записи. Приведенный ниже код выполняет все задачи по управлению моделями в одной функции (в качестве примера).

Получение количества моделей

Следующий блок кода получает количество моделей, в настоящее время находящихся в вашей учетной записи.

async function countModels() {
    // First, we see how many custom models we have, and what our limit is
    const accountProperties = await trainingClient.getAccountProperties();
    console.log(
        `Our account has ${accountProperties.customModelCount} custom models, and we can have at most ${accountProperties.customModelLimit} custom models`
    );
}
countModels().catch((err) => {
    console.error("The sample encountered an error:", err);
});

Получение списка моделей в учетной записи

Следующий блок кода предоставляет полный список доступных в учетной записи моделей, в том числе сведения о дате и времени их создания и их текущем состоянии.

async function listModels() {

    // returns an async iteratable iterator that supports paging
    const result = trainingClient.listCustomModels();
    let i = 0;
    for await (const modelInfo of result) {
        console.log(`model ${i++}:`);
        console.log(modelInfo);
    }
}

listModels().catch((err) => {
    console.error("The sample encountered an error:", err);
});

Результат выглядит следующим образом.

model 0:
{
  modelId: '453cc2e6-e3eb-4e9f-aab6-e1ac7b87e09e',
  status: 'invalid',
  trainingStartedOn: 2020-08-20T22:28:52.000Z,
  trainingCompletedOn: 2020-08-20T22:28:53.000Z
}
model 1:
{
  modelId: '628739de-779c-473d-8214-d35c72d3d4f7',
  status: 'ready',
  trainingStartedOn: 2020-08-20T23:16:51.000Z,
  trainingCompletedOn: 2020-08-20T23:16:59.000Z
}
model 2:
{
  modelId: '789b1b37-4cc3-4e36-8665-9dde68618072',
  status: 'ready',
  trainingStartedOn: 2020-08-21T03:30:37.000Z,
  trainingCompletedOn: 2020-08-21T03:30:43.000Z
}
model 3:
{
  modelId: '9d893595-1690-4cf2-a4b1-fbac0fb11909',
  status: 'ready',
  trainingStartedOn: 2020-08-21T03:27:26.000Z,
  trainingCompletedOn: 2020-08-21T03:27:37.000Z
}

Получение списка идентификаторов моделей с разбиением на страницы

Этот блок кода предоставляет список моделей и их идентификаторов с разбиением на страницы.

async function listModelsByPage() {
    // using `byPage()`
    i = 1;
    for await (const response of trainingClient.listCustomModels().byPage()) {
        for (const modelInfo of response.modelList) {
            console.log(`model ${i++}: ${modelInfo.modelId}`);
        }
    }
}
listModelsByPage().catch((err) => {
    console.error("The sample encountered an error:", err);
});

Результат выглядит следующим образом.

model 1: 453cc2e6-e3eb-4e9f-aab6-e1ac7b87e09e
model 2: 628739de-779c-473d-8214-d35c72d3d4f7
model 3: 789b1b37-4cc3-4e36-8665-9dde68618072

Получение модели по идентификатору

Следующая функция принимает идентификатор модели и получает соответствующий объект модели. Эта функция не вызывается по умолчанию.

async function getModel(modelId) {
    // Now we'll get the first custom model in the paged list
    const model = await client.getCustomModel(modelId);
    console.log("--- First Custom Model ---");
    console.log(`Model Id: ${model.modelId}`);
    console.log(`Status: ${model.status}`);
    console.log("Documents used in training:");
    for (const doc of model.trainingDocuments || []) {
        console.log(`- ${doc.name}`);
    }
}

Удаление модели из учетной записи ресурсов

Модель можно удалить из учетной записи ресурсов по ее идентификатору. Эта функция удаляет модель с заданным идентификатором. Эта функция не вызывается по умолчанию.

async function deleteModel(modelId) {
    await client.deleteModel(modelId);
    try {
        const deleted = await client.getCustomModel(modelId);
        console.log(deleted);
    } catch (err) {
        // Expected
        console.log(`Model with id ${modelId} has been deleted`);
    }
}

Результат выглядит следующим образом.

Model with id 789b1b37-4cc3-4e36-8665-9dde68618072 has been deleted

Выполнение приложения

Запустите приложение, выполнив команду node для файла проекта.

node index.js

Очистка ресурсов

Если вы хотите очистить и удалить подписку на службы искусственного интеллекта Azure, можно удалить ресурс или группу ресурсов. При удалении группы ресурсов также удаляются все связанные с ней ресурсы.

Устранение неполадок

При использовании этой библиотеки с помощью приведенной ниже переменной среды можно настроить ведение журналов отладки.

export DEBUG=azure*

Дополнительные сведения о том, как включить журналы, см. в документации к пакету @azure/logger.

Следующие шаги

Для этого проекта вы использовали клиентскую библиотеку JavaScript для аналитики документов для обучения моделей и анализа форм различными способами. Теперь следует изучить советы по созданию лучшего набора данных для обучения и созданию более точных моделей.

Внимание

Этот проект предназначен для REST API Аналитики документов версии 2.1.

Справочная документация | Исходный код библиотеки | Пакет (PyPi) | Примеры

Необходимые компоненты

  • Подписка Azure — создайте бесплатную учетную запись.

  • Python 3.x. Установка Python должна включать pip. Вы можете проверить, установлен ли pip, выполнив команду pip --version в командной строке. Чтобы использовать pip, установите последнюю версию Python.

  • Набор данных для обучения в хранилище BLOB-объектов Azure. Ознакомьтесь со сборкой и обучением пользовательской модели , чтобы ознакомиться с советами и параметрами объединения набора данных для обучения. Для этого проекта можно использовать файлы в папке Train примера набора данных. Скачайте и разархивируйте файл sample_data.zip.

  • Ресурс аналитики документов. Создайте ресурс аналитики документов в портал Azure. Используйте бесплатную ценовую категорию (F0), чтобы опробовать службу, а затем выполните обновление до платного уровня для рабочей среды.

    1. После развертывания ресурса выберите Перейти к ресурсу.
    2. В меню навигации слева выберите "Ключи" и "Конечная точка".
    3. Скопируйте один из ключей и конечной точки для использования далее в этой статье.

    Снимок экрана: расположение ключей и конечной точки на портале Azure.

Настройка среды программирования

Установите клиентную библиотеку и создайте приложение Python.

Установка клиентской библиотеки

  • После установки Python выполните следующую команду, чтобы установить последнюю версию клиентской библиотеки Аналитики документов.

    pip install azure-ai-formrecognizer 
    

Создание приложения Python

  1. Создайте приложение Python с именем form-recognizer.py в редакторе или интегрированной среде разработки.

  2. Импортируйте следующие библиотеки.

    import os
    from azure.core.exceptions import ResourceNotFoundError
    from azure.ai.formrecognizer import FormRecognizerClient
    from azure.ai.formrecognizer import FormTrainingClient
    from azure.core.credentials import AzureKeyCredential
    
  3. Создайте переменные для конечной точки Azure и ключа ресурса.

    endpoint = "PASTE_YOUR_FORM_RECOGNIZER_ENDPOINT_HERE"
    key = "PASTE_YOUR_FORM_RECOGNIZER_SUBSCRIPTION_KEY_HERE"
    

Использование объектной модели

С помощью аналитики документов можно создать два разных типа клиента. Во-первых, form_recognizer_clientслужба запрашивает службу для распознавания полей формы и содержимого. Во-вторых, form_training_clientсоздает пользовательские модели и управляет ими для улучшения распознавания.

form_recognizer_client предоставляет следующие операции:

  • Распознать поля формы и содержимое с помощью пользовательских моделей, обученных для анализа пользовательских форм.
  • Распознать содержимое формы, включая таблицы, строки и слова, без необходимости обучения модели.
  • Распознать общие поля из квитанций с помощью предварительно обученной модели получения в службе аналитики документов.

form_training_client предоставляет операции для:

  • Обучение пользовательских моделей для анализа всех полей и значений, найденных в пользовательских формах. См. раздел "Обучение модели без меток " в этой статье.
  • Обучите пользовательские модели для анализа определенных полей и значений, указанных путем маркировки пользовательских форм. См. статью "Обучение модели с помощью меток " в этой статье.
  • Управление моделями, созданными в вашей учетной записи.
  • Скопируйте пользовательскую модель из одного ресурса аналитики документов в другой.

Примечание.

Модели также можно обучены с помощью графического пользовательского интерфейса, например средства метки аналитики документов.

аутентификация клиента;

Проверка подлинности двух клиентских объектов с помощью определенных ранее переменных подписки. AzureKeyCredential Используйте объект, чтобы при необходимости можно обновить ключ без создания новых клиентских объектов.

form_recognizer_client = FormRecognizerClient(endpoint, AzureKeyCredential(key))
form_training_client = FormTrainingClient(endpoint, AzureKeyCredential(key))

Получение ресурсов для тестирования

Необходимо добавить ссылки на URL-адреса для обучающих и тестовых данных.

  1. Чтобы получить URL-адрес SAS для данных обучения пользовательской модели, перейдите к ресурсу хранилища в портал Azure и выберите контейнеры хранилища>данных.

  2. Перейдите к контейнеру, щелкните правой кнопкой мыши и выберите "Создать SAS".

    Получите SAS для контейнера, а не для самой учетной записи хранения.

  3. Убедитесь, что выбраны разрешения на чтение, запись, удаление и список, а затем выберите "Создать маркер SAS" и URL-адрес.

  4. Скопируйте значение в разделе URL-адреса во временное расположение. Оно должно быть в таком формате: https://<storage account>.blob.core.windows.net/<container name>?<SAS value>.

Используйте образы формы и квитанции, включенные в примеры, которые также доступны на сайте GitHub. Кроме того, можно воспользоваться приведенными выше инструкциями, чтобы получить URL-адрес SAS отдельного документа в хранилище BLOB-объектов.

Примечание.

Во фрагментах кода в этом проекте используются удаленные формы, доступ к которым осуществляется по URL-адресам. Если вы хотите обработать локальные документы, см. соответствующие методы в справочной документации и примерах.

Анализ макета

Аналитика документов позволяет анализировать таблицы, строки и слова в документах без необходимости обучения модели. Дополнительные сведения об извлечении макета см. в модели макета аналитики документов.

Для анализа содержимого файла по указанному URL-адресу используйте метод begin_recognize_content_from_url. Возвращаемое значение — это коллекция FormPage объектов. Существует один объект для каждой страницы в отправленном документе. Приведенный ниже код обрабатывает эти объекты в цикле и выводит извлеченные из документа пары ключей и значений, а также табличные данные.

formUrl = "https://raw.githubusercontent.com/Azure/azure-sdk-for-python/master/sdk/formrecognizer/azure-ai-formrecognizer/tests/sample_forms/forms/Form_1.jpg"

poller = form_recognizer_client.begin_recognize_content_from_url(formUrl)
page = poller.result()

table = page[0].tables[0] # page 1, table 1
print("Table found on page {}:".format(table.page_number))
for cell in table.cells:
    print("Cell text: {}".format(cell.text))
    print("Location: {}".format(cell.bounding_box))
    print("Confidence score: {}\n".format(cell.confidence))

Совет

Кроме того, содержимое из локальных образов можно получить с помощью методов FormRecognizerClient, таких как begin_recognize_content.

Table found on page 1:
Cell text: Invoice Number
Location: [Point(x=0.5075, y=2.8088), Point(x=1.9061, y=2.8088), Point(x=1.9061, y=3.3219), Point(x=0.5075, y=3.3219)]
Confidence score: 1.0

Cell text: Invoice Date
Location: [Point(x=1.9061, y=2.8088), Point(x=3.3074, y=2.8088), Point(x=3.3074, y=3.3219), Point(x=1.9061, y=3.3219)]
Confidence score: 1.0

Cell text: Invoice Due Date
Location: [Point(x=3.3074, y=2.8088), Point(x=4.7074, y=2.8088), Point(x=4.7074, y=3.3219), Point(x=3.3074, y=3.3219)]
Confidence score: 1.0

Cell text: Charges
Location: [Point(x=4.7074, y=2.8088), Point(x=5.386, y=2.8088), Point(x=5.386, y=3.3219), Point(x=4.7074, y=3.3219)]
Confidence score: 1.0
...

анализ квитанций;

В этом разделе показано, как анализировать и извлекать общие поля из квитанций США с помощью предварительно обученной модели получения. Дополнительные сведения об анализе квитанций см. в модели квитанций аналитики документов. Для анализа квитанций по URL-адресу используйте метод begin_recognize_receipts_from_url.

receiptUrl = "https://raw.githubusercontent.com/Azure/azure-sdk-for-python/master/sdk/formrecognizer/azure-ai-formrecognizer/tests/sample_forms/receipt/contoso-receipt.png"

poller = form_recognizer_client.begin_recognize_receipts_from_url(receiptUrl)
result = poller.result()

for receipt in result:
    for name, field in receipt.fields.items():
        if name == "Items":
            print("Receipt Items:")
            for idx, items in enumerate(field.value):
                print("...Item #{}".format(idx + 1))
                for item_name, item in items.value.items():
                    print("......{}: {} has confidence {}".format(item_name, item.value, item.confidence))
        else:
            print("{}: {} has confidence {}".format(name, field.value, field.confidence))

Совет

Кроме того, можно анализировать локальные изображения квитанций с помощью методов FormRecognizerClient, таких как begin_recognize_receipts.

ReceiptType: Itemized has confidence 0.659
MerchantName: Contoso Contoso has confidence 0.516
MerchantAddress: 123 Main Street Redmond, WA 98052 has confidence 0.986
MerchantPhoneNumber: None has confidence 0.99
TransactionDate: 2019-06-10 has confidence 0.985
TransactionTime: 13:59:00 has confidence 0.968
Receipt Items:
...Item #1
......Name: 8GB RAM (Black) has confidence 0.916
......TotalPrice: 999.0 has confidence 0.559
...Item #2
......Quantity: None has confidence 0.858
......Name: SurfacePen has confidence 0.858
......TotalPrice: 99.99 has confidence 0.386
Subtotal: 1098.99 has confidence 0.964
Tax: 104.4 has confidence 0.713
Total: 1203.39 has confidence 0.774

анализ визитных карточек;

В этом разделе показано, как анализировать и извлекать общие поля из английских визитных карточек с помощью предварительно обученной модели. Дополнительные сведения об анализе визитных карточек см. в модели бизнес-карты аналитики документов.

Для анализа визитных карточек по URL-адресу используйте метод begin_recognize_business_cards_from_url.

bcUrl = "https://raw.githubusercontent.com/Azure/azure-sdk-for-python/master/sdk/formrecognizer/azure-ai-formrecognizer/samples/sample_forms/business_cards/business-card-english.jpg"

poller = form_recognizer_client.begin_recognize_business_cards_from_url(bcUrl)
business_cards = poller.result()

for idx, business_card in enumerate(business_cards):
    print("--------Recognizing business card #{}--------".format(idx+1))
    contact_names = business_card.fields.get("ContactNames")
    if contact_names:
        for contact_name in contact_names.value:
            print("Contact First Name: {} has confidence: {}".format(
                contact_name.value["FirstName"].value, contact_name.value["FirstName"].confidence
            ))
            print("Contact Last Name: {} has confidence: {}".format(
                contact_name.value["LastName"].value, contact_name.value["LastName"].confidence
            ))
    company_names = business_card.fields.get("CompanyNames")
    if company_names:
        for company_name in company_names.value:
            print("Company Name: {} has confidence: {}".format(company_name.value, company_name.confidence))
    departments = business_card.fields.get("Departments")
    if departments:
        for department in departments.value:
            print("Department: {} has confidence: {}".format(department.value, department.confidence))
    job_titles = business_card.fields.get("JobTitles")
    if job_titles:
        for job_title in job_titles.value:
            print("Job Title: {} has confidence: {}".format(job_title.value, job_title.confidence))
    emails = business_card.fields.get("Emails")
    if emails:
        for email in emails.value:
            print("Email: {} has confidence: {}".format(email.value, email.confidence))
    websites = business_card.fields.get("Websites")
    if websites:
        for website in websites.value:
            print("Website: {} has confidence: {}".format(website.value, website.confidence))
    addresses = business_card.fields.get("Addresses")
    if addresses:
        for address in addresses.value:
            print("Address: {} has confidence: {}".format(address.value, address.confidence))
    mobile_phones = business_card.fields.get("MobilePhones")
    if mobile_phones:
        for phone in mobile_phones.value:
            print("Mobile phone number: {} has confidence: {}".format(phone.value, phone.confidence))
    faxes = business_card.fields.get("Faxes")
    if faxes:
        for fax in faxes.value:
            print("Fax number: {} has confidence: {}".format(fax.value, fax.confidence))
    work_phones = business_card.fields.get("WorkPhones")
    if work_phones:
        for work_phone in work_phones.value:
            print("Work phone number: {} has confidence: {}".format(work_phone.value, work_phone.confidence))
    other_phones = business_card.fields.get("OtherPhones")
    if other_phones:
        for other_phone in other_phones.value:
            print("Other phone number: {} has confidence: {}".format(other_phone.value, other_phone.confidence))

Совет

Кроме того, можно анализировать локальные изображения визитных карточек с помощью методов FormRecognizerClient, таких как begin_recognize_business_cards.

анализ счетов;

В этом разделе показано, как анализировать и извлекать общие поля из счетов по продажам с помощью предварительно обученной модели. Дополнительные сведения об анализе счетов см. в модели счета аналитики документов.

Для анализа счетов по URL-адресу используйте метод begin_recognize_invoices_from_url.

invoiceUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/simple-invoice.png"

poller = form_recognizer_client.begin_recognize_invoices_from_url(invoiceUrl)
invoices = poller.result()

for idx, invoice in enumerate(invoices):
    print("--------Recognizing invoice #{}--------".format(idx+1))
    vendor_name = invoice.fields.get("VendorName")
    if vendor_name:
        print("Vendor Name: {} has confidence: {}".format(vendor_name.value, vendor_name.confidence))
    vendor_address = invoice.fields.get("VendorAddress")
    if vendor_address:
        print("Vendor Address: {} has confidence: {}".format(vendor_address.value, vendor_address.confidence))
    customer_name = invoice.fields.get("CustomerName")
    if customer_name:
        print("Customer Name: {} has confidence: {}".format(customer_name.value, customer_name.confidence))
    customer_address = invoice.fields.get("CustomerAddress")
    if customer_address:
        print("Customer Address: {} has confidence: {}".format(customer_address.value, customer_address.confidence))
    customer_address_recipient = invoice.fields.get("CustomerAddressRecipient")
    if customer_address_recipient:
        print("Customer Address Recipient: {} has confidence: {}".format(customer_address_recipient.value, customer_address_recipient.confidence))
    invoice_id = invoice.fields.get("InvoiceId")
    if invoice_id:
        print("Invoice Id: {} has confidence: {}".format(invoice_id.value, invoice_id.confidence))
    invoice_date = invoice.fields.get("InvoiceDate")
    if invoice_date:
        print("Invoice Date: {} has confidence: {}".format(invoice_date.value, invoice_date.confidence))
    invoice_total = invoice.fields.get("InvoiceTotal")
    if invoice_total:
        print("Invoice Total: {} has confidence: {}".format(invoice_total.value, invoice_total.confidence))
    due_date = invoice.fields.get("DueDate")
    if due_date:
        print("Due Date: {} has confidence: {}".format(due_date.value, due_date.confidence))

Совет

Кроме того, можно анализировать локальные изображения счетов с помощью методов FormRecognizerClient, таких как begin_recognize_invoices.

Анализ документов, удостоверяющих личность

В этом разделе показано, как анализировать и извлекать ключевые сведения из документов идентификации, выданных правительством, включая паспорта по всему миру и лицензии водителя США, с помощью предварительно созданной модели идентификатора аналитики документов. Дополнительные сведения об анализе документов с идентификаторами см. в модели документов аналитики документов.

Для анализа удостоверений личности по URL-адресу используйте метод begin_recognize_id_documents_from_url.

idURL = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/id-license.jpg"

for idx, id_document in enumerate(id_documents):
    print("--------Recognizing ID document #{}--------".format(idx+1))
    first_name = id_document.fields.get("FirstName")
    if first_name:
        print("First Name: {} has confidence: {}".format(first_name.value, first_name.confidence))
    last_name = id_document.fields.get("LastName")
    if last_name:
        print("Last Name: {} has confidence: {}".format(last_name.value, last_name.confidence))
    document_number = id_document.fields.get("DocumentNumber")
    if document_number:
        print("Document Number: {} has confidence: {}".format(document_number.value, document_number.confidence))
    dob = id_document.fields.get("DateOfBirth")
    if dob:
        print("Date of Birth: {} has confidence: {}".format(dob.value, dob.confidence))
    doe = id_document.fields.get("DateOfExpiration")
    if doe:
        print("Date of Expiration: {} has confidence: {}".format(doe.value, doe.confidence))
    sex = id_document.fields.get("Sex")
    if sex:
        print("Sex: {} has confidence: {}".format(sex.value, sex.confidence))
    address = id_document.fields.get("Address")
    if address:
        print("Address: {} has confidence: {}".format(address.value, address.confidence))
    country_region = id_document.fields.get("CountryRegion")
    if country_region:
        print("Country/Region: {} has confidence: {}".format(country_region.value, country_region.confidence))
    region = id_document.fields.get("Region")
    if region:
        print("Region: {} has confidence: {}".format(region.value, region.confidence))

Совет

Кроме того, можно анализировать изображения документов, удостоверяющих личность, с помощью методов FormRecognizerClient, таких как begin_recognize_identity_documents.

обучение пользовательской модели;

В этом разделе демонстрируется, как обучить модель на основе собственных данных. Обученная модель может выводить структурированные данные, которые включают связи "ключ-значение" в исходном документе. После обучения модели вы можете проверить ее, повторно обучить и, в конечном итоге, применить с целью надежного извлечения данных из нескольких форм в соответствии со своими потребностями.

Примечание.

Вы также можете обучить модели с графическим пользовательским интерфейсом, таким как средство создания меток для аналитики документов.

Обучение моделей без меток

Вы можете обучить свою модель анализировать все поля и значения в ваших формах без необходимости вручную помечать документы, которые вы будете использовать для обучения.

Следующий код использует обучающий клиент с begin_training функцией для обучения модели в заданном наборе документов. Возвращаемый объект CustomFormModel содержит сведения о типах форм, которые может анализировать модель, и полях, которые она способна извлечь из формы каждого типа. Приведенный ниже блок кода выводит эту информацию в консоль.

# To train a model you need an Azure Storage account.
# Use the SAS URL to access your training files.
trainingDataUrl = "PASTE_YOUR_SAS_URL_OF_YOUR_FORM_FOLDER_IN_BLOB_STORAGE_HERE"

poller = form_training_client.begin_training(trainingDataUrl, use_training_labels=False)
model = poller.result()

print("Model ID: {}".format(model.model_id))
print("Status: {}".format(model.status))
print("Training started on: {}".format(model.training_started_on))
print("Training completed on: {}".format(model.training_completed_on))

print("\nRecognized fields:")
for submodel in model.submodels:
    print(
        "The submodel with form type '{}' has recognized the following fields: {}".format(
            submodel.form_type,
            ", ".join(
                [
                    field.label if field.label else name
                    for name, field in submodel.fields.items()
                ]
            ),
        )
    )

# Training result information
for doc in model.training_documents:
    print("Document name: {}".format(doc.name))
    print("Document status: {}".format(doc.status))
    print("Document page count: {}".format(doc.page_count))
    print("Document errors: {}".format(doc.errors))

Это выходные данные для модели, обученной по данным для обучения, доступным в пакете SDK для Python.

Model ID: 628739de-779c-473d-8214-d35c72d3d4f7
Status: ready
Training started on: 2020-08-20 23:16:51+00:00
Training completed on: 2020-08-20 23:16:59+00:00

Recognized fields:
The submodel with form type 'form-0' has recognized the following fields: Additional Notes:, Address:, Company Name:, Company Phone:, Dated As:, Details, Email:, Hero Limited, Name:, Phone:, Purchase Order, Purchase Order #:, Quantity, SUBTOTAL, Seattle, WA 93849 Phone:, Shipped From, Shipped To, TAX, TOTAL, Total, Unit Price, Vendor Name:, Website:
Document name: Form_1.jpg
Document status: succeeded
Document page count: 1
Document errors: []
Document name: Form_2.jpg
Document status: succeeded
Document page count: 1
Document errors: []
Document name: Form_3.jpg
Document status: succeeded
Document page count: 1
Document errors: []
Document name: Form_4.jpg
Document status: succeeded
Document page count: 1
Document errors: []
Document name: Form_5.jpg
Document status: succeeded
Document page count: 1
Document errors: []

Обучение моделей с метками

Модели также можно обучать на документах, которые размечены вручную. В некоторых сценариях обучение по такой схеме приводит к лучшим результатам. Возвращенный CustomFormModel указывает, что поля, которые модель может извлекать, а также ее оценочную точность в каждом поле. Приведенный ниже блок кода выводит эту информацию в консоль.

Внимание

Чтобы производить обучение с метками, в контейнере хранилища BLOB-объектов вместе с документами для обучения должны находиться особые файлы с информацией о метках (<имя_файла>.pdf.labels.json) Средство создания меток аналитики документов предоставляет пользовательский интерфейс для создания этих файлов меток. После их получения можно вызвать функцию begin_training с заданным параметром use_training_labels true.

# To train a model you need an Azure Storage account.
# Use the SAS URL to access your training files.
trainingDataUrl = "PASTE_YOUR_SAS_URL_OF_YOUR_FORM_FOLDER_IN_BLOB_STORAGE_HERE"

poller = form_training_client.begin_training(trainingDataUrl, use_training_labels=True)
model = poller.result()
trained_model_id = model.model_id

print("Model ID: {}".format(trained_model_id))
print("Status: {}".format(model.status))
print("Training started on: {}".format(model.training_started_on))
print("Training completed on: {}".format(model.training_completed_on))

print("\nRecognized fields:")
for submodel in model.submodels:
    print(
        "The submodel with form type '{}' has recognized the following fields: {}".format(
            submodel.form_type,
            ", ".join(
                [
                    field.label if field.label else name
                    for name, field in submodel.fields.items()
                ]
            ),
        )
    )

# Training result information
for doc in model.training_documents:
    print("Document name: {}".format(doc.name))
    print("Document status: {}".format(doc.status))
    print("Document page count: {}".format(doc.page_count))
    print("Document errors: {}".format(doc.errors))

Это выходные данные для модели, обученной по данным для обучения, доступным в пакете SDK для Python.

Model ID: ae636292-0b14-4e26-81a7-a0bfcbaf7c91

Status: ready
Training started on: 2020-08-20 23:20:56+00:00
Training completed on: 2020-08-20 23:20:57+00:00

Recognized fields:
The submodel with form type 'form-ae636292-0b14-4e26-81a7-a0bfcbaf7c91' has recognized the following fields: CompanyAddress, CompanyName, CompanyPhoneNumber, DatedAs, Email, Merchant, PhoneNumber, PurchaseOrderNumber, Quantity, Signature, Subtotal, Tax, Total, VendorName, Website
Document name: Form_1.jpg
Document status: succeeded
Document page count: 1
Document errors: []
Document name: Form_2.jpg
Document status: succeeded
Document page count: 1
Document errors: []
Document name: Form_3.jpg
Document status: succeeded
Document page count: 1
Document errors: []
Document name: Form_4.jpg
Document status: succeeded
Document page count: 1
Document errors: []
Document name: Form_5.jpg
Document status: succeeded
Document page count: 1
Document errors: []

анализ документов с помощью пользовательской модели;

В этом разделе показано, как извлекать данные вида "ключ/значение" и другое содержимое из пользовательских шаблонов с помощью обученных на них моделей.

Внимание

Для реализации этого сценария необходимо уже обучить модель, чтобы передать его идентификатор в операцию метода. См. раздел Обучение модели.

Воспользуйтесь методом begin_recognize_custom_forms_from_url. Возвращаемое значение — это коллекция RecognizedForm объектов. Существует один объект для каждой страницы в отправленном документе. Следующий код выводит в консоль результаты анализа. Он отображает каждое из распознанных полей с соответствующим значением и коэффициентом достоверности.


poller = form_recognizer_client.begin_recognize_custom_forms_from_url(
    model_id=trained_model_id, form_url=formUrl)
result = poller.result()

for recognized_form in result:
    print("Form type: {}".format(recognized_form.form_type))
    for name, field in recognized_form.fields.items():
        print("Field '{}' has label '{}' with value '{}' and a confidence score of {}".format(
            name,
            field.label_data.text if field.label_data else name,
            field.value,
            field.confidence
        ))

Совет

Можно также проанализировать локальные изображения. Изучите информацию о методах класса FormRecognizerClient, например о begin_recognize_custom_forms. Либо просмотрите пример кода на GitHub для сценариев, включающих использование локальных изображений.

Модель из предыдущего примера отображает следующие выходные данные:

Form type: form-ae636292-0b14-4e26-81a7-a0bfcbaf7c91
Field 'Merchant' has label 'Merchant' with value 'Invoice For:' and a confidence score of 0.116
Field 'CompanyAddress' has label 'CompanyAddress' with value '1 Redmond way Suite 6000 Redmond, WA' and a confidence score of 0.258
Field 'Website' has label 'Website' with value '99243' and a confidence score of 0.114
Field 'VendorName' has label 'VendorName' with value 'Charges' and a confidence score of 0.145
Field 'CompanyPhoneNumber' has label 'CompanyPhoneNumber' with value '$56,651.49' and a confidence score of 0.249
Field 'CompanyName' has label 'CompanyName' with value 'PT' and a confidence score of 0.245
Field 'DatedAs' has label 'DatedAs' with value 'None' and a confidence score of None
Field 'Email' has label 'Email' with value 'None' and a confidence score of None
Field 'PhoneNumber' has label 'PhoneNumber' with value 'None' and a confidence score of None
Field 'PurchaseOrderNumber' has label 'PurchaseOrderNumber' with value 'None' and a confidence score of None
Field 'Quantity' has label 'Quantity' with value 'None' and a confidence score of None
Field 'Signature' has label 'Signature' with value 'None' and a confidence score of None
Field 'Subtotal' has label 'Subtotal' with value 'None' and a confidence score of None
Field 'Tax' has label 'Tax' with value 'None' and a confidence score of None
Field 'Total' has label 'Total' with value 'None' and a confidence score of None

Управление настраиваемыми моделями.

В этом разделе показано, как управлять пользовательскими моделями, которые хранятся в вашей учетной записи.

Проверка числа моделей в учетной записи ресурсов FormRecognizer

В следующем блоке кода проверяется количество моделей, сохраненных в учетной записи аналитики документов, и сравнивается с ограничением учетной записи.

account_properties = form_training_client.get_account_properties()
print("Our account has {} custom models, and we can have at most {} custom models".format(
    account_properties.custom_model_count, account_properties.custom_model_limit
))

Результат выглядит следующим образом.

Our account has 5 custom models, and we can have at most 5000 custom models

Вывод списка моделей, которые хранятся в учетной записи ресурсов

Приведенный ниже блок кода выводит в консоль список текущих моделей в вашей учетной записи с подробными сведениями о них. Он также сохраняет ссылку на первую модель.

# Next, we get a paged list of all of our custom models
custom_models = form_training_client.list_custom_models()

print("We have models with the following ids:")

# Let's pull out the first model
first_model = next(custom_models)
print(first_model.model_id)
for model in custom_models:
    print(model.model_id)

Результат выглядит следующим образом.

Это пример выходных данных для тестовой учетной записи.

We have models with the following ids:
453cc2e6-e3eb-4e9f-aab6-e1ac7b87e09e
628739de-779c-473d-8214-d35c72d3d4f7
ae636292-0b14-4e26-81a7-a0bfcbaf7c91
b4b5df77-8538-4ffb-a996-f67158ecd305
c6309148-6b64-4fef-aea0-d39521452699

Получение определенной модели по ее идентификатору

Следующий блок кода получает подробные сведения о модели по ее идентификатору, сохраненному в предыдущем разделе.

custom_model = form_training_client.get_custom_model(model_id=trained_model_id)
print("Model ID: {}".format(custom_model.model_id))
print("Status: {}".format(custom_model.status))
print("Training started on: {}".format(custom_model.training_started_on))
print("Training completed on: {}".format(custom_model.training_completed_on))

Это пример выходных данных для пользовательской модели, созданной в предыдущем примере.

Model ID: ae636292-0b14-4e26-81a7-a0bfcbaf7c91
Status: ready
Training started on: 2020-08-20 23:20:56+00:00
Training completed on: 2020-08-20 23:20:57+00:00

Удаление модели из учетной записи ресурсов

Модель можно удалить из учетной записи ресурсов по ее идентификатору. Этот фрагмент кода удаляет модель, которая использовалась в предыдущем разделе.

form_training_client.delete_model(model_id=custom_model.model_id)

try:
    form_training_client.get_custom_model(model_id=custom_model.model_id)
except ResourceNotFoundError:
    print("Successfully deleted model with id {}".format(custom_model.model_id))

Выполнение приложения

Запустите приложение, выполнив команду python:

python form-recognizer.py

Очистка ресурсов

Если вы хотите очистить и удалить подписку на службы искусственного интеллекта Azure, можно удалить ресурс или группу ресурсов. При удалении группы ресурсов также удаляются все связанные с ней ресурсы.

Устранение неполадок

Эти проблемы могут оказаться полезными при устранении неполадок.

Общие

Клиентская библиотека аналитики документов вызывает исключения, определенные в Azure Core.

Ведение журнала

Эта библиотека использует для ведения журнала соответствующую стандартную библиотеку. Основные сведения о сеансах HTTP, таких как URL-адреса и заголовки, регистрируются на уровне INFO.

С помощью аргумента-ключевого слова logging_enable можно включить в клиенте ведение журнала на уровне отладки (DEBUG), на котором фиксируются сведения о телах запросов и ответов, а также заголовки без изменений:

import sys
import logging
from azure.ai.formrecognizer import FormRecognizerClient
from azure.core.credentials import AzureKeyCredential

# Create a logger for the 'azure' SDK
logger = logging.getLogger('azure')
logger.setLevel(logging.DEBUG)

# Configure a console output
handler = logging.StreamHandler(stream=sys.stdout)
logger.addHandler(handler)

endpoint = "PASTE_YOUR_FORM_RECOGNIZER_ENDPOINT_HERE"
credential = AzureKeyCredential("PASTE_YOUR_FORM_RECOGNIZER_SUBSCRIPTION_KEY_HERE")

# This client will log detailed information about its HTTP sessions, at DEBUG level
form_recognizer_client = FormRecognizerClient(endpoint, credential, logging_enable=True)

Аналогичным образом с помощью параметра logging_enable можно включить подробное журналирование для отдельной операции (даже если этот режим не включен в клиенте):

receiptUrl = "https://raw.githubusercontent.com/Azure/azure-sdk-for-python/master/sdk/formrecognizer/azure-ai-formrecognizer/tests/sample_forms/receipt/contoso-receipt.png"
poller = form_recognizer_client.begin_recognize_receipts_from_url(receiptUrl, logging_enable=True)

Примеры REST на GitHub

Следующие шаги

Для этого проекта вы использовали клиентская библиотека Python для аналитики документов для обучения моделей и анализа форм различными способами. Теперь следует изучить советы по созданию лучшего набора данных для обучения и созданию более точных моделей.

Примечание.

Этот проект предназначен для API аналитики документов Azure версии 2.1 с помощью cURL для выполнения вызовов REST API.

Справочник по REST API | Аналитики документов Azure REST API

Необходимые компоненты

  • Подписка Azure — создайте бесплатную учетную запись.

  • Установленное средство командной строки cURL. Windows 10 и Windows 11 поставляются с копией cURL. В командной строке введите следующую команду cURL. Если отображаются параметры справки, cURL устанавливается в среде Windows.

    curl -help
    

    Если cURL не установлен, его можно получить здесь:

  • PowerShell версии 6.0 и выше или аналогичное приложение командной строки.

  • Набор данных для обучения в хранилище BLOB-объектов Azure. Ознакомьтесь со сборкой и обучением пользовательской модели , чтобы ознакомиться с советами и параметрами объединения набора данных для обучения. Файлы можно использовать в папке Train примера набора данных. Скачайте и разархивируйте файл sample_data.zip.

  • Служба ИИ Azure или ресурс аналитики документов. Создание одной службы или нескольких служб. Используйте бесплатную ценовую категорию (F0), чтобы опробовать службу, а затем выполните обновление до платного уровня для рабочей среды.

  • Ключ и конечная точка из ресурса, создаваемого для подключения приложения к службе аналитики документов Azure.

    1. После развертывания ресурса выберите Перейти к ресурсу.
    2. В меню навигации слева выберите "Ключи" и "Конечная точка".
    3. Скопируйте один из ключей и конечной точки для использования далее в этой статье.

    Снимок экрана: расположение ключей и конечной точки на портале Azure.

  • URL-адрес изображения квитанции. Образец можно использовать.

  • URL-адрес изображения визитной карточки Образец можно использовать.

  • URL-адрес изображения счета-фактуры Пример документа можно использовать.

  • URL-адрес изображения документа, удостоверяющего личность Вы можете использовать пример изображения

Анализ макета

Вы можете использовать аналитику документов для анализа и извлечения таблиц, меток выделения, текста и структуры в документах без необходимости обучения модели. Дополнительные сведения об извлечении макета см. в модели макета аналитики документов.

Перед выполнением команды внесите следующие изменения:

  1. Замените <конечную> точку конечной точкой, полученной подпиской Document Intelligence.
  2. Замените <ключ ключом> , скопированным на предыдущем шаге.
  3. Замените <url-адрес> документа одним из примеров URL-адресов.
curl -v -i POST "https://<endpoint>/formrecognizer/v2.1/layout/analyze" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: <key>" --data-ascii "{​​​​​​​'source': '<your-document-url>'}​​​​​​​​"

Вы получите 202 (Success) ответ, содержащий заголовок только для Operation-Location чтения. Значение этого заголовка содержит resultId запрос, который можно запросить, чтобы получить состояние асинхронной операции и получить результаты с помощью запроса GET с тем же ключом подписки ресурса:

https://cognitiveservice/formrecognizer/v2.1/layout/analyzeResults/<resultId>

В следующем примере такая часть URL-адреса, как строка после analyzeResults/, является идентификатором результата.

https://cognitiveservice/formrecognizer/v2/layout/analyzeResults/54f0b076-4e38-43e5-81bd-b85b8835fdfb

Получение результатов макета

После вызова API анализа макета проанализируйте API результатов анализа, чтобы получить состояние операции и извлеченные данные. Перед выполнением команды внесите следующие изменения:

  1. Замените <конечную> точку конечной точкой, полученной подпиской Document Intelligence.
  2. Замените <ключ ключом> , скопированным на предыдущем шаге.
  3. Замените <resultId> идентификатором результата на предыдущий шаг.
curl -v -X GET "https://<endpoint>/formrecognizer/v2.1/layout/analyzeResults/<resultId>" -H "Ocp-Apim-Subscription-Key: <key>"

Вы получаете 200 (success) ответ с содержимым JSON.

Ознакомьтесь со следующим изображением накладной и его соответствующими выходными данными в формате JSON.

  • Узел "readResults" содержит каждую строку текста с соответствующим расположением ограничивающего прямоугольника на странице.
  • Узел selectionMarks отображает каждую отметку выделения (флажок или переключатель) и состояние selected или unselected.
  • В разделе "pageResults" содержатся извлеченные таблицы. Для каждой таблицы извлекаются текст, строка и индекс столбца, объединение строки и столбца, ограничивающий прямоугольник и т. д.

Фотография документа инструкции проекта Contoso с таблицей.

Выходные данные текста ответа сокращены для простоты. См. полный пример выходных данных на сайте GitHub.

{
    "status": "succeeded",
    "createdDateTime": "2020-08-20T20:40:50Z",
    "lastUpdatedDateTime": "2020-08-20T20:40:55Z",
    "analyzeResult": {
        "version": "2.1.0",
        "readResults": [
            {
                "page": 1,
                "angle": 0,
                "width": 8.5,
                "height": 11,
                "unit": "inch",
                "lines": [
                    {
                        "boundingBox": [
                            0.5826,
                            0.4411,
                            2.3387,
                            0.4411,
                            2.3387,
                            0.7969,
                            0.5826,
                            0.7969
                        ],
                        "text": "Contoso, Ltd.",
                        "words": [
                            {
                                "boundingBox": [
                                    0.5826,
                                    0.4411,
                                    1.744,
                                    0.4411,
                                    1.744,
                                    0.7969,
                                    0.5826,
                                    0.7969
                                ],
                                "text": "Contoso,",
                                "confidence": 1
                            },
                            {
                                "boundingBox": [
                                    1.8448,
                                    0.4446,
                                    2.3387,
                                    0.4446,
                                    2.3387,
                                    0.7631,
                                    1.8448,
                                    0.7631
                                ],
                                "text": "Ltd.",
                                "confidence": 1
                            }
                        ]
                    },
                    ...
                        ]
                    }
                ],
                "selectionMarks": [
                    {
                        "boundingBox": [
                            3.9737,
                            3.7475,
                            4.1693,
                            3.7475,
                            4.1693,
                            3.9428,
                            3.9737,
                            3.9428
                        ],
                        "confidence": 0.989,
                        "state": "selected"
                    },
                    ...
                ]
            }
        ],
        "pageResults": [
            {
                "page": 1,
                "tables": [
                    {
                        "rows": 5,
                        "columns": 5,
                        "cells": [
                            {
                                "rowIndex": 0,
                                "columnIndex": 0,
                                "text": "Training Date",
                                "boundingBox": [
                                    0.5133,
                                    4.2167,
                                    1.7567,
                                    4.2167,
                                    1.7567,
                                    4.4492,
                                    0.5133,
                                    4.4492
                                ],
                                "elements": [
                                    "#/readResults/0/lines/12/words/0",
                                    "#/readResults/0/lines/12/words/1"
                                ]
                            },
                            ...
                        ]
                    },
                    ...
                ]
            }
        ]
    }
}

анализ квитанций;

В этом разделе показано, как анализировать и извлекать общие поля из квитанций США с помощью предварительно обученной модели получения. Дополнительные сведения об анализе квитанций см. в модели квитанций аналитики документов. Чтобы начать анализ квитанции, вызовите API анализа квитанций с помощью команды cURL. Перед выполнением команды внесите следующие изменения:

  1. Замените <конечную> точку конечной точкой, полученной подпиской Document Intelligence.
  2. Замените <URL-адрес> квитанции URL-адресом изображения квитанции.
  3. Замените <ключ ключом>, скопированным на предыдущем шаге.
curl -i -X POST "https://<endpoint>/formrecognizer/v2.1/prebuilt/receipt/analyze" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: <key>" --data-ascii "{ 'source': '<your receipt URL>'}"

Вы получите 202 (Success) ответ, содержащий Operation-Location заголовок. Значение этого заголовка содержит идентификатор результата, который можно использовать для запроса состояния асинхронной операции и получения результатов:

https://cognitiveservice/formrecognizer/v2.1/prebuilt/receipt/analyzeResults/<resultId>

В следующем примере строка после operations/ является идентификатором результата.

https://cognitiveservice/formrecognizer/v2.1/prebuilt/receipt/operations/aeb13e15-555d-4f02-ba47-04d89b487ed5

Получение результатов анализа квитанции

После вызова API анализа квитанций вызовите API получения результатов анализа квитанций, чтобы получить состояние операции и извлеченные данные. Перед выполнением команды внесите следующие изменения:

  1. Замените <конечную точку конечной> точкой, полученной ключом аналитики документов.
  2. Замените <resultId> идентификатором результата на предыдущий шаг.
  3. Замените <ключ ключом> .
curl -X GET "https://<endpoint>/formrecognizer/v2.1/prebuilt/receipt/analyzeResults/<resultId>" -H "Ocp-Apim-Subscription-Key: <key>"

Вы получаете ответ с выходными данными 200 (Success) JSON. В первом поле, "status", указывается состояние операции. Если операция не завершена, значение "status" равно "running" или "notStarted", и необходимо снова вызвать API вручную или через скрипт. Мы рекомендуем установить между вызовами интервал в одну секунду или более.

Узел "readResults" содержит весь распознанный текст, если присвоить необязательному includeTextDetails параметру trueзначение ). Ответ упорядочивает текст по страницам, а затем по строкам, а затем по отдельным словам. Узел "documentResults" содержит обнаруженные моделью значения, зависящие от квитанции. Узел "documentResults" находится в расположении полезных пар "ключ-значение", таких как налог, итог, адрес продавца и т. д.

Ознакомьтесь со следующим изображением квитанции и его соответствующими выходными данными в формате JSON.

На фотографии показана печатная квитанция от Contoso.

Выходные данные текста ответа сокращены для удобства чтения. См. полный пример выходных данных на сайте GitHub.

{
  "status":"succeeded",
  "createdDateTime":"2019-12-17T04:11:24Z",
  "lastUpdatedDateTime":"2019-12-17T04:11:32Z",
  "analyzeResult":{
    "version":"2.1.0",
    "readResults":[
      {
        "page":1,
        "angle":0.6893,
        "width":1688,
        "height":3000,
        "unit":"pixel",
        "language":"en",
        "lines":[
          {
            "text":"Contoso",
            "boundingBox":[
              635,
              510,
              1086,
              461,
              1098,
              558,
              643,
              604
            ],
            "words":[
              {
                "text":"Contoso",
                "boundingBox":[
                  639,
                  510,
                  1087,
                  461,
                  1098,
                  551,
                  646,
                  604
                ],
                "confidence":0.955
              }
            ]
          },
          ...
        ]
      }
    ],
    "documentResults":[
      {
        "docType":"prebuilt:receipt",
        "pageRange":[
          1,
          1
        ],
        "fields":{
          "ReceiptType":{
            "type":"string",
            "valueString":"Itemized",
            "confidence":0.692
          },
          "MerchantName":{
            "type":"string",
            "valueString":"Contoso Contoso",
            "text":"Contoso Contoso",
            "boundingBox":[
              378.2,
              292.4,
              1117.7,
              468.3,
              1035.7,
              812.7,
              296.3,
              636.8
            ],
            "page":1,
            "confidence":0.613,
            "elements":[
              "#/readResults/0/lines/0/words/0",
              "#/readResults/0/lines/1/words/0"
            ]
          },
          "MerchantAddress":{
            "type":"string",
            "valueString":"123 Main Street Redmond, WA 98052",
            "text":"123 Main Street Redmond, WA 98052",
            "boundingBox":[
              302,
              675.8,
              848.1,
              793.7,
              809.9,
              970.4,
              263.9,
              852.5
            ],
            "page":1,
            "confidence":0.99,
            "elements":[
              "#/readResults/0/lines/2/words/0",
              "#/readResults/0/lines/2/words/1",
              "#/readResults/0/lines/2/words/2",
              "#/readResults/0/lines/3/words/0",
              "#/readResults/0/lines/3/words/1",
              "#/readResults/0/lines/3/words/2"
            ]
          },
          "MerchantPhoneNumber":{
            "type":"phoneNumber",
            "valuePhoneNumber":"+19876543210",
            "text":"987-654-3210",
            "boundingBox":[
              278,
              1004,
              656.3,
              1054.7,
              646.8,
              1125.3,
              268.5,
              1074.7
            ],
            "page":1,
            "confidence":0.99,
            "elements":[
              "#/readResults/0/lines/4/words/0"
            ]
          },
          "TransactionDate":{
            "type":"date",
            "valueDate":"2019-06-10",
            "text":"6/10/2019",
            "boundingBox":[
              265.1,
              1228.4,
              525,
              1247,
              518.9,
              1332.1,
              259,
              1313.5
            ],
            "page":1,
            "confidence":0.99,
            "elements":[
              "#/readResults/0/lines/5/words/0"
            ]
          },
          "TransactionTime":{
            "type":"time",
            "valueTime":"13:59:00",
            "text":"13:59",
            "boundingBox":[
              541,
              1248,
              677.3,
              1261.5,
              668.9,
              1346.5,
              532.6,
              1333
            ],
            "page":1,
            "confidence":0.977,
            "elements":[
              "#/readResults/0/lines/5/words/1"
            ]
          },
          "Items":{
            "type":"array",
            "valueArray":[
              {
                "type":"object",
                "valueObject":{
                  "Quantity":{
                    "type":"number",
                    "text":"1",
                    "boundingBox":[
                      245.1,
                      1581.5,
                      300.9,
                      1585.1,
                      295,
                      1676,
                      239.2,
                      1672.4
                    ],
                    "page":1,
                    "confidence":0.92,
                    "elements":[
                      "#/readResults/0/lines/7/words/0"
                    ]
                  },
                  "Name":{
                    "type":"string",
                    "valueString":"Cappuccino",
                    "text":"Cappuccino",
                    "boundingBox":[
                      322,
                      1586,
                      654.2,
                      1601.1,
                      650,
                      1693,
                      317.8,
                      1678
                    ],
                    "page":1,
                    "confidence":0.923,
                    "elements":[
                      "#/readResults/0/lines/7/words/1"
                    ]
                  },
                  "TotalPrice":{
                    "type":"number",
                    "valueNumber":2.2,
                    "text":"$2.20",
                    "boundingBox":[
                      1107.7,
                      1584,
                      1263,
                      1574,
                      1268.3,
                      1656,
                      1113,
                      1666
                    ],
                    "page":1,
                    "confidence":0.918,
                    "elements":[
                      "#/readResults/0/lines/8/words/0"
                    ]
                  }
                }
              },
              ...
            ]
          },
          "Subtotal":{
            "type":"number",
            "valueNumber":11.7,
            "text":"11.70",
            "boundingBox":[
              1146,
              2221,
              1297.3,
              2223,
              1296,
              2319,
              1144.7,
              2317
            ],
            "page":1,
            "confidence":0.955,
            "elements":[
              "#/readResults/0/lines/13/words/1"
            ]
          },
          "Tax":{
            "type":"number",
            "valueNumber":1.17,
            "text":"1.17",
            "boundingBox":[
              1190,
              2359,
              1304,
              2359,
              1304,
              2456,
              1190,
              2456
            ],
            "page":1,
            "confidence":0.979,
            "elements":[
              "#/readResults/0/lines/15/words/1"
            ]
          },
          "Tip":{
            "type":"number",
            "valueNumber":1.63,
            "text":"1.63",
            "boundingBox":[
              1094,
              2479,
              1267.7,
              2485,
              1264,
              2591,
              1090.3,
              2585
            ],
            "page":1,
            "confidence":0.941,
            "elements":[
              "#/readResults/0/lines/17/words/1"
            ]
          },
          "Total":{
            "type":"number",
            "valueNumber":14.5,
            "text":"$14.50",
            "boundingBox":[
              1034.2,
              2617,
              1387.5,
              2638.2,
              1380,
              2763,
              1026.7,
              2741.8
            ],
            "page":1,
            "confidence":0.985,
            "elements":[
              "#/readResults/0/lines/19/words/0"
            ]
          }
        }
      }
    ]
  }
}

анализ визитных карточек;

В этом разделе показано, как анализировать и извлекать общие поля из английских визитных карточек с помощью предварительно обученной модели. Дополнительные сведения об анализе визитных карточек см. в модели бизнес-карты аналитики документов. Чтобы начать анализ визитной карточки, вызовите API анализа визитных карточек с помощью команды cURL. Перед выполнением команды внесите следующие изменения:

  1. Замените <конечную> точку конечной точкой, полученной подпиской Document Intelligence.
  2. Замените <URL-адрес> визитной карточки URL-адресом изображения квитанции.
  3. Замените <ключ ключом> , скопированным на предыдущем шаге.
curl -i -X POST "https://<endpoint>/formrecognizer/v2.1/prebuilt/businessCard/analyze" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: <key>" --data-ascii "{ 'source': '<your receipt URL>'}"

Вы получите 202 (Success) ответ, содержащий заголовок Operation-Location . Значение этого заголовка содержит идентификатор результата, который можно использовать для запроса состояния асинхронной операции и получения результатов:

https://cognitiveservice/formrecognizer/v2.1/prebuilt/businessCard/analyzeResults/<resultId>

В следующем примере такая часть URL-адреса, как строка после analyzeResults/, является идентификатором результата.

https://cognitiveservice/formrecognizer/v2.1/prebuilt/businessCard/analyzeResults/54f0b076-4e38-43e5-81bd-b85b8835fdfb

После вызова API анализа визитных карточек вызовите API результатов анализа визитных карточек, чтобы получить состояние операции и извлеченные данные. Перед выполнением команды внесите следующие изменения:

  1. Замените <конечную точку конечной> точкой, полученной ключом аналитики документов.
  2. Замените <resultId> идентификатором результата на предыдущий шаг.
  3. Замените <ключ ключом> .
curl -v -X GET https://<endpoint>/formrecognizer/v2.1/prebuilt/businessCard/analyzeResults/<resultId>"
-H "Ocp-Apim-Subscription-Key: <key>"

Вы получаете ответ с выходными данными 200 (Success) JSON.

Узел "readResults" содержит весь распознанный текст. Ответ упорядочивает текст по страницам, а затем по строкам, а затем по отдельным словам. Узел "documentResults" содержит обнаруженные моделью значения для конкретной визитной карточки. Узел "documentResults" находится в расположении полезных контактных данных, таких как название компании, имя, фамилия, номер телефона и т. д.

Фотография показывает визитную карточку компании, называемой Contoso.

Эти выходные данные JSON сокращены для удобства чтения. См. полный пример выходных данных на сайте GitHub.

{
    "status": "succeeded",
    "createdDateTime":"2021-02-09T18:14:05Z",
    "lastUpdatedDateTime":"2021-02-09T18:14:10Z",
    "analyzeResult": {
        "version": "2.1.0",
        "readResults": [
            {
             "page":1,
             "angle":-16.6836,
             "width":4032,
             "height":3024,
             "unit":"pixel"
          }
        ],
        "documentResults": [
            {
                "docType": "prebuilt:businesscard",
                "pageRange": [
                    1,
                    1
                ],
                "fields": {
                    "ContactNames": {
                        "type": "array",
                        "valueArray": [
                            {
                                "type": "object",
                                "valueObject": {
                                    "FirstName": {
                                        "type": "string",
                                        "valueString": "Avery",
                                        "text": "Avery",
                                        "boundingBox": [
                                            703,
                                            1096,
                                            1134,
                                            989,
                                            1165,
                                            1109,
                                            733,
                                            1206
                                        ],
                                        "page": 1
                                },
                                "text": "Dr. Avery Smith",
                                "boundingBox": [
                                    419.3,
                                    1154.6,
                                    1589.6,
                                    877.9,
                                    1618.9,
                                    1001.7,
                                    448.6,
                                    1278.4
                                ],
                                "confidence": 0.993
                            }
                        ]
                    },
                    "Emails": {
                        "type": "array",
                        "valueArray": [
                            {
                                "type": "string",
                                "valueString": "[email protected]",
                                "text": "[email protected]",
                                "boundingBox": [
                                    2107,
                                    934,
                                    2917,
                                    696,
                                    2935,
                                    764,
                                    2126,
                                    995
                                ],
                                "page": 1,
                                "confidence": 0.99
                            }
                        ]
                    },
                    "Websites": {
                        "type": "array",
                        "valueArray": [
                            {
                                "type": "string",
                                "valueString": "https://www.contoso.com/",
                                "text": "https://www.contoso.com/",
                                "boundingBox": [
                                    2121,
                                    1002,
                                    2992,
                                    755,
                                    3014,
                                    826,
                                    2143,
                                    1077
                                ],
                                "page": 1,
                                "confidence": 0.995
                            }
                        ]
                    }
                }
            }
        ]
    }
}

Скрипт выводит ответы на консоль до завершения операции анализа визитных карточек.

анализ счетов;

Вы можете использовать аналитику документов для извлечения текста поля и семантических значений из данного документа счета. Чтобы начать анализ счета, используйте команду cURL. Дополнительные сведения об анализе счета см. в статье Служба макета Распознавателя документов. Чтобы начать анализ счета, вызовите API анализа счетов с помощью команды cURL.

Перед выполнением команды внесите следующие изменения:

  1. Замените <конечную> точку конечной точкой, полученной подпиской Document Intelligence.
  2. Замените <URL-адрес> счета URL-адресом документа счета.
  3. Замените <ключ ключом> .
curl -v -i POST https://<endpoint>/formrecognizer/v2.1/prebuilt/invoice/analyze" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: <key>" --data-ascii "{​​​​​​​'source': '<your invoice URL>'}​​​​​​​​"

Вы получите 202 (Success) ответ, содержащий Operation-Location заголовок. Значение этого заголовка содержит идентификатор результата, который можно использовать для запроса состояния асинхронной операции и получения результатов:

https://cognitiveservice/formrecognizer/v2.1/prebuilt/receipt/analyzeResults/<resultId>

В следующем примере такая часть URL-адреса, как строка после analyzeResults/, является идентификатором результата.

https://cognitiveservice/formrecognizer/v2.1/prebuilt/invoice/analyzeResults/54f0b076-4e38-43e5-81bd-b85b8835fdfb

После вызова API анализа счета вызовите API получения результатов анализа счета, чтобы получить состояние операции и извлеченные данные.

Перед выполнением команды внесите следующие изменения:

  1. Замените <конечную точку конечной> точкой, полученной ключом аналитики документов.
  2. Замените <resultId> идентификатором результата на предыдущий шаг.
  3. Замените <ключ ключом> .
curl -v -X GET "https://<endpoint>/formrecognizer/v2.1/prebuilt/invoice/analyzeResults/<resultId>" -H "Ocp-Apim-Subscription-Key: <key>"

Вы получаете ответ с выходными данными 200 (Success) JSON.

  • Поле "readResults" содержит каждую строку текста, извлеченную из счета.
  • "pageResults" включает таблицы и метки выбора, извлеченные из счета.
  • Поле "documentResults" содержит сведения о ключе и значении для наиболее релевантных частей счета.

Ознакомьтесь со следующим счетом-фактурой и его соответствующими выходными данными в формате JSON.

Содержимое json текста ответа сокращено для удобства чтения. См. полный пример выходных данных на сайте GitHub.

{
    "status": "succeeded",
    "createdDateTime": "2020-11-06T23:32:11Z",
    "lastUpdatedDateTime": "2020-11-06T23:32:20Z",
    "analyzeResult": {
        "version": "2.1.0",
        "readResults": [{
            "page": 1,
            "angle": 0,
            "width": 8.5,
            "height": 11,
            "unit": "inch"
        }],
        "pageResults": [{
            "page": 1,
            "tables": [{
                "rows": 3,
                "columns": 4,
                "cells": [{
                    "rowIndex": 0,
                    "columnIndex": 0,
                    "text": "QUANTITY",
                    "boundingBox": [0.4953,
                    5.7306,
                    1.8097,
                    5.7306,
                    1.7942,
                    6.0122,
                    0.4953,
                    6.0122]
                },
                {
                    "rowIndex": 0,
                    "columnIndex": 1,
                    "text": "DESCRIPTION",
                    "boundingBox": [1.8097,
                    5.7306,
                    5.7529,
                    5.7306,
                    5.7452,
                    6.0122,
                    1.7942,
                    6.0122]
                },
                ...
                ],
                "boundingBox": [0.4794,
                5.7132,
                8.0158,
                5.714,
                8.0118,
                6.5627,
                0.4757,
                6.5619]
            },
            {
                "rows": 2,
                "columns": 6,
                "cells": [{
                    "rowIndex": 0,
                    "columnIndex": 0,
                    "text": "SALESPERSON",
                    "boundingBox": [0.4979,
                    4.963,
                    1.8051,
                    4.963,
                    1.7975,
                    5.2398,
                    0.5056,
                    5.2398]
                },
                {
                    "rowIndex": 0,
                    "columnIndex": 1,
                    "text": "P.O. NUMBER",
                    "boundingBox": [1.8051,
                    4.963,
                    3.3047,
                    4.963,
                    3.3124,
                    5.2398,
                    1.7975,
                    5.2398]
                },
                ...
                ],
                "boundingBox": [0.4976,
                4.961,
                7.9959,
                4.9606,
                7.9959,
                5.5204,
                0.4972,
                5.5209]
            }]
        }],
        "documentResults": [{
            "docType": "prebuilt:invoice",
            "pageRange": [1,
            1],
            "fields": {
                "AmountDue": {
                    "type": "number",
                    "valueNumber": 610,
                    "text": "$610.00",
                    "boundingBox": [7.3809,
                    7.8153,
                    7.9167,
                    7.8153,
                    7.9167,
                    7.9591,
                    7.3809,
                    7.9591],
                    "page": 1,
                    "confidence": 0.875
                },
                "BillingAddress": {
                    "type": "string",
                    "valueString": "123 Bill St, Redmond WA, 98052",
                    "text": "123 Bill St, Redmond WA, 98052",
                    "boundingBox": [0.594,
                    4.3724,
                    2.0125,
                    4.3724,
                    2.0125,
                    4.7125,
                    0.594,
                    4.7125],
                    "page": 1,
                    "confidence": 0.997
                },
                "BillingAddressRecipient": {
                    "type": "string",
                    "valueString": "Microsoft Finance",
                    "text": "Microsoft Finance",
                    "boundingBox": [0.594,
                    4.1684,
                    1.7907,
                    4.1684,
                    1.7907,
                    4.2837,
                    0.594,
                    4.2837],
                    "page": 1,
                    "confidence": 0.998
                },
                ...
            }
        }]
    }
}

Анализ документов, удостоверяющих личность

Чтобы начать анализ документа идентификации (идентификатора), используйте команду cURL. Дополнительные сведения об анализе документов с идентификаторами см. в модели документов аналитики документов. Чтобы начать анализ документа с идентификатором, вызовите API документов анализа с помощью команды cURL.

Перед выполнением команды внесите следующие изменения:

  1. Замените <конечную> точку конечной точкой, полученной подпиской Document Intelligence.
  2. Замените <URL-адрес> документа идентификатора URL-адресом изображения квитанции.
  3. Замените <ключ ключом> , скопированным на предыдущем шаге.
curl -i -X POST "https://<endpoint>/formrecognizer/v2.1/prebuilt/idDocument/analyze" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: <key>" --data-ascii "{ 'source': '<your ID document URL>'}"

Вы получите 202 (Success) ответ, содержащий Operation-Location заголовок. Значение этого заголовка содержит идентификатор результата, который можно использовать для запроса состояния асинхронной операции и получения результатов:

https://cognitiveservice/formrecognizer/v2.1/prebuilt/documentId/analyzeResults/<resultId>

В следующем примере строка после analyzeResults/ является идентификатором результата.

https://westus.api.cognitive.microsoft.com/formrecognizer/v2.1/prebuilt/idDocument/analyzeResults/3bc1d6e0-e24c-41d2-8c50-14e9edc336d1

Получение результата анализа документа, удостоверяющего личность

После вызова API документа анализа идентификатора вызовите API результатов анализа идентификаторов, чтобы получить состояние операции и извлеченных данных. Перед выполнением команды внесите следующие изменения:

  1. Замените <конечную точку конечной> точкой, полученной ключом аналитики документов.
  2. Замените <resultId> идентификатором результата на предыдущий шаг.
  3. Замените <ключ ключом> .
curl -X GET "https://<endpoint>/formrecognizer/v2.1/prebuilt/idDocument/analyzeResults/<resultId>" -H "Ocp-Apim-Subscription-Key: <key>"

Вы получаете ответ с выходными данными 200 (Success) JSON. В первом поле, "status", указывается состояние операции. Если операция не завершена, значение "status" равно "running" или "notStarted". Снова вызовите API вручную или через скрипт, пока не получите succeeded это значение. Мы рекомендуем установить между вызовами интервал в одну секунду или более.

  • Поле "readResults" содержит каждую строку текста, извлеченную из удостоверения личности.
  • Поле "documentResults" содержит массив объектов, каждый из которых представляет документ, удостоверяющий личность, обнаруженный во входном документе.

Ниже приведен пример документа идентификатора и его соответствующих выходных данных JSON.

Снимок экрана: пример лицензии водителя.

Вот текст ответа.

{
    "status": "succeeded",
    "createdDateTime": "2021-04-13T17:24:52Z",
    "lastUpdatedDateTime": "2021-04-13T17:24:55Z",
    "analyzeResult": {
      "version": "2.1.0",
      "readResults": [
        {
          "page": 1,
          "angle": -0.2823,
          "width": 450,
          "height": 294,
          "unit": "pixel"
        }
      ],
      "documentResults": [
        {
          "docType": "prebuilt:idDocument:driverLicense",
          "docTypeConfidence": 0.995,
          "pageRange": [
            1,
            1
          ],
          "fields": {
            "Address": {
              "type": "string",
              "valueString": "123 STREET ADDRESS YOUR CITY WA 99999-1234",
              "text": "123 STREET ADDRESS YOUR CITY WA 99999-1234",
              "boundingBox": [
                158,
                151,
                326,
                151,
                326,
                177,
                158,
                177
              ],
              "page": 1,
              "confidence": 0.965
            },
            "CountryRegion": {
              "type": "countryRegion",
              "valueCountryRegion": "USA",
              "confidence": 0.99
            },
            "DateOfBirth": {
              "type": "date",
              "valueDate": "1958-01-06",
              "text": "01/06/1958",
              "boundingBox": [
                187,
                133,
                272,
                132,
                272,
                148,
                187,
                149
              ],
              "page": 1,
              "confidence": 0.99
            },
            "DateOfExpiration": {
              "type": "date",
              "valueDate": "2020-08-12",
              "text": "08/12/2020",
              "boundingBox": [
                332,
                230,
                414,
                228,
                414,
                244,
                332,
                245
              ],
              "page": 1,
              "confidence": 0.99
            },
            "DocumentNumber": {
              "type": "string",
              "valueString": "LICWDLACD5DG",
              "text": "LIC#WDLABCD456DG",
              "boundingBox": [
                162,
                70,
                307,
                68,
                307,
                84,
                163,
                85
              ],
              "page": 1,
              "confidence": 0.99
            },
            "FirstName": {
              "type": "string",
              "valueString": "LIAM R.",
              "text": "LIAM R.",
              "boundingBox": [
                158,
                102,
                216,
                102,
                216,
                116,
                158,
                116
              ],
              "page": 1,
              "confidence": 0.985
            },
            "LastName": {
              "type": "string",
              "valueString": "TALBOT",
              "text": "TALBOT",
              "boundingBox": [
                160,
                86,
                213,
                85,
                213,
                99,
                160,
                100
              ],
              "page": 1,
              "confidence": 0.987
            },
            "Region": {
              "type": "string",
              "valueString": "Washington",
              "confidence": 0.99
            },
            "Sex": {
              "type": "string",
              "valueString": "M",
              "text": "M",
              "boundingBox": [
                226,
                190,
                232,
                190,
                233,
                201,
                226,
                201
              ],
              "page": 1,
              "confidence": 0.99
            }
          }
        }
      ]
    }
  }

обучение пользовательской модели;

Для обучения пользовательской модели требуется набор обучающих данных в большом двоичном объекте служба хранилища Azure. У вас должны быть как минимум пять заполненных форм (PDF-документы и (или) изображения) одного типа и структуры. Ознакомьтесь со сборкой и обучением пользовательской модели , чтобы ознакомиться с советами и параметрами для объединения обучающих данных.

Обучение без помеченных данных является стандартной и более простой операцией. Кроме того, можно заранее пометить некоторые или все обучающие данные вручную. Это более сложный процесс, но он предоставляет более лучшую обученную модель.

Примечание.

Вы также можете обучить модели с графическим пользовательским интерфейсом, таким как средство создания меток для аналитики документов.

Обучение моделей без меток

Чтобы обучить модель аналитики документов с документами в контейнере BLOB-объектов Azure, вызовите API обучения пользовательской модели , выполнив следующую команду cURL. Перед выполнением команды внесите следующие изменения:

  1. Замените <конечную> точку конечной точкой, полученной подпиской Document Intelligence.
  2. Замените <ключ ключом> , скопированным на предыдущем шаге.
  3. Замените <URL-адрес SAS URL-адресом url-адреса> подписанного URL-адреса контейнера хранилища BLOB-объектов Azure.

Чтобы получить URL-адрес SAS для данных обучения пользовательской модели, выполните следующие действия.

  1. Перейдите к ресурсу хранилища в портал Azure и выберите контейнеры хранилища>данных.

  2. Перейдите к контейнеру, щелкните правой кнопкой мыши и выберите "Создать SAS".

    Получите SAS для контейнера, а не для самой учетной записи хранения.

  3. Убедитесь, что выбраны разрешения на чтение, запись, удаление и список, а затем выберите "Создать маркер SAS" и URL-адрес.

  4. Скопируйте значение в разделе URL-адреса во временное расположение. Оно должно быть в таком формате: https://<storage account>.blob.core.windows.net/<container name>?<SAS value>.

Внесите изменения и выполните команду:

curl -i -X POST "https://<endpoint>/formrecognizer/v2.1/custom/models" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: <key>" --data-ascii "{ 'source': '<SAS URL>'}"

Вы получаете 201 (Success) ответ с заголовком Location . Значение этого заголовка содержит идентификатор модели для только что обученной модели, который можно использовать для запроса статуса операции и получения результатов.

https://<endpoint>/formrecognizer/v2.1/custom/models/<modelId>

В следующем примере такая часть URL-адреса, как строка после models/, является идентификатором модели.

https://westus.api.cognitive.microsoft.com/formrecognizer/v2.1/custom/models/77d8ecad-b8c1-427e-ac20-a3fe4af503e9

Обучение моделей с метками

Чтобы производить обучение с метками, в контейнере хранилища BLOB-объектов вместе с документами для обучения должны находиться особые файлы с информацией о метках (<имя_файла>.pdf.labels.json) Средство создания меток аналитики документов предоставляет пользовательский интерфейс для создания этих файлов меток. После их получения вызовите API обучения пользовательской модели с параметром "useLabelFile" , заданным true в тексте JSON.

Перед выполнением команды внесите следующие изменения:

  1. Замените <конечную> точку конечной точкой, полученной подпиской Document Intelligence.
  2. Замените <ключ ключом> , скопированным на предыдущем шаге.
  3. Замените <URL-адрес SAS URL-адресом url-адреса> подписанного URL-адреса контейнера хранилища BLOB-объектов Azure.

Чтобы получить URL-адрес SAS для данных обучения пользовательской модели, выполните следующие действия.

  1. Перейдите к ресурсу хранилища в портал Azure и выберите контейнеры хранилища>данных.1. Перейдите к контейнеру, щелкните правой кнопкой мыши и выберите "Создать SAS".

    Получите SAS для контейнера, а не для самой учетной записи хранения.

  2. Убедитесь, что выбраны разрешения на чтение, запись, удаление и список, а затем выберите "Создать маркер SAS" и URL-адрес.

  3. Скопируйте значение в разделе URL-адреса во временное расположение. Оно должно быть в таком формате: https://<storage account>.blob.core.windows.net/<container name>?<SAS value>.

Внесите изменения и выполните команду:

curl -i -X POST "https://<endpoint>/formrecognizer/v2.1/custom/models" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: <key>" --data-ascii "{ 'source': '<SAS URL>', 'useLabelFile':true}"

Вы получаете 201 (Success) ответ с заголовком Location . Значение этого заголовка содержит идентификатор модели для только что обученной модели, который можно использовать для запроса статуса операции и получения результатов.

https://<endpoint>/formrecognizer/v2.1/custom/models/<modelId>

В следующем примере такая часть URL-адреса, как строка после models/, является идентификатором модели.

https://westus.api.cognitive.microsoft.com/formrecognizer/v2.1/custom/models/62e79d93-78a7-4d18-85be-9540dbb8e792

После запуска операции обучения используйте пользовательскую модель для проверки состояния обучения. Передайте идентификатор модели в этот запрос API, чтобы проверить состояние обучения.

  1. Замените <конечную точку конечной> точкой, полученной ключом аналитики документов.
  2. Замена <ключа ключом>
  3. Замените <идентификатор модели идентификатором> модели, полученным на предыдущем шаге.
curl -X GET "https://<endpoint>/formrecognizer/v2.1/custom/models/<modelId>" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: <key>"

анализ документов с помощью пользовательской модели;

Затем используйте новую обученную модель для анализа документа и извлечения полей и таблиц из него. Вызовите API анализа формы, выполнив следующую команду. Перед выполнением команды внесите следующие изменения:

  1. Замените <конечную точку конечной> точкой, полученной из ключа аналитики документов.
  2. Замените <идентификатор модели идентификатором> модели, полученным в предыдущем разделе.
  3. Замените <URL-адрес SAS URL-адресом> SAS на файл в хранилище Azure. Выполните действия, описанные в разделе "Обучение", но вместо получения URL-адреса SAS для всего контейнера больших двоичных объектов, получите его для определенного файла, который нужно проанализировать.
  4. Замените <ключ ключом> .
curl -v "https://<endpoint>/formrecognizer/v2.1/custom/models/<modelId>/analyze?includeTextDetails=true" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: <key>" -d "{ 'source': '<SAS URL>' } "

Вы получаете 202 (Success) ответ с заголовком Operation-Location . Значение этого заголовка содержит идентификатор результата, используемый для отслеживания результатов операции анализа:

https://cognitiveservice/formrecognizer/v2.1/custom/models/<modelId>/analyzeResults/<resultId>

В следующем примере такая часть URL-адреса, как строка после analyzeResults/, является идентификатором результата.

https://cognitiveservice/formrecognizer/v2/layout/analyzeResults/e175e9db-d920-4c7d-bc44-71d1653cdd06

Сохраните этот идентификатор результатов для следующего шага.

Вызовите API результатов анализа формы, чтобы запросить результаты операции анализа.

  1. Замените <конечную точку конечной> точкой, полученной из ключа аналитики документов.
  2. Замените <идентификатор результата идентификатором> , полученным в предыдущем разделе.
  3. Замените <ключ ключом> .
curl -X GET "https://<endpoint>/formrecognizer/v2.1/custom/models/<modelId>/analyzeResults/<resultId>" -H "Ocp-Apim-Subscription-Key: <key>"

Вы получаете 200 (Success) ответ с текстом JSON в следующем формате. Выходные данные сокращены для простоты. Обратите внимание на поле "status" внизу. Это поле имеет значение "succeeded" при завершении операции анализа. Если операция анализа не завершена, необходимо повторно запросить службу, повторно выполнив команду. Мы рекомендуем установить между вызовами интервал в одну секунду или более.

В пользовательских моделях, обученных без меток, пары "ключ-значение" и таблицы находятся в узле "pageResults" выходных данных JSON. В пользовательских моделях, обученных с добавлением меток, пары "ключ-значение" находятся в узле "documentResults". Если вы также указали извлечение обычного текста с помощью параметра URL-адреса includeTextDetails , "readResults" узел отображает содержимое и позиции всего текста в документе.

Выходные данные JSON сокращены для простоты. См. полный пример выходных данных на сайте GitHub.

{
  "status": "succeeded",
  "createdDateTime": "2020-08-21T01:13:28Z",
  "lastUpdatedDateTime": "2020-08-21T01:13:42Z",
  "analyzeResult": {
    "version": "2.1.0",
    "readResults": [
      {
        "page": 1,
        "angle": 0,
        "width": 8.5,
        "height": 11,
        "unit": "inch",
        "lines": [
          {
            "text": "Project Statement",
            "boundingBox": [
              5.0444,
              0.3613,
              8.0917,
              0.3613,
              8.0917,
              0.6718,
              5.0444,
              0.6718
            ],
            "words": [
              {
                "text": "Project",
                "boundingBox": [
                  5.0444,
                  0.3587,
                  6.2264,
                  0.3587,
                  6.2264,
                  0.708,
                  5.0444,
                  0.708
                ]
              },
              {
                "text": "Statement",
                "boundingBox": [
                  6.3361,
                  0.3635,
                  8.0917,
                  0.3635,
                  8.0917,
                  0.6396,
                  6.3361,
                  0.6396
                ]
              }
            ]
          },
          ...
        ]
      }
    ],
    "pageResults": [
      {
        "page": 1,
        "keyValuePairs": [
          {
            "key": {
              "text": "Date:",
              "boundingBox": [
                6.9833,
                1.0615,
                7.3333,
                1.0615,
                7.3333,
                1.1649,
                6.9833,
                1.1649
              ],
              "elements": [
                "#/readResults/0/lines/2/words/0"
              ]
            },
            "value": {
              "text": "9/10/2020",
              "boundingBox": [
                7.3833,
                1.0802,
                7.925,
                1.0802,
                7.925,
                1.174,
                7.3833,
                1.174
              ],
              "elements": [
                "#/readResults/0/lines/3/words/0"
              ]
            },
            "confidence": 1
          },
          ...
        ],
        "tables": [
          {
            "rows": 5,
            "columns": 5,
            "cells": [
              {
                "text": "Training Date",
                "rowIndex": 0,
                "columnIndex": 0,
                "boundingBox": [
                  0.6944,
                  4.2779,
                  1.5625,
                  4.2779,
                  1.5625,
                  4.4005,
                  0.6944,
                  4.4005
                ],
                "confidence": 1,
                "rowSpan": 1,
                "columnSpan": 1,
                "elements": [
                  "#/readResults/0/lines/15/words/0",
                  "#/readResults/0/lines/15/words/1"
                ],
                "isHeader": true,
                "isFooter": false
              },
              ...
            ]
          }
        ],
        "clusterId": 0
      }
    ],
    "documentResults": [],
    "errors": []
  }
}

Улучшение результатов

Изучите значения "confidence" для каждого результата "ключ — значение" в узле "pageResults". Следует также обратить внимание на оценки достоверности в узле "readResults", который соответствует операции чтения текста. Достоверность результатов чтения не влияет на достоверность результатов извлечения ключа или значения, поэтому следует проверить оба.

  • Если оценка достоверности для операции чтения низка, попробуйте улучшить качество входных документов. Дополнительные сведения см. в разделе "Требования к входным данным".
  • Если оценки достоверности для операции извлечения ключей и значений низкие, убедитесь, что у анализируемых документов и документов в наборе для обучения одинаковый тип. Если внешний вид документов в обучающем наборе отличается, попробуйте рассортировать их по разным папкам и обучить разные модели соответствующим образом.

Оценка достоверности, которую вы используете, зависит от вашего варианта использования, но, как правило, рекомендуется нацеливать оценку на 80 процентов или выше. Для более конфиденциальных случаев, таких как чтение медицинских записей или инструкций по выставлению счетов, рекомендуется оценить 100 процентов.

Управление настраиваемыми моделями.

Используйте API перечисления пользовательских моделей в следующей команде, чтобы получить список всех пользовательских моделей, связанных с вашей подпиской.

  1. Замените <конечную> точку конечной точкой, полученной подпиской Document Intelligence.
  2. Замените <ключ ключом> , скопированным на предыдущем шаге.
curl -v -X GET "https://<endpoint>/formrecognizer/v2.1/custom/models?op=full"
-H "Ocp-Apim-Subscription-Key: <key>"

Вы получаете ответ об успешном выполнении 200 с данными JSON, как показано ниже. Элемент "modelList" содержит все созданные модели и сведения о них.

{
  "summary": {
    "count": 0,
    "limit": 0,
    "lastUpdatedDateTime": "string"
  },
  "modelList": [
    {
      "modelId": "string",
      "status": "creating",
      "createdDateTime": "string",
      "lastUpdatedDateTime": "string"
    }
  ],
  "nextLink": "string"
}

Получение определенной модели

Чтобы получить дополнительные сведения об определенной пользовательской модели, используйте API получения пользовательской модели в следующей команде.

  1. Замените <конечную> точку конечной точкой, полученной подпиской Document Intelligence.
  2. Замените <ключ ключом> , скопированным на предыдущем шаге.
  3. Замените <modelId> идентификатором настраиваемой модели, которую вы хотите найти.
curl -v -X GET "https://<endpoint>/formrecognizer/v2.1/custom/models/<modelId>" -H "Ocp-Apim-Subscription-Key: <key>"

Вы получаете ответ успешного 200 выполнения с данными JSON текста запроса, как показано ниже.

{
  "modelInfo": {
    "modelId": "string",
    "status": "creating",
    "createdDateTime": "string",
    "lastUpdatedDateTime": "string"
  },
  "keys": {
    "clusters": {}
  },
  "trainResult": {
    "trainingDocuments": [
      {
        "documentName": "string",
        "pages": 0,
        "errors": [
          "string"
        ],
        "status": "succeeded"
      }
    ],
    "fields": [
      {
        "fieldName": "string",
        "accuracy": 0.0
      }
    ],
    "averageModelAccuracy": 0.0,
    "errors": [
      {
        "message": "string"
      }
    ]
  }
}

Удаление модели из учетной записи ресурсов

Модель можно удалить из учетной записи ресурсов по ее идентификатору. Эта команда вызывает API удаления пользовательской модели, чтобы удалить модель, используемую, как описано в предыдущем разделе.

  1. Замените <конечную> точку конечной точкой, полученной подпиской Document Intelligence.
  2. Замените <ключ ключом> , скопированным на предыдущем шаге.
  3. Замените <modelId> идентификатором настраиваемой модели, которую вы хотите найти.
curl -v -X DELETE "https://<endpoint>/formrecognizer/v2.1/custom/models/<modelId>" -H "Ocp-Apim-Subscription-Key: <key>"

Вы получаете ответ успешного выполнения, указывающий 204 , что модель помечена для удаления. Артефакты модели удаляются в течение 48 часов.

Следующие шаги

Для этого проекта вы использовали REST API аналитики документов для анализа форм разными способами. Далее ознакомьтесь со справочной документацией, чтобы узнать о API аналитики документов более подробно.