次の方法で共有


Document Intelligence の概要

重要

  • Azure Cognitive Services Form Recognizer が Azure AI ドキュメント インテリジェンスになりました。
  • 一部のプラットフォームでは、まだ名前が更新されていません。
  • ドキュメントで Form Recognizer または Document Intelligence に言及している場合は、同じ Azure サービスを参照しています。

このコンテンツの適用対象: checkmark v4.0 (GA) 以前のバージョン: 青のチェックマーク v3.1 (GA) 青のチェックマーク v3.0 (GA)

  • Azure AI Document Intelligence の最新の安定バージョン v4.0 2024-11-30 (GA) の使用を開始します。

このコンテンツの適用対象: checkmark v3.1 (GA) 以前のバージョン: 青のチェックマーク v3.0 青のチェックマーク v2.1

  • Azure Form Recognizer の最新の GA バージョン (2023-07-31) の使用を開始します。

このコンテンツの適用対象: checkmark v3.0 (GA) 最新バージョン: 青のチェックマーク v3.1 青のチェックマーク v2.1

  • Azure Form Recognizer レガシの最新の GA バージョン (2022-08-31) の使用を開始します。
  • Azure AI Document Intelligence / Form Recognizer は、機械学習を使用してドキュメントからキーと値のペア、テキスト、テーブル、および主要なデータを抽出するクラウドベースの Azure AI サービスです。

  • プログラミング言語の SDK を使用するか、REST API を呼び出すことによって、ドキュメント処理モデルをワークフローとアプリケーションに簡単に統合できます。

  • このクイックスタートのテクノロジを学習している間は、無料サービスを使用することをお勧めします。 無料のページは 1 か月あたり 500 ページに制限されていることに注意してください。

API の機能と開発オプションの詳細については、「概要」ページをご覧ください。

このクイックスタートでは、次の機能を使用して、フォームとドキュメントからデータと値を分析および抽出します。

  • レイアウト モデル—モデルをトレーニングすることなく、ドキュメント内のテーブル、行、単語、およびラジオ ボタンやチェック ボックスなどの選択マークを分析および抽出します。

  • 事前構築済みモデル — 事前構築済みのモデルを使用して、特定のドキュメント タイプから共通フィールドを分析および抽出します。

前提条件

  • Azure AI サービスまたは Document Intelligence リソース。 Azure サブスクリプションを用意できたら、Azure portal で単一サービスまたは Azure AI マルチサービスのリソースを作成し、キーとエンドポイントを取得します。

  • Free 価格レベル (`F0`) を使用してサービスを試用し、後から運用環境用の有料レベルにアップグレードすることができます。

ヒント

1 つのエンドポイント/キーで複数の Azure AI サービスにアクセスする予定の場合は、Azure AI サービス リソースを作成します。 Document Intelligence へのアクセスのみの場合は、Document Intelligence リソースを作成します。 Microsoft Entra 認証を使用する場合は、単一サービス リソースが必要になることに注意してください。

  • リソースがデプロイされたら、 [リソースに移動] を選択します。 アプリケーションを Document Intelligence API に接続するには、作成したリソースのキーとエンドポイントが必要になります。 このクイックスタートで後に示すコードに、自分のキーとエンドポイントを貼り付けます。

    Azure portal のキーとエンドポイントの場所のスクリーンショット。

  • Azure AI サービスまたは Form Recognizer リソース。 Azure サブスクリプションを用意できたら、Azure portal で単一サービスまたは Azure AI マルチサービスのリソースを作成し、キーとエンドポイントを取得します。

  • Free 価格レベル (`F0`) を使用してサービスを試用し、後から運用環境用の有料レベルにアップグレードすることができます。

ヒント

1 つのエンドポイント/キーで複数の Azure AI サービスにアクセスする予定の場合は、Azure AI サービス リソースを作成します。 Form Recognizer アクセスのみの場合は、Form Recognizer リソースを作成します。 Microsoft Entra 認証を使用する場合は、単一サービス リソースが必要になることに注意してください。

  • リソースがデプロイされたら、 [リソースに移動] を選択します。 自分のアプリケーションを Form Recognizer API に接続するには、作成したリソースのキーとエンドポイントが必要になります。 このクイックスタートで後に示すコードに、自分のキーとエンドポイントを貼り付けます。

    Azure portal のキーとエンドポイントの場所のスクリーンショット。

設定

  1. Visual Studio を起動します。

  2. スタート ページで、[新しいプロジェクトの作成] を選択します。

    Visual Studio の開始ページのスクリーンショット。

  3. [新しいプロジェクトの作成] ページで、検索ボックスに「コンソール」と入力します。 [コンソール アプリケーション] テンプレートを選択し、 [次へ] を選択します。

    Visual Studio の [新しいプロジェクトの作成] ページのスクリーンショット。

  1. [新しいプロジェクトの構成] ダイアログ ウィンドウの [プロジェクト名] ボックスに「doc_intel_quickstart」と入力します。 [次へ] を選びます。
  1. [新しいプロジェクトの構成] ダイアログ ウィンドウの [プロジェクト名] ボックスに「form_recognizer_quickstart」と入力します。 [次へ] を選びます。
  1. [追加情報] ダイアログ ウィンドウで、[.NET 8.0 (長期的なサポート)] を選択し、[作成] を選択します。

    Visual Studio の [追加情報] ダイアログ ウィンドウのスクリーンショット。

NuGet を使用してクライアント ライブラリをインストールする

  1. doc_intel_quickstart プロジェクトを右クリックし、[Manage NuGet Packages...] (NuGet パッケージの管理...) を選択します。

    Visual Studio の NuGet プレリリース パッケージの選択ウィンドウのスクリーンショット。

  2. [参照] タブを選択し、「Azure.AI.DocumentIntelligence」と入力します。

  3. [Include prerelease] チェックボックスを選択します。

    Visual Studio のプレリリース NuGet パッケージの選択のスクリーンショット。

  4. ドロップダウン メニューからバージョンを選択し、プロジェクトにパッケージをインストールします。

  1. form_recognizer_quickstart プロジェクトを右クリックし、[NuGet パッケージの管理...] を選択します。

    Visual Studio の NuGet パッケージの検索ウィンドウのスクリーンショット。

  2. [参照] タブを選択し、「Azure.AI.FormRecognizer」と入力します。 ドロップダウン メニューからバージョン 4.1.0 を選択します

    Visual Studio の NuGet Form Recognizer パッケージの選択のスクリーンショット。

  1. form_recognizer_quickstart プロジェクトを右クリックし、[NuGet パッケージの管理...] を選択します。

    Visual Studio の NuGet パッケージ ウィンドウのスクリーンショット。

  2. [参照] タブを選択し、「Azure.AI.FormRecognizer」と入力します。 ドロップダウン メニューからバージョン 4.0.0 を選択します

    Visual Studio の NuGet レガシ パッケージの選択のスクリーンショット。

アプリケーションをビルドする

Document Intelligence サービスとやり取りするには、DocumentIntelligenceClient クラスのインスタンスを作成する必要があります。 これを行うために、Azure portal の key を使用して AzureKeyCredential を作成し、その AzureKeyCredential と Document Intelligence の endpoint を使用して DocumentIntelligenceClient インスタンスを作成します。

Form Recognizer サービスと対話するには、DocumentAnalysisClient クラスのインスタンスを作成する必要があります。 それを行うには、Azure portal から key を使用して AzureKeyCredential を作成し、その AzureKeyCredential と Form Recognizer の endpoint を使用して DocumentAnalysisClient インスタンスを作成します。

注意

  • .NET 6 以降では、console テンプレートを使用する新しいプロジェクトによって、以前のバージョンとは異なる新しいプログラム スタイルが生成されます。
  • この新しい出力では、記述する必要があるコードを簡素化できる最新の C# 機能が使用されています。
  • 新しいバージョンで使用する場合、記述する必要があるのは、`Main` メソッドの本体のみです。 最上位レベルのステートメント、グローバル using ディレクティブ、または暗黙的な using ディレクティブを含める必要はありません。
  • 詳細については、「C# コンソール アプリ テンプレートで最上位レベルのステートメントが生成される」を "参照してください"。
  1. Program.cs ファイルを開きます。

  2. 既存のコード (行 Console.Writeline("Hello World!") を含む) を削除して、次のコード サンプルのいずれかを選択し、アプリケーションの Program.cs ファイルの中にコピーして貼り付けます。

重要

終わったらコードからキーを削除し、公開しないよう注意してください。 運用環境では、Azure Key Vault などの資格情報を格納してアクセスする安全な方法を使用します。 詳しくは、Azure AI サービスのセキュリティを "ご覧ください"。

レイアウト モデル

テキスト、選択マーク、テキスト スタイル、テーブルの構造、そして対応する境界領域の座標をドキュメントから抽出します。

  • この例では、URI で指定されたドキュメント ファイルが必要になります。 このクイックスタートでは、サンプル ドキュメントを使用できます。
  • スクリプトの先頭にある Uri fileUri 変数にファイル URI 値が追加されています。
  • URI で指定されたファイルからレイアウトを抽出するには、StartAnalyzeDocumentFromUri メソッドを使用して prebuilt-layout をモデル ID として渡します。 戻り値は、送信されたドキュメントからのデータを含む AnalyzeResult オブジェクトです。

Program.cs ファイルに次のコード サンプルを追加します。 次のように Azure portal の Document Intelligence インスタンスの値を使用して、キーおよびエンドポイント変数を必ず更新してください。


using Azure;
using Azure.AI.DocumentIntelligence;

//set `<your-endpoint>` and `<your-key>` variables with the values from the Azure portal to create your `AzureKeyCredential` and `DocumentIntelligenceClient` instance
string endpoint = "<your-endpoint>";
string key = "<your-key>";
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/sample-layout.pdf");

AnalyzeDocumentContent content = new AnalyzeDocumentContent()
{
    UrlSource= fileUri
};

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

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)," +
        $" 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}:");
        Console.WriteLine($"    Content: '{line.Content}'");

        Console.Write("    Bounding polygon, with points ordered clockwise:");
        for (int j = 0; j < line.Polygon.Count; j += 2)
        {
            Console.Write($" ({line.Polygon[j]}, {line.Polygon[j + 1]})");
        }

        Console.WriteLine();
    }

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

        Console.WriteLine($"  Selection Mark {i} is {selectionMark.State}.");
        Console.WriteLine($"    State: {selectionMark.State}");

        Console.Write("    Bounding polygon, with points ordered clockwise:");
        for (int j = 0; j < selectionMark.Polygon.Count; j++)
        {
            Console.Write($" ({selectionMark.Polygon[j]}, {selectionMark.Polygon[j + 1]})");
        }

        Console.WriteLine();
    }
}

for (int i = 0; i < result.Paragraphs.Count; i++)
{
    DocumentParagraph paragraph = result.Paragraphs[i];

    Console.WriteLine($"Paragraph {i}:");
    Console.WriteLine($"  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)
        {
            var handwrittenContent = result.Content.Substring(span.Offset, span.Length);
            Console.WriteLine($"  {handwrittenContent}");
        }
    }
}

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}) is a '{cell.Kind}' with content: {cell.Content}");
    }
}

アプリケーションを実行します

アプリケーションにコード サンプルを追加したら、formRecognizer_quickstart の横にある緑色の [スタート] ボタンを選択し、プログラムをビルドして実行するか、F5 キーを押します。

Visual Studio プログラムの実行ボタンのスクリーンショット。

Program.cs ファイルに次のコード サンプルを追加します。 Azure portal の Form Recognizer インスタンスの値を使用して、キーとエンドポイントの各変数を必ず更新してください。

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

//set `<your-endpoint>` and `<your-key>` variables with the values from the Azure portal to create your `AzureKeyCredential` and `DocumentAnalysisClient` instance
string endpoint = "<your-endpoint>";
string key = "<your-key>";
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/sample-layout.pdf");

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 box is:");
        Console.WriteLine($"      Upper left => X: {line.BoundingPolygon[0].X}, Y= {line.BoundingPolygon[0].Y}");
        Console.WriteLine($"      Upper right => X: {line.BoundingPolygon[1].X}, Y= {line.BoundingPolygon[1].Y}");
        Console.WriteLine($"      Lower right => X: {line.BoundingPolygon[2].X}, Y= {line.BoundingPolygon[2].Y}");
        Console.WriteLine($"      Lower left => X: {line.BoundingPolygon[3].X}, Y= {line.BoundingPolygon[3].Y}");
    }

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

        Console.WriteLine($"  Selection Mark {i} is {selectionMark.State}.");
        Console.WriteLine($"    Its bounding box is:");
        Console.WriteLine($"      Upper left => X: {selectionMark.BoundingPolygon[0].X}, Y= {selectionMark.BoundingPolygon[0].Y}");
        Console.WriteLine($"      Upper right => X: {selectionMark.BoundingPolygon[1].X}, Y= {selectionMark.BoundingPolygon[1].Y}");
        Console.WriteLine($"      Lower right => X: {selectionMark.BoundingPolygon[2].X}, Y= {selectionMark.BoundingPolygon[2].Y}");
        Console.WriteLine($"      Lower left => X: {selectionMark.BoundingPolygon[3].X}, Y= {selectionMark.BoundingPolygon[3].Y}");
    }
}

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

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

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

        foreach (DocumentSpan span in style.Spans)
        {
            Console.WriteLine($"  Content: {result.Content.Substring(span.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}'.");
    }
}

アプリケーションを実行します

アプリケーションにコード サンプルを追加したら、formRecognizer_quickstart の横にある緑色の [スタート] ボタンを選択し、プログラムをビルドして実行するか、F5 キーを押します。

Visual Studio プログラムの実行ボタンの場所のスクリーンショット。

レイアウト モデルの出力

予測される出力のスニペットを次に示します。

  Document Page 1 has 69 line(s), 425 word(s), and 15 selection mark(s).
  Line 0 has content: 'UNITED STATES'.
    Its bounding box is:
      Upper left => X: 3.4915, Y= 0.6828
      Upper right => X: 5.0116, Y= 0.6828
      Lower right => X: 5.0116, Y= 0.8265
      Lower left => X: 3.4915, Y= 0.8265
  Line 1 has content: 'SECURITIES AND EXCHANGE COMMISSION'.
    Its bounding box is:
      Upper left => X: 2.1937, Y= 0.9061
      Upper right => X: 6.297, Y= 0.9061
      Lower right => X: 6.297, Y= 1.0498
      Lower left => X: 2.1937, Y= 1.0498

出力全体を表示するには、GitHub 上の Azure サンプル リポジトリにアクセスして、レイアウト モデルの出力を表示します。

Program.cs ファイルに次のコード サンプルを追加します。 Azure portal の Form Recognizer インスタンスの値を使用して、キーとエンドポイントの各変数を必ず更新してください。

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

//set `<your-endpoint>` and `<your-key>` variables with the values from the Azure portal to create your `AzureKeyCredential` and `DocumentAnalysisClient` instance
string endpoint = "<your-endpoint>";
string key = "<your-key>";
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/sample-layout.pdf");

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}'.");
    }
}
Extract the layout of a document from a file stream
To extract the layout from a given file at a file stream, use the AnalyzeDocument method and pass prebuilt-layout as the model ID. The returned value is an AnalyzeResult object containing data about the submitted document.

string filePath = "<filePath>";
using var stream = new FileStream(filePath, FileMode.Open);

AnalyzeDocumentOperation operation = await client.AnalyzeDocumentAsync(WaitUntil.Completed, "prebuilt-layout", stream);
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}'.");
    }
}

アプリケーションを実行します

アプリケーションにコード サンプルを追加したら、formRecognizer_quickstart の横にある緑色の [スタート] ボタンを選択し、プログラムをビルドして実行するか、F5 キーを押します。

Visual Studioプログラムの実行のスクリーンショット。

事前構築済みのモデル

事前構築済みモデルを使用して、特定のドキュメントの種類から一般的なフィールドを分析して抽出します。 この例では、事前構築済み請求書モデルを使用して請求書を分析します。

ヒント

請求書に限らず、複数の事前構築済みモデルから選択できます。各モデルには、独自のサポートされているフィールドのセットが含まれます。 analyze 操作に使用するモデルは、分析するドキュメントの種類によって異なります。 「モデル データの抽出」を参照してください。

  • 事前構築済み請求書モデルを使用して請求書を分析します。 このクイックスタートでは、Microsoft のサンプル請求書ドキュメントを使用できます。
  • Program.cs ファイルの先頭にある Uri invoiceUri 変数にファイル URI 値が追加されています。
  • URI で指定されたファイルを分析するには、StartAnalyzeDocumentFromUri メソッドを使用して prebuilt-invoice をモデル ID として渡します。 戻り値は、送信されたドキュメントからのデータを含む AnalyzeResult オブジェクトです。
  • わかりやすくするために、サービスから返されるキーと値のペアはすべてここには表示されません。 サポートされているフィールドと対応する型の一覧については、請求書の概念に関するページを参照してください。

Program.cs ファイルに次のコード サンプルを追加します。 次のように Azure portal の Document Intelligence インスタンスの値を使用して、キーおよびエンドポイント変数を必ず更新してください。


using Azure;
using Azure.AI.DocumentIntelligence;

//set `<your-endpoint>` and `<your-key>` variables with the values from the Azure portal to create your `AzureKeyCredential` and `DocumentIntelligenceClient` instance
string endpoint = "<your-endpoint>";
string key = "<your-key>";
AzureKeyCredential credential = new AzureKeyCredential(key);
DocumentIntelligenceClient client = new DocumentIntelligenceClient(new Uri(endpoint), credential);

//sample invoice document

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

AnalyzeDocumentContent content = new AnalyzeDocumentContent()
{
    UrlSource = invoiceUri
};

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

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)
        && vendorNameField.Type == DocumentFieldType.String)
    {
        string vendorName = vendorNameField.ValueString;
        Console.WriteLine($"Vendor Name: '{vendorName}', with confidence {vendorNameField.Confidence}");
    }

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

    if (document.Fields.TryGetValue("Items", out DocumentField itemsField)
        && itemsField.Type == DocumentFieldType.Array)
    {
        foreach (DocumentField itemField in itemsField.ValueArray)
        {
            Console.WriteLine("Item:");

            if (itemField.Type == DocumentFieldType.Object)
            {
                IReadOnlyDictionary<string, DocumentField> itemFields = itemField.ValueObject;

                if (itemFields.TryGetValue("Description", out DocumentField itemDescriptionField)
                    && itemDescriptionField.Type == DocumentFieldType.String)
                {
                    string itemDescription = itemDescriptionField.ValueString;
                    Console.WriteLine($"  Description: '{itemDescription}', with confidence {itemDescriptionField.Confidence}");
                }

                if (itemFields.TryGetValue("Amount", out DocumentField itemAmountField)
                    && itemAmountField.Type == DocumentFieldType.Currency)
                {
                    CurrencyValue itemAmount = itemAmountField.ValueCurrency;
                    Console.WriteLine($"  Amount: '{itemAmount.CurrencySymbol}{itemAmount.Amount}', with confidence {itemAmountField.Confidence}");
                }
            }
        }
    }

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

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

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

アプリケーションを実行します

アプリケーションにコード サンプルを追加したら、formRecognizer_quickstart の横にある緑色の [スタート] ボタンを選択し、プログラムをビルドして実行するか、F5 キーを押します。

Visual Studio プログラムの実行ボタンのスクリーンショット。

Program.cs ファイルに次のコード サンプルを追加します。 Azure portal の Form Recognizer インスタンスの値を使用して、キーとエンドポイントの各変数を必ず更新してください。


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

//set `<your-endpoint>` and `<your-key>` variables with the values from the Azure portal to create your `AzureKeyCredential` and `FormRecognizerClient` instance
string endpoint = "<your-endpoint>";
string key = "<your-key>";
AzureKeyCredential credential = new AzureKeyCredential(key);
DocumentAnalysisClient client = new DocumentAnalysisClient(new Uri(endpoint), credential);

//sample invoice document

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

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

アプリケーションを実行します

アプリケーションにコード サンプルを追加したら、formRecognizer_quickstart の横にある緑色の [スタート] ボタンを選択し、プログラムをビルドして実行するか、F5 キーを押します。

Visual Studio プログラムの実行ボタンの場所のスクリーンショット。

事前構築済みモデルの出力

予測される出力のスニペットを次に示します。

  Document 0:
  Vendor Name: 'CONTOSO LTD.', with confidence 0.962
  Customer Name: 'MICROSOFT CORPORATION', with confidence 0.951
  Item:
    Description: 'Test for 23 fields', with confidence 0.899
    Amount: '100', with confidence 0.902
  Sub Total: '100', with confidence 0.979

出力全体を表示するには、GitHub 上の Azure サンプル リポジトリにアクセスして、事前構築済み請求書モデルの出力を表示します。

Program.cs ファイルに次のコード サンプルを追加します。 Azure portal の Form Recognizer インスタンスの値を使用して、キーとエンドポイントの各変数を必ず更新してください。


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

//set `<your-endpoint>` and `<your-key>` variables with the values from the Azure portal to create your `AzureKeyCredential` and `FormRecognizerClient` instance
string endpoint = "<your-endpoint>";
string key = "<your-key>";
AzureKeyCredential credential = new AzureKeyCredential(key);
DocumentAnalysisClient client = new DocumentAnalysisClient(new Uri(endpoint), credential);

//sample invoice document

Uri invoiceUri = new Uri ("https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/sample-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}");
        }
    }
}

アプリケーションを実行します

アプリケーションにコード サンプルを追加したら、formRecognizer_quickstart の横にある緑色の [スタート] ボタンを選択し、プログラムをビルドして実行するか、F5 キーを押します。

Visual Studioプログラムの実行のスクリーンショット。

このクイックスタートでは、次の機能を使用して、フォームとドキュメントからデータと値を分析および抽出します。

  • レイアウト—モデルをトレーニングすることなく、ドキュメント内のテーブル、行、単語、およびラジオ ボタンやチェック ボックスなどの選択マークを分析および抽出します。

  • 事前構築済みの請求書 - 事前トレーニング済みのモデルを使用して、共通フィールドの分析と、特定のドキュメント タイプからの抽出を行います。

前提条件

  • Azure サブスクリプション - 無料アカウントを作成します

  • Visual Studio Code または好みの IDE の最新バージョン。 「Visual Studio Code での Java」を "参照してください"。

    ヒント

    • Visual Studio Code には、Windows および macOS 用の Java 用コーディング パック が用意されています。コーディング パックは、VS Code、Java Development Kit (JDK)、および Microsoft が推奨する拡張機能のコレクションのバンドルです。 コーディング パックを使用して、既存の開発環境を修正できます。
    • VS Code と Java 用のコーディング パックを使用している場合は、Java 用 Gradle 拡張機能をインストールします。
  • Visual Studio Code を使用していない場合、開発環境に次のものがインストールされていることを確認してください。

  • Azure AI サービスまたは Document Intelligence リソース。 Azure サブスクリプションを用意できたら、Azure portal で単一サービスまたはマルチサービスの Document Intelligence リソースを作成し、キーとエンドポイントを取得します。 Free 価格レベル (F0) を使用してサービスを試用し、後から運用環境用の有料レベルにアップグレードすることができます。

    ヒント

    1 つのエンドポイント/キーで複数の Azure AI サービスにアクセスする予定の場合は、Azure AI サービス リソースを作成します。 Document Intelligence へのアクセスのみの場合は、Document Intelligence リソースを作成します。 Microsoft Entra 認証を使用する場合は、単一サービス リソースが必要になることに注意してください。

  • リソースがデプロイされたら、 [リソースに移動] を選択します。 アプリケーションを Document Intelligence API に接続するには、作成したリソースのキーとエンドポイントが必要になります。 後で、コードに自分のキーとエンドポイントを貼り付けます。

    Azure portal のキーとエンドポイントの場所のスクリーンショット。

設定

新しい Gradle プロジェクトを作成する

  1. コンソール ウィンドウ (cmd、PowerShell、Bash など) で、アプリ用の新しいディレクトリを doc-intel-app という名前で作成し、そこに移動します。

    mkdir doc-intel-app && doc-intel-app
    
    mkdir doc-intel-app; cd doc-intel-app
    
  2. 作業ディレクトリから gradle init コマンドを実行します。 このコマンドによって、Gradle 用の重要なビルド ファイルが作成されます。たとえば、実行時にアプリケーションを作成して構成するために使用される build.gradle.kts などです。

    gradle init --type basic
    
  3. DSL を選択するよう求められたら、Kotlin を選択します。

  4. Return または Enter キーを選択して、既定のプロジェクト名 (doc-intel-app) を受け入れます。

  1. コンソール ウィンドウ (cmd、PowerShell、Bash など) で、form-recognize-app という名前のアプリ用に新しいディレクトリを作成し、そこに移動します。

    mkdir form-recognize-app && form-recognize-app
    
    mkdir form-recognize-app; cd form-recognize-app
    
  2. 作業ディレクトリから gradle init コマンドを実行します。 このコマンドによって、Gradle 用の重要なビルド ファイルが作成されます。たとえば、実行時にアプリケーションを作成して構成するために使用される build.gradle.kts などです。

    gradle init --type basic
    
  3. DSL を選択するよう求められたら、Kotlin を選択します。

  4. Return または Enter キーを選択して、既定のプロジェクト名 (form-recognize-app) を受け入れます。

クライアント ライブラリをインストールする

このクイックスタートでは、Gradle 依存関係マネージャーを使用します。 クライアント ライブラリとその他の依存関係マネージャーの情報については、Maven Central Repository を参照してください。

IDE でプロジェクトの build.gradle.kts ファイルを開きます。 次のコードをコピーして貼り付け、必要なプラグインと設定と共に、クライアント ライブラリを 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'

   }

このクイックスタートでは、Gradle 依存関係マネージャーを使用します。 クライアント ライブラリとその他の依存関係マネージャーの情報については、Maven Central Repository を参照してください。

IDE でプロジェクトの build.gradle.kts ファイルを開きます。 次のコードをコピーして貼り付け、必要なプラグインと設定と共に、クライアント ライブラリを implementation ステートメントとして含めます。

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

   }

このクイックスタートでは、Gradle 依存関係マネージャーを使用します。 クライアント ライブラリとその他の依存関係マネージャーの情報については、Maven Central Repository を参照してください。

IDE でプロジェクトの build.gradle.kts ファイルを開きます。 次のコードをコピーして貼り付け、必要なプラグインと設定と共に、クライアント ライブラリを implementation ステートメントとして含めます。

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


   }

Java アプリケーションの作成

Document Intelligence サービスとやり取りするには、DocumentIntelligenceClient クラスのインスタンスを作成する必要があります。 これを行うために、Azure portal の key を使用して AzureKeyCredential を作成し、その AzureKeyCredential と Document Intelligence の endpoint を使用して DocumentIntelligenceClient インスタンスを作成します。

Document Intelligence サービスとやり取りするには、DocumentAnalysisClient クラスのインスタンスを作成する必要があります。 これを行うために、Azure portal の key を使用して AzureKeyCredential を作成し、その AzureKeyCredential と Document Intelligence の endpoint を使用して DocumentAnalysisClient インスタンスを作成します。

  1. doc-intel-app ディレクトリから、次のコマンドを実行します。

    mkdir -p src/main/java
    

    次のディレクトリ構造を作成します。

    Java ディレクトリ構造のスクリーンショット

  1. java ディレクトリに移動して、DocIntelligence.java という名前のファイルを作成します。

    ヒント

    • PowerShell を使用して新しいファイルを作成できます。
    • Shift キーを押しながらフォルダーを右クリックして、プロジェクト ディレクトリで PowerShell ウィンドウを開きます。
    • New-Item DocIntelligence.java コマンドを入力します。
  2. DocIntelligence.java ファイルを開きます。 次のコード サンプルのいずれかをコピーして、アプリケーションに貼り付けます。

  1. java ディレクトリに移動して、FormRecognizer.java という名前のファイルを作成します。

    ヒント

    • PowerShell を使用して新しいファイルを作成できます。
    • Shift キーを押しながらフォルダーを右クリックして、プロジェクト ディレクトリで PowerShell ウィンドウを開きます。
    • コマンド New-Item FormRecognizer.java をタイプします。
  2. FormRecognizer.java ファイルを開きます。 次のコード サンプルのいずれかをコピーして、アプリケーションに貼り付けます。

重要

終わったらコードからキーを削除し、公開しないよう注意してください。 運用環境では、Azure Key Vault などの資格情報を格納してアクセスする安全な方法を使用します。 詳しくは、Azure AI サービスのセキュリティを "ご覧ください"。

レイアウト モデル

テキスト、選択マーク、テキスト スタイル、テーブルの構造、そして対応する境界領域の座標をドキュメントから抽出します。

  • この例では、URI にドキュメント ファイルが必要になります。 このクイックスタートでは、サンプル ドキュメントを使用できます。
  • URI で特定のファイルを分析するには、beginAnalyzeDocumentFromUrl メソッドを使用して、モデル ID として prebuilt-layout を渡します。返される値は、送信されたドキュメントに関するデータを含む AnalyzeResult オブジェクトです。
  • Main メソッドの documentUrl 変数にファイル URI 値を追加してあります。

次のコード サンプルを DocIntelligence.java ファイルに追加します。 次のように Azure portal の Document Intelligence インスタンスの値を使用して、キーおよびエンドポイント変数を必ず更新してください。


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.DocumentTable;
import com.azure.core.credential.AzureKeyCredential;
import com.azure.core.util.polling.SyncPoller;

import java.util.List;

public class DocIntelligence {

  // set `<your-endpoint>` and `<your-key>` variables with the values from the Azure portal
  private static final String endpoint = "<your-endpoint>";
  private static final String key = "<your-key>";

  public static void main(String[] args) {

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

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

    SyncPoller <AnalyzeResultOperation, AnalyzeResultOperation> analyzeLayoutPoller =
      client.beginAnalyzeDocument(modelId,
          null,
          null,
          null,
          null,
          null,
          null,
          new AnalyzeDocumentRequest().setUrlSource(documentUrl));

    AnalyzeResult analyzeLayoutResult = analyzeLayoutPoller.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.getPolygon()));

      // 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.getState().toString(),
          documentSelectionMark.getPolygon(),
          documentSelectionMark.getConfidence()));
    });

    // tables
    List < DocumentTable > tables = analyzeLayoutResult.getTables();
    for (int i = 0; i < tables.size(); i++) {
      DocumentTable documentTable = tables.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();
    }

    // styles
    analyzeLayoutResult.getStyles().forEach(documentStyle -
      > System.out.printf("Document is handwritten %s.%n", documentStyle.isHandwritten()));
  }
}

アプリケーションの構築と実行

アプリケーションにコード サンプルを追加したら、メイン プロジェクト ディレクトリ (doc-intel-app) に戻ります。

  1. build コマンドを使用してアプリケーションをビルドします。

    gradle build
    
  2. run コマンドを使用してアプリケーションを実行します。

    gradle run
    

次のコード サンプルを FormRecognizer.java ファイルに追加します。 次のように Azure portal の Document Intelligence インスタンスの値を使用して、キーおよびエンドポイント変数を必ず更新してください。


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 {

  // set `<your-endpoint>` and `<your-key>` variables with the values from the Azure portal
  private static final String endpoint = "<your-endpoint>";
  private static final String key = "<your-key>";

  public static void main(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/sample-layout.pdf";
    String modelId = "prebuilt-layout";

    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()));

      // 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.getState().toString(),
          documentSelectionMark.getBoundingPolygon().toString(),
          documentSelectionMark.getConfidence()));
    });

    // tables
    List < DocumentTable > tables = analyzeLayoutResult.getTables();
    for (int i = 0; i < tables.size(); i++) {
      DocumentTable documentTable = tables.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();
    }
  }
  // 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(", "));
  }
}

アプリケーションの構築と実行

アプリケーションにコード サンプルを追加したら、メイン プロジェクト ディレクトリ (form-recognize-app) に戻ります。

  1. build コマンドを使用してアプリケーションをビルドします。

    gradle build
    
  2. run コマンドを使用してアプリケーションを実行します。

    gradle run
    

レイアウト モデルの出力

予測される出力のスニペットを次に示します。

  Table 0 has 5 rows and 3 columns.
  Cell 'Title of each class', has row index 0 and column index 0.
  Cell 'Trading Symbol', has row index 0 and column index 1.
  Cell 'Name of exchange on which registered', has row index 0 and column index 2.
  Cell 'Common stock, $0.00000625 par value per share', has row index 1 and column index 0.
  Cell 'MSFT', has row index 1 and column index 1.
  Cell 'NASDAQ', has row index 1 and column index 2.
  Cell '2.125% Notes due 2021', has row index 2 and column index 0.
  Cell 'MSFT', has row index 2 and column index 1.
  Cell 'NASDAQ', has row index 2 and column index 2.
  Cell '3.125% Notes due 2028', has row index 3 and column index 0.
  Cell 'MSFT', has row index 3 and column index 1.
  Cell 'NASDAQ', has row index 3 and column index 2.
  Cell '2.625% Notes due 2033', has row index 4 and column index 0.
  Cell 'MSFT', has row index 4 and column index 1.
  Cell 'NASDAQ', has row index 4 and column index 2.

出力全体を表示するには、GitHub 上の Azure サンプル リポジトリにアクセスして、レイアウト モデルの出力を表示します。

次のコード サンプルを FormRecognizer.java ファイルに追加します。 次のように Azure portal の Document Intelligence インスタンスの値を使用して、キーおよびエンドポイント変数を必ず更新してください。


import com.azure.ai.formrecognizer.documentanalysis.DocumentAnalysisClient;
import com.azure.ai.formrecognizer.documentanalysis.DocumentAnalysisClientBuilder;
import com.azure.ai.formrecognizer.documentanalysis.models.AnalyzeResult;
import com.azure.ai.formrecognizer.documentanalysis.models.OperationResult;
import com.azure.ai.formrecognizer.documentanalysis.models.DocumentTable;
import com.azure.ai.formrecognizer.documentanalysis.models.Point;
import com.azure.core.credential.AzureKeyCredential;
import com.azure.core.util.polling.SyncPoller;

import java.util.List;
import java.util.stream.Collectors;

public class FormRecognizer {

  // set `<your-endpoint>` and `<your-key>` variables with the values from the Azure portal
  private static final String endpoint = "<your-endpoint>";
  private static final String key = "<your-key>";

  public static void main(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/sample-layout.pdf";
    String modelId = "prebuilt-layout";

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

    AnalyzeResult analyzeLayoutResult = analyzeLayoutPoller.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(),
          getBoundingCoordinates(documentLine.getBoundingPolygon())));

      // 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 documentTable = tables.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();
    }

    // styles
    analyzeLayoutResult.getStyles().forEach(documentStyle -
      > System.out.printf("Document is handwritten %s.%n", documentStyle.isHandwritten()));
  }

  /**
   * 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(", "));
  }
}

アプリケーションの構築と実行

アプリケーションにコード サンプルを追加したら、メイン プロジェクト ディレクトリ (form-recognize-app) に戻ります。

  1. build コマンドを使用してアプリケーションをビルドします。

    gradle build
    
  2. run コマンドを使用してアプリケーションを実行します。

    gradle run
    

事前構築済みのモデル

事前構築済みモデルを使用して、特定のドキュメントの種類から一般的なフィールドを分析して抽出します。 この例では、事前構築済み請求書モデルを使用して請求書を分析します。

ヒント

請求書に限らず、複数の事前構築済みモデルから選択できます。各モデルには、独自のサポートされているフィールドのセットが含まれます。 analyze 操作に使用するモデルは、分析するドキュメントの種類によって異なります。 「モデル データの抽出」を参照してください。

  • 事前構築済み請求書モデルを使用して請求書を分析します。 このクイックスタートでは、Microsoft のサンプル請求書ドキュメントを使用できます。
  • ファイルの先頭にある invoiceUrl 変数にファイル URL 値が追加されています。
  • URI で特定のファイルを分析するには、beginAnalyzeDocuments メソッドを使用して、モデル ID として PrebuiltModels.Invoice を渡します。返される値は、送信されたドキュメントに関するデータを含む result オブジェクトです。
  • わかりやすくするために、サービスから返されるキーと値のペアはすべてここには表示されません。 サポートされているフィールドと対応する型の一覧については、請求書の概念に関するページを参照してください。

次のコード サンプルを DocIntelligence.java ファイルに追加します。 次のように Azure portal の Document Intelligence インスタンスの値を使用して、キーおよびエンドポイント変数を必ず更新してください。


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 {

  // set `<your-endpoint>` and `<your-key>` variables with the values from the Azure portal
  private static final String endpoint = "<your-endpoint>";
  private static final String key = "<your-key>";

  public static void main(String[] args) {

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

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

      // Instantiate a client that will be used to call the service.
      DocumentIntelligenceClient client = new DocumentIntelligenceClientBuilder()
        .credential(new AzureKeyCredential(key))
        .endpoint(endpoint)
        .buildClient();

      SyncPoller<AnalyzeResultOperation, AnalyzeResultOperation > analyzeInvoicesPoller =
        client.beginAnalyzeDocument(modelId, 
            null,
            null,
            null,
            null,
            null,
            null,
            new AnalyzeDocumentRequest().setUrlSource(invoiceUrl));

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

      for (int i = 0; i < analyzeInvoiceResult.getDocuments().size(); i++) {
        Document 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.getValueString();
            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.getValueString();
            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.getValueString();
            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.getValueString();
            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.getValueString();
            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.getValueDate();
            System.out.printf("Invoice Date: %s, confidence: %.2f%n",
              invoiceDate, invoiceDateField.getConfidence());
          }
        }

        DocumentField invoiceTotalField = invoiceFields.get("InvoiceTotal");
        if (customerAddressRecipientField != null) {
          if (DocumentFieldType.NUMBER == invoiceTotalField.getType()) {
            Double invoiceTotal = invoiceTotalField.getValueNumber();
            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.ARRAY == invoiceItemsField.getType()) {
            List < DocumentField > invoiceItems = invoiceItemsField.getValueArray();
            invoiceItems.stream()
              .filter(invoiceItem -> DocumentFieldType.OBJECT == invoiceItem.getType())
              .map(documentField -> documentField.getValueObject())
              .forEach(documentFieldMap -> documentFieldMap.forEach((key, documentField) -> {

                // See a full list of fields found on an invoice here:
                // https://aka.ms/documentintelligence/invoicefields

                if ("Description".equals(key)) {
                  if (DocumentFieldType.STRING == documentField.getType()) {
                    String name = documentField.getValueString();
                    System.out.printf("Description: %s, confidence: %.2fs%n",
                      name, documentField.getConfidence());
                  }
                }
                if ("Quantity".equals(key)) {
                  if (DocumentFieldType.NUMBER == documentField.getType()) {
                    Double quantity = documentField.getValueNumber();
                    System.out.printf("Quantity: %f, confidence: %.2f%n",
                      quantity, documentField.getConfidence());
                  }
                }
                if ("UnitPrice".equals(key)) {
                  if (DocumentFieldType.NUMBER == documentField.getType()) {
                    Double unitPrice = documentField.getValueNumber();
                    System.out.printf("Unit Price: %f, confidence: %.2f%n",
                      unitPrice, documentField.getConfidence());
                  }
                }
                if ("ProductCode".equals(key)) {
                  if (DocumentFieldType.NUMBER == documentField.getType()) {
                    Double productCode = documentField.getValueNumber();
                    System.out.printf("Product Code: %f, confidence: %.2f%n",
                      productCode, documentField.getConfidence());
                  }
                }
              }));
          }
        }
      }
    }
  }
}

アプリケーションの構築と実行

アプリケーションにコード サンプルを追加したら、メイン プロジェクト ディレクトリ (doc-intel-app) に戻ります。

  1. build コマンドを使用してアプリケーションをビルドします。

    gradle build
    
  2. run コマンドを使用してアプリケーションを実行します。

    gradle run
    

次のコード サンプルを FormRecognizer.java ファイルに追加します。 次のように Azure portal の Document Intelligence インスタンスの値を使用して、キーおよびエンドポイント変数を必ず更新してください。


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 {

  // set `<your-endpoint>` and `<your-key>` variables with the values from the Azure portal
  private static final String endpoint = "<your-endpoint>";
  private static final String key = "<your-key>";

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

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

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

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

    AnalyzeResult analyzeInvoiceResult = analyzeInvoicePoller.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) -> {

              // See a full list of fields found on an invoice here:
              // https://aka.ms/formrecognizer/invoicefields

              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());
                }
              }
            }));
        }
      }
    }
  }
}

アプリケーションの構築と実行

アプリケーションにコード サンプルを追加したら、メイン プロジェクト ディレクトリ (doc-intel-app) に戻ります。

  1. build コマンドを使用してアプリケーションをビルドします。

    gradle build
    
  2. run コマンドを使用してアプリケーションを実行します。

    gradle run
    

事前構築済みモデルの出力

予測される出力のスニペットを次に示します。

  ----------- Analyzing invoice  0 -----------
  Analyzed document has doc type invoice with confidence : 1.00
  Vendor Name: CONTOSO LTD., confidence: 0.92
  Vendor address: 123 456th St New York, NY, 10001, confidence: 0.91
  Customer Name: MICROSOFT CORPORATION, confidence: 0.84
  Customer Address Recipient: Microsoft Corp, confidence: 0.92
  Invoice ID: INV-100, confidence: 0.97
  Invoice Date: 2019-11-15, confidence: 0.97

出力全体を表示するには、GitHub 上の Azure サンプル リポジトリにアクセスして、事前構築済み請求書モデルの出力を表示します。

次のコード サンプルを FormRecognizer.java ファイルに追加します。 次のように Azure portal の Document Intelligence インスタンスの値を使用して、キーおよびエンドポイント変数を必ず更新してください。


import com.azure.ai.formrecognizer.documentanalysis.DocumentAnalysisClient;
import com.azure.ai.formrecognizer.documentanalysis.DocumentAnalysisClientBuilder;
import com.azure.ai.formrecognizer.documentanalysis.models.AnalyzeResult;
import com.azure.ai.formrecognizer.documentanalysis.models.AnalyzedDocument;
import com.azure.ai.formrecognizer.documentanalysis.models.DocumentField;
import com.azure.ai.formrecognizer.documentanalysis.models.DocumentFieldType;
import com.azure.ai.formrecognizer.documentanalysis.models.OperationResult;
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 FormRecognizer {

  // set `<your-endpoint>` and `<your-key>` variables with the values from the Azure portal
  private static final String endpoint = "<your-endpoint>";
  private static final String key = "<your-key>";

  public static void main(String[] args) {

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

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

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

    AnalyzeResult analyzeInvoiceResult = analyzeInvoicePoller.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) -> {

              // See a full list of fields found on an invoice here:
              // https://aka.ms/formrecognizer/invoicefields

              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());
                }
              }
            }));
        }
      }
    }
  }
}

アプリケーションの構築と実行

アプリケーションにコード サンプルを追加したら、メイン プロジェクト ディレクトリ (doc-intel-app) に戻ります。

  1. build コマンドを使用してアプリケーションをビルドします。

    gradle build
    
  2. run コマンドを使用してアプリケーションを実行します。

    gradle run
    

このクイックスタートでは、次の機能を使用して、フォームとドキュメントからデータと値を分析および抽出します。

  • レイアウト—モデルをトレーニングすることなく、ドキュメント内のテーブル、行、単語、およびラジオ ボタンやチェック ボックスなどの選択マークを分析および抽出します。

  • 事前構築済みの請求書 - 事前トレーニング済みの請求書モデルを使用して、共通フィールドの分析と、特定のドキュメント タイプからの抽出を行います。

前提条件

  • Azure サブスクリプション - 無料アカウントを作成します

  • Visual Studio Code または好みの IDE の最新バージョン。 詳細については、「Visual Studio Code での Node.js」を "参照してください"。

  • 最新 LTS バージョンの Node.js

  • Azure AI サービスまたは Document Intelligence リソース。 Azure サブスクリプションを用意できたら、Azure portal で単一サービスまたはマルチサービスの Document Intelligence リソースを作成し、キーとエンドポイントを取得します。 Free 価格レベル (F0) を使用してサービスを試用し、後から運用環境用の有料レベルにアップグレードすることができます。

    ヒント

    1 つのエンドポイント/キーで複数の Azure AI サービスにアクセスする予定の場合は、Azure AI サービス リソースを作成します。 Document Intelligence へのアクセスのみの場合は、Document Intelligence リソースを作成します。 Microsoft Entra 認証を使用する場合は、単一サービス リソースが必要になることに注意してください。

  • リソースがデプロイされたら、 [リソースに移動] を選択します。 アプリケーションを Document Intelligence API に接続するには、作成したリソースのキーとエンドポイントが必要になります。 このクイックスタートで後に示すコードに、自分のキーとエンドポイントを貼り付けます。

    Azure portal のキーとエンドポイントの場所のスクリーンショット。

設定

  1. Node.js Express 新規アプリケーションを作成: コンソール ウィンドウ (cmd、PowerShell、Bash など) で、doc-intel-app というご利用のアプリ用に新しいディレクトリを作成し、そこに移動します。

    mkdir doc-intel-app && cd doc-intel-app
    
  2. npm init コマンドを実行して、アプリケーションを初期化し、プロジェクトをスキャフォールディングします。

    npm init
    
  3. ターミナルに表示されるプロンプトを使用して、プロジェクトの属性を指定します。

    • 最も重要な属性は、名前、バージョン番号、およびエントリ ポイントです。
    • エントリ ポイント名は index.js を保持することをお勧めします。 説明、テスト コマンド、GitHub リポジトリ、キーワード、作成者、ライセンス情報はオプションの属性であり、このプロジェクトでは省略可能です。
    • [戻る] または Enter キーを押して、かっこで囲んだ候補を受け入れます。
    • 画面の指示に従って入力すると、doc-intel-app ディレクトリに package.json ファイルが作成されます。
  1. ai-document-intelligence クライアント ライブラリと azure/identity npm パッケージをインストールします。

    npm i @azure-rest/ai-document-intelligence@1.0.0-beta.3 @azure/core-auth
    

    アプリの package.json ファイルが依存関係によって更新されます。

  1. ai-form-recognizer クライアント ライブラリと azure/identity npm パッケージをインストールします。

    npm i @azure/ai-form-recognizer@5.0.0 @azure/identity
    
    • アプリの package.json ファイルが依存関係によって更新されます。
  1. ai-form-recognizer クライアント ライブラリと azure/identity npm パッケージをインストールします。

    npm i @azure/ai-form-recognizer@4.0.0 @azure/identity
    
  1. index.js というファイルをアプリケーション ディレクトリ内に作成します。

    ヒント

    • PowerShell を使用して新しいファイルを作成できます。
    • Shift キーを押しながらフォルダーを右クリックして、プロジェクト ディレクトリで PowerShell ウィンドウを開きます。
    • 次のコマンド New-Item index.js を入力します。

アプリケーションをビルドする

Document Intelligence サービスとやり取りするには、DocumentIntelligenceClient クラスのインスタンスを作成する必要があります。 これを行うために、Azure portal の key を使用して AzureKeyCredential を作成し、その AzureKeyCredential と Document Intelligence の endpoint を使用して DocumentIntelligenceClient インスタンスを作成します。

Document Intelligence サービスとやり取りするには、DocumentAnalysisClient クラスのインスタンスを作成する必要があります。 それを行うには、Azure portal から key を使用して AzureKeyCredential を作成し、その AzureKeyCredential と Form Recognizer の endpoint を使用して DocumentAnalysisClient インスタンスを作成します。

  1. Visual Studio Code または任意の IDE で index.js ファイルを開きます。 次のコード サンプルのいずれかをコピーして、アプリケーションに貼り付けます。

重要

終わったらコードからキーを削除し、公開しないよう注意してください。 運用環境では、Azure Key Vault などの資格情報を格納してアクセスする安全な方法を使用します。 詳しくは、Azure AI サービスのセキュリティを "ご覧ください"。

レイアウト モデル

テキスト、選択マーク、テキスト スタイル、テーブルの構造、そして対応する境界領域の座標をドキュメントから抽出します。

  • この例では、URL で指定されたドキュメント ファイルが必要になります。 このクイックスタートでは、サンプル ドキュメントを使用できます。
  • ファイルの先頭付近にある formUrl 変数にファイル URL 値が追加されています。
  • URL で指定されたファイルを分析するには、beginAnalyzeDocuments メソッドを使用して prebuilt-layout をモデル ID として渡します。
    const DocumentIntelligence = require("@azure-rest/ai-document-intelligence").default,
  { getLongRunningPoller, isUnexpected } = require("@azure-rest/ai-document-intelligence");

  const { AzureKeyCredential } = require("@azure/core-auth");

    // set `<your-key>` and `<your-endpoint>` variables with the values from the Azure portal.
    const key = "<your-key>";
    const endpoint = "<your-endpoint>";

    // sample document
    const formUrl = "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 initialResponse = await client
      .path("/documentModels/{modelId}:analyze", "prebuilt-layout")
      .post({
        contentType: "application/json",
        body: {
          urlSource: formUrl
        },
       });

       if (isUnexpected(initialResponse)) {
       throw initialResponse.body.error;
     }

    const poller = await getLongRunningPoller(client, initialResponse);
    const analyzeResult = (await poller.pollUntilDone()).body.analyzeResult;

    const documents = analyzeResult?.documents;

    const document = documents && documents[0];
    if (!document) {
    throw new Error("Expected at least one document in the result.");
    }

    console.log(
    "Extracted document:",
    document.docType,
    `(confidence: ${document.confidence || "<undefined>"})`,
    );
    console.log("Fields:", document.fields);
}

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

アプリケーションを実行します

アプリケーションにコード サンプルを追加したら、プログラムを実行します。

  1. Document Intelligence アプリケーション (doc-intel-app) があるフォルダーに移動します。

  2. ご利用のターミナルで、次のコマンドを入力します。

    node index.js
    

次のコード サンプルを index.js ファイルに追加します。 次のように Azure portal の Document Intelligence インスタンスの値を使用して、キーおよびエンドポイント変数を必ず更新してください。


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

    // set `<your-key>` and `<your-endpoint>` variables with the values from the Azure portal.
    const key = "<your-key>";
    const endpoint = "<your-endpoint>";

    // sample document
  const formUrl = "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-layout", formUrl);

    const {
        pages,
        tables
    } = 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 (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);
});

アプリケーションを実行します

アプリケーションにコード サンプルを追加したら、プログラムを実行します。

  1. Document Intelligence アプリケーション (doc-intel-app) があるフォルダーに移動します。

  2. ご利用のターミナルで、次のコマンドを入力します。

    node index.js
    

レイアウト モデルの出力

予測される出力のスニペットを次に示します。

Pages:
- Page 1 (unit: inch)
  8.5x11, angle: 0
  69 lines, 425 words
Tables:
- Extracted table: 3 columns, 5 rows (15 cells)

出力全体を表示するには、GitHub 上の Azure サンプル リポジトリにアクセスして、レイアウト モデルの出力を表示します。

事前構築済みのモデル

この例では、事前構築済み請求書モデルを使用して請求書を分析します。

ヒント

請求書に限らず、複数の事前構築済みモデルから選択できます。各モデルには、独自のサポートされているフィールドのセットが含まれます。 analyze 操作に使用するモデルは、分析するドキュメントの種類によって異なります。 「モデル データの抽出」を参照してください。

  • 事前構築済み請求書モデルを使用して請求書を分析します。 このクイックスタートでは、Microsoft のサンプル請求書ドキュメントを使用できます。
  • ファイルの先頭にある invoiceUrl 変数にファイル URL 値が追加されています。
  • URI で特定のファイルを分析するには、beginAnalyzeDocuments メソッドを使用して、モデル ID として PrebuiltModels.Invoice を渡します。返される値は、送信されたドキュメントに関するデータを含む result オブジェクトです。
  • わかりやすくするために、サービスから返されるキーと値のペアはすべてここには表示されません。 サポートされているフィールドと対応する型の一覧については、請求書の概念に関するページを参照してください。

const DocumentIntelligence = require("@azure-rest/ai-document-intelligence").default,
  { getLongRunningPoller, isUnexpected } = require("@azure-rest/ai-document-intelligence");

const { AzureKeyCredential } = require("@azure/core-auth");

    // set `<your-key>` and `<your-endpoint>` variables with the values from the Azure portal.
    const key = "<your-key>";
    const endpoint = "<your-endpoint>";

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

async function main() {

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

    const initialResponse = await client
    .path("/documentModels/{modelId}:analyze", "prebuilt-invoice")
    .post({
      contentType: "application/json",
      body: {
        // The Document Intelligence service will access the URL to the invoice image and extract data from it
        urlSource: invoiceUrl,
      },
    });

    if (isUnexpected(initialResponse)) {
       throw initialResponse.body.error;
     }

    const poller = await getLongRunningPoller(client, initialResponse);

    poller.onProgress((state) => console.log("Operation:", state.result, state.status));
    const analyzeResult = (await poller.pollUntilDone()).body.analyzeResult;

    const documents = analyzeResult?.documents;

    const result = documents && documents[0];
    if (result) {
      console.log(result.fields);
    } else {
      throw new Error("Expected at least one invoice in the result.");
    }

console.log(
    "Extracted invoice:",
    document.docType,
    `(confidence: ${document.confidence || "<undefined>"})`,
  );
  console.log("Fields:", document.fields);
}


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

アプリケーションを実行します

アプリケーションにコード サンプルを追加したら、プログラムを実行します。

  1. Document Intelligence アプリケーション (doc-intel-app) があるフォルダーに移動します。

  2. ご利用のターミナルで、次のコマンドを入力します。

    node index.js
    

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

// set `<your-key>` and `<your-endpoint>` variables with the values from the Azure portal.
const key = "<your-key>";
const endpoint = "<your-endpoint>";
// sample document
invoiceUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/sample-invoice.pdf"

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

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

    const {
        pages,
        tables
    } = 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 && 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.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);
});

アプリケーションを実行します

アプリケーションにコード サンプルを追加したら、プログラムを実行します。

  1. Document Intelligence アプリケーション (doc-intel-app) があるフォルダーに移動します。

  2. ご利用のターミナルで、次のコマンドを入力します。

    node index.js
    

事前構築済みモデルの出力

予測される出力のスニペットを次に示します。

  Vendor Name: CONTOSO LTD.
  Customer Name: MICROSOFT CORPORATION
  Invoice Date: 2019-11-15T00:00:00.000Z
  Due Date: 2019-12-15T00:00:00.000Z
  Items:
  - <no product code>
    Description: Test for 23 fields
    Quantity: 1
    Date: undefined
    Unit: undefined
    Unit Price: 1
    Tax: undefined
    Amount: 100

出力全体を表示するには、GitHub 上の Azure サンプル リポジトリにアクセスして、事前構築済み請求書モデルの出力を表示します。

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

  // set `<your-key>` and `<your-endpoint>` variables with the values from the Azure portal.
      const key = "<your-key>";
      const endpoint = "<your-endpoint>";
// sample document
    invoiceUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/sample-invoice.pdf"

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

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

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


  if (document) {
    const {
      vendorName,
      customerName,
      invoiceDate,
      dueDate,
      items,
      subTotal,
      previousUnpaidBalance,
      totalTax,
      amountDue,
    } = document.fields;

    // The invoice model has many fields. For details, *see* [Invoice model field extraction](../../prebuilt/invoice.md#field-extraction)
    console.log("Vendor Name:", vendorName && vendorName.value);
    console.log("Customer Name:", customerName && customerName.value);
    console.log("Invoice Date:", invoiceDate && invoiceDate.value);
    console.log("Due Date:", dueDate && dueDate.value);

    console.log("Items:");
    for (const item of (items && items.values) || []) {
      const { productCode, description, quantity, date, unit, unitPrice, tax, amount } =
        item.properties;

      console.log("-", (productCode && productCode.value) || "<no product code>");
      console.log("  Description:", description && description.value);
      console.log("  Quantity:", quantity && quantity.value);
      console.log("  Date:", date && date.value);
      console.log("  Unit:", unit && unit.value);
      console.log("  Unit Price:", unitPrice && unitPrice.value);
      console.log("  Tax:", tax && tax.value);
      console.log("  Amount:", amount && amount.value);
    }

    console.log("Subtotal:", subTotal && subTotal.value);
    console.log("Previous Unpaid Balance:", previousUnpaidBalance && previousUnpaidBalance.value);
    console.log("Tax:", totalTax && totalTax.value);
    console.log("Amount Due:", amountDue && amountDue.value);
  } else {
    throw new Error("Expected at least one receipt in the result.");
  }
}


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

アプリケーションを実行します

アプリケーションにコード サンプルを追加したら、プログラムを実行します。

  1. Document Intelligence アプリケーション (doc-intel-app) があるフォルダーに移動します。

  2. ご利用のターミナルで、次のコマンドを入力します。

    node index.js
    

このクイックスタートでは、次の機能を使用して、フォームとドキュメントからデータを分析および抽出します。

  • レイアウト—モデルをトレーニングすることなく、テーブル、行、単語、ラジオ ボタンやチェック ボックスなどの選択マーク、キーと値のペアを分析および抽出します。

  • 事前構築済みの請求書 - 事前トレーニング済みのモデルを使用して、共通フィールドの分析と、特定のドキュメント タイプからの抽出を行います。

前提条件

  • Azure サブスクリプション - 無料アカウントを作成します

  • Python 3.7、またはそれ以降

    • Python のインストールには、pip が含まれている必要があります。 pip がインストールされているかどうかを確認するには、コマンド ラインで pip --version を実行します。 最新バージョンの Python をインストールして pip を入手してください。
  • Visual Studio Code または好みの IDE の最新バージョン。 詳細については、「Visual Studio Code での Python の概要」を "参照してください"。

  • Azure AI サービスまたは Document Intelligence リソース。 Azure サブスクリプションを用意できたら、Azure portal で単一サービスまたはマルチサービスの Document Intelligence リソースを作成し、キーとエンドポイントを取得します。 Free 価格レベル (F0) を使用してサービスを試用し、後から運用環境用の有料レベルにアップグレードすることができます。

ヒント

1 つのエンドポイント/キーで複数の Azure AI サービスにアクセスする予定の場合は、Azure AI サービス リソースを作成します。 Document Intelligence へのアクセスのみの場合は、Document Intelligence リソースを作成します。 Microsoft Entra 認証を使用する場合は、単一サービス リソースが必要になることに注意してください。

  • リソースがデプロイされたら、 [リソースに移動] を選択します。 アプリケーションを Document Intelligence API に接続するには、作成したリソースのキーとエンドポイントが必要になります。 このクイックスタートで後に示すコードに、自分のキーとエンドポイントを貼り付けます。

    Azure portal のキーとエンドポイントの場所のスクリーンショット。

設定

ローカル環境でターミナル ウィンドウを開き、次のように pip を使用して Python 用の Azure AI Document Intelligence クライアント ライブラリをインストールします。

pip install azure-ai-documentintelligence==1.0.0b4

pip install azure-ai-formrecognizer==3.3.0

pip install azure-ai-formrecognizer==3.2.0b6

Python アプリケーションを作成する

Document Intelligence サービスとやり取りするには、DocumentIntelligenceClient クラスのインスタンスを作成する必要があります。 これを行うために、Azure portal の key を使用して AzureKeyCredential を作成し、その AzureKeyCredential と Document Intelligence の endpoint を使用して DocumentIntelligenceClient インスタンスを作成します。

  1. 任意のエディターまたは IDE で、doc_intel_quickstart.py という新しい Python ファイルを作成します。

  2. doc_intel_quickstart.py ファイルを開き、次のコード サンプルのいずれかを選択してコピーし、アプリケーションに貼り付けます。

Document Intelligence サービスとやり取りするには、DocumentAnalysisClient クラスのインスタンスを作成する必要があります。 これを行うために、Azure portal の key を使用して AzureKeyCredential を作成し、その AzureKeyCredential と Document Intelligence の endpoint を使用して DocumentAnalysisClient インスタンスを作成します。

  1. 任意のエディターまたは IDE で、form_recognizer_quickstart.py という新しい Python ファイルを作成します。

  2. form_recognizer_quickstart.py ファイルを開き、次のコード サンプルのいずれかを選択してコピーし、アプリケーションに貼り付けます。

重要

終わったらコードからキーを削除し、公開しないよう注意してください。 運用環境では、Azure Key Vault などの資格情報を格納してアクセスする安全な方法を使用します。 詳しくは、Azure AI サービスのセキュリティを "ご覧ください"。

レイアウト モデル

テキスト、選択マーク、テキスト スタイル、テーブルの構造、そして対応する境界領域の座標をドキュメントから抽出します。

  • この例では、URL で指定されたドキュメント ファイルが必要になります。 このクイックスタートでは、サンプル ドキュメントを使用できます。
  • analyze_layout 関数の formUrl 変数にファイル URL 値を追加してあります。

次のコード サンプルを doc_intel_quickstart.py アプリケーションに追加します。 次のように Azure portal の Document Intelligence インスタンスの値を使用して、キーおよびエンドポイント変数を必ず更新してください。


# import libraries
import os
from azure.core.credentials import AzureKeyCredential
from azure.ai.documentintelligence import DocumentIntelligenceClient
from azure.ai.documentintelligence.models import AnalyzeResult
from azure.ai.documentintelligence.models import AnalyzeDocumentRequest

# set `<your-endpoint>` and `<your-key>` variables with the values from the Azure portal
endpoint = "<your-endpoint>"
key = "<your-key>"

# 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_layout():
    # sample document
    formUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/sample-layout.pdf"

    document_intelligence_client = DocumentIntelligenceClient(
        endpoint=endpoint, credential=AzureKeyCredential(key)
    )

    poller = document_intelligence_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()

アプリケーションの実行

アプリケーションにコード サンプルを追加したら、プログラムをビルドして実行します。

  1. doc_intel_quickstart.py ファイルがあるフォルダーに移動します。

  2. ご利用のターミナルで、次のコマンドを入力します。

    python doc_intel_quickstart.py
    

URL で指定されたファイルを分析するには begin_analyze_document_from_url メソッドを使用して、prebuilt-layout をモデル ID として渡します。 その戻り値は、送信されたドキュメントに関するデータを含む result オブジェクトです。

次のコード サンプルを form_recognizer_quickstart.py アプリケーションに追加します。 Azure portal の Form Recognizer インスタンスの値を使用して、キーとエンドポイントの各変数を必ず更新してください。


# import libraries
import os
from azure.ai.formrecognizer import DocumentAnalysisClient
from azure.core.credentials import AzureKeyCredential

# set `<your-endpoint>` and `<your-key>` variables with the values from the Azure portal
endpoint = "<your-endpoint>"
key = "<your-key>"

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/sample-layout.pdf"

    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()

アプリケーションの実行

アプリケーションにコード サンプルを追加したら、プログラムをビルドして実行します。

  1. form_recognizer_quickstart.py ファイルがあるフォルダーに移動します。

  2. ご利用のターミナルで、次のコマンドを入力します。

    python form_recognizer_quickstart.py
    

レイアウト モデルの出力

予測される出力のスニペットを次に示します。

  ----Analyzing layout from page #1----
  Page has width: 8.5 and height: 11.0, measured with unit: inch
  ...Line # 0 has word count 2 and text 'UNITED STATES' within bounding box '[3.4915, 0.6828], [5.0116, 0.6828], [5.0116, 0.8265], [3.4915, 0.8265]'
  ......Word 'UNITED' has a confidence of 1.0
  ......Word 'STATES' has a confidence of 1.0
  ...Line # 1 has word count 4 and text 'SECURITIES AND EXCHANGE COMMISSION' within bounding box '[2.1937, 0.9061], [6.297, 0.9061], [6.297, 1.0498], [2.1937, 1.0498]'
  ......Word 'SECURITIES' has a confidence of 1.0
  ......Word 'AND' has a confidence of 1.0
  ......Word 'EXCHANGE' has a confidence of 1.0
  ......Word 'COMMISSION' has a confidence of 1.0
  ...Line # 2 has word count 3 and text 'Washington, D.C. 20549' within bounding box '[3.4629, 1.1179], [5.031, 1.1179], [5.031, 1.2483], [3.4629, 1.2483]'
  ......Word 'Washington,' has a confidence of 1.0
  ......Word 'D.C.' has a confidence of 1.0

出力全体を表示するには、GitHub 上の Azure サンプル リポジトリにアクセスして、レイアウト モデルの出力を表示します。

次のコード サンプルを form_recognizer_quickstart.py アプリケーションに追加します。 Azure portal の Form Recognizer インスタンスの値を使用して、キーとエンドポイントの各変数を必ず更新してください。


# import libraries
import os
from azure.ai.formrecognizer import DocumentAnalysisClient
from azure.core.credentials import AzureKeyCredential

# set `<your-endpoint>` and `<your-key>` variables with the values from the Azure portal
endpoint = "<your-endpoint>"
key = "<your-key>"


def analyze_layout():
    # sample document
    formUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/sample-layout.pdf"

    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 polygon '{}'".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 polygon '{}' 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 polygon '{}'".format(
                        region.page_number,
                        format_polygon(region.polygon),
                    )
                )

    print("----------------------------------------")


if __name__ == "__main__":
    analyze_layout()


アプリケーションの実行

アプリケーションにコード サンプルを追加したら、プログラムをビルドして実行します。

  1. form_recognizer_quickstart.py ファイルがあるフォルダーに移動します。

  2. ご利用のターミナルで、次のコマンドを入力します。

    python form_recognizer_quickstart.py
    

事前構築済みのモデル

事前構築済みモデルを使用して、特定のドキュメントの種類から一般的なフィールドを分析して抽出します。 この例では、事前構築済み請求書モデルを使用して請求書を分析します。

ヒント

請求書に限らず、複数の事前構築済みモデルから選択できます。各モデルには、独自のサポートされているフィールドのセットが含まれます。 analyze 操作に使用するモデルは、分析するドキュメントの種類によって異なります。 「モデル データの抽出」を参照してください。

  • 事前構築済み請求書モデルを使用して請求書を分析します。 このクイックスタートでは、Microsoft のサンプル請求書ドキュメントを使用できます。
  • ファイルの先頭にある invoiceUrl 変数にファイル URL 値が追加されています。
  • わかりやすくするために、サービスから返されるキーと値のペアはすべてここには表示されません。 サポートされているフィールドと対応する型の一覧については、請求書の概念に関するページを参照してください。

次のコード サンプルを doc_intel_quickstart.py アプリケーションに追加します。 次のように Azure portal の Document Intelligence インスタンスの値を使用して、キーおよびエンドポイント変数を必ず更新してください。


# import libraries
import os
from azure.core.credentials import AzureKeyCredential
from azure.ai.documentintelligence import DocumentIntelligenceClient
from azure.ai.documentintelligence.models import AnalyzeResult
from azure.ai.documentintelligence.models import AnalyzeDocumentRequest



# set `<your-endpoint>` and `<your-key>` variables with the values from the Azure portal
endpoint = "<your-endpoint>"
key = "<your-key>"

def analyze_invoice():
    # sample document

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

    document_intelligence_client = DocumentIntelligenceClient(
        endpoint=endpoint, credential=AzureKeyCredential(key)
    )

    poller = document_intelligence_client.begin_analyze_document(
        "prebuilt-invoice", AnalyzeDocumentRequest(url_source=invoiceUrl)
    )
    invoices = poller.result()

    if invoices.documents:
        for idx, invoice in enumerate(invoices.documents):
            print(f"--------Analyzing invoice #{idx + 1}--------")
            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 customer_id:
                print(
                    f"Customer Id: {customer_id.get('content')} has confidence: {customer_id.get('confidence')}"
                )
            customer_address = invoice.fields.get("CustomerAddress")
            if customer_address:
                print(
                    f"Customer Address: {customer_address.get('content')} has confidence: {customer_address.get('confidence')}"
                )
            customer_address_recipient = invoice.fields.get("CustomerAddressRecipient")
            if customer_address_recipient:
                print(
                    f"Customer Address Recipient: {customer_address_recipient.get('content')} has confidence: {customer_address_recipient.get('confidence')}"
                )
            invoice_id = invoice.fields.get("InvoiceId")
            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:")
            for idx, item in enumerate(invoice.fields.get("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()


アプリケーションの実行

アプリケーションにコード サンプルを追加したら、プログラムをビルドして実行します。

  1. doc_intel_quickstart.py ファイルがあるフォルダーに移動します。

  2. ご利用のターミナルで、次のコマンドを入力します。

    python doc_intel_quickstart.py
    

URI で指定されたファイルを分析するには、begin_analyze_document_from_url メソッドを使用して prebuilt-invoice をモデル ID として渡します。 その戻り値は、送信されたドキュメントに関するデータを含む result オブジェクトです。

次のコード サンプルを form_recognizer_quickstart.py アプリケーションに追加します。 Azure portal の Form Recognizer インスタンスの値を使用して、キーとエンドポイントの各変数を必ず更新してください。

# import libraries
import os
from azure.ai.formrecognizer import DocumentAnalysisClient
from azure.core.credentials import AzureKeyCredential

# set `<your-endpoint>` and `<your-key>` variables with the values from the Azure portal
endpoint = "<your-endpoint>"
key = "<your-key>"


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
    )


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()


アプリケーションの実行

アプリケーションにコード サンプルを追加したら、プログラムをビルドして実行します。

  1. form_recognizer_quickstart.py ファイルがあるフォルダーに移動します。

  2. ご利用のターミナルで、次のコマンドを入力します。

    python form_recognizer_quickstart.py
    

事前構築済みモデルの出力

予測される出力のスニペットを次に示します。

  --------Recognizing invoice #1--------
  Vendor Name: CONTOSO LTD. has confidence: 0.919
  Vendor Address: 123 456th St New York, NY, 10001 has confidence: 0.907
  Vendor Address Recipient: Contoso Headquarters has confidence: 0.919
  Customer Name: MICROSOFT CORPORATION has confidence: 0.84
  Customer Id: CID-12345 has confidence: 0.956
  Customer Address: 123 Other St, Redmond WA, 98052 has confidence: 0.909
  Customer Address Recipient: Microsoft Corp has confidence: 0.917
  Invoice Id: INV-100 has confidence: 0.972
  Invoice Date: 2019-11-15 has confidence: 0.971
  Invoice Total: CurrencyValue(amount=110.0, symbol=$) has confidence: 0.97
  Due Date: 2019-12-15 has confidence: 0.973

出力全体を表示するには、GitHub 上の Azure サンプル リポジトリにアクセスして、事前構築済み請求書モデルの出力を表示します。

次のコード サンプルを form_recognizer_quickstart.py アプリケーションに追加します。 Azure portal の Form Recognizer インスタンスの値を使用して、キーとエンドポイントの各変数を必ず更新してください。


# import libraries
import os
from azure.ai.formrecognizer import DocumentAnalysisClient
from azure.core.credentials import AzureKeyCredential

# set `<your-endpoint>` and `<your-key>` variables with the values from the Azure portal
endpoint = "<your-endpoint>"
key = "<your-key>"


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/sample-layout.pdf"

    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 polygon '{}'".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 polygon '{}' 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 polygon '{}'".format(
                    region.page_number,
                    format_polygon(region.polygon),
                )
            )

print("----------------------------------------")


if __name__ == "__main__":
    analyze_layout()


アプリケーションの実行

アプリケーションにコード サンプルを追加したら、プログラムをビルドして実行します。

  1. form_recognizer_quickstart.py ファイルがあるフォルダーに移動します。

  2. ご利用のターミナルで、次のコマンドを入力します。

    python form_recognizer_quickstart.py
    

このクイックスタートでは、Document Intelligence REST API を使用して、ドキュメントからデータと値を分析および抽出する方法を学習します。

前提条件

  • Azure サブスクリプション - 無料アカウントを作成します

  • curl コマンド ライン ツールがインストールされている。

  • PowerShell バージョン 7.* 以降 (または同様のコマンドライン アプリケーション。):

  • PowerShell のバージョンを確認するには、オペレーティング システムに関連して次のコマンドを入力します。

    • Windows: Get-Host | Select-Object Version
    • macOS または Linux: $PSVersionTable
  • Document Intelligence (単一サービス) または Azure AI サービス (マルチサービス) リソース。 Azure サブスクリプションを用意できたら、Azure portal で単一サービスまたはマルチサービスの Document Intelligence リソースを作成し、キーとエンドポイントを取得します。 Free 価格レベル (F0) を使用してサービスを試用し、後から運用環境用の有料レベルにアップグレードすることができます。

ヒント

1 つのエンドポイント/キーで複数の Azure AI サービスにアクセスする予定の場合は、Azure AI サービス リソースを作成します。 Document Intelligence へのアクセスのみの場合は、Document Intelligence リソースを作成します。 Microsoft Entra 認証を使用する場合は、単一サービス リソースが必要になることに注意してください。

  • リソースがデプロイされたら、 [リソースに移動] を選択します。 アプリケーションを Document Intelligence API に接続するには、作成したリソースのキーとエンドポイントが必要になります。 このクイックスタートで後に示すコードに、自分のキーとエンドポイントを貼り付けます。

    Azure portal のキーとエンドポイントの場所のスクリーンショット。

ドキュメントを分析して結果を取得する

POST 要求は、事前構築済みまたはカスタムのモデルを使用してドキュメントを分析するために使用されます。 GET 要求は、ドキュメント分析呼び出しの結果を取得するために使用されます。 modelId は POST 操作で使用され、resultId は GET 操作で使用されます。

ドキュメントの分析 (POST 要求)

cURL コマンドを実行する前に、post 要求に次の変更を加えます

  1. {endpoint} を、Azure portal の Document Intelligence インスタンスのエンドポイントの値で置き換えます。

  2. {key} を、Azure portal の Document Intelligence インスタンスのキーの値で置き換えます。

  3. 次の表を参考にして、{modelID}{your-document-url} を目的の値に置き換えます。

  4. URL にドキュメント ファイルが必要です。 このクイック スタートでは、各機能について、次の表に示すサンプル フォームを使用できます。

サンプル ドキュメント

機能 {modelID} {your-document-url}
読み取り prebuilt-read https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/read.png
レイアウト 事前構築済みレイアウト https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/layout.png
医療保険カード prebuilt-healthInsuranceCard.us https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/insurance-card.png
W-2 prebuilt-tax.us.w2 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
Receipt 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

サンプル ドキュメント

機能 {modelID} {your-document-url}
一般的なドキュメント 事前構築済みドキュメント https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/sample-layout.pdf
読み取り prebuilt-read https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/read.png
レイアウト 事前構築済みレイアウト https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/layout.png
医療保険カード prebuilt-healthInsuranceCard.us https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/insurance-card.png
W-2 prebuilt-tax.us.w2 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
Receipt 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
名刺 事前構築された名刺 https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/de5e0d8982ab754823c54de47a47e8e499351523/curl/form-recognizer/rest-api/business_card.jpg

重要

終わったらコードからキーを削除し、公開しないよう注意してください。 運用環境では、Azure Key Vault などの資格情報を格納してアクセスする安全な方法を使用します。 詳しくは、Azure AI サービスのセキュリティを "参照してください"。

POST 要求

curl -v -i POST "{endpoint}/documentintelligence/documentModels/{modelId}:analyze?api-version=2024-11-30" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: {key}" --data-ascii "{'urlSource': '{your-document-url}'}"
curl -v -i POST "{endpoint}/formrecognizer/documentModels/{modelID}:analyze?api-version=2023-07-31" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: {key}" --data-ascii "{'urlSource': '{your-document-url}'}"
curl -v -i POST "{endpoint}/formrecognizer/documentModels/{modelId}:analyze?api-version=2022-08-31" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: {key}" --data-ascii "{'urlSource': '{your-document-url}'}"

POST 応答 (resultID)

読み取り専用の Operation-Location ヘッダーを含む 202 (Success) 応答を受信します。 このヘッダーの値には resultID が含まれており、クエリを実行して非同期操作の状態を取得し、同じリソース サブスクリプション キーで GET 要求を使用して結果を取得できます。

{alt-text}

分析結果の取得 (GET 要求)

Analyze document&preserve-view=true&tabs=HTTP) API を呼び出した後、Get analyze result&preserve-view=true&tabs=HTTP) API を呼び出して、操作の状態と抽出されたデータを取得します。 コマンドを実行する前に、次の変更を行います。

Analyze document API を呼び出した後、Get analyze result API を呼び出して、操作の状態と抽出されたデータを取得します。 コマンドを実行する前に、次の変更を行います。

Analyze document API を呼び出した後、Get analyze result API を呼び出して、操作の状態と抽出されたデータを取得します。 コマンドを実行する前に、次の変更を行います。

  1. POST 応答{resultID} Operation-Location ヘッダーを置き換えます。

  2. {key} を、Azure portal の Document Intelligence インスタンスのキーの値で置き換えます。

GET 要求

curl -v -X GET "{endpoint}/documentintelligence/documentModels/{modelId}/analyzeResults/{resultId}?api-version=2024-11-30" -H "Ocp-Apim-Subscription-Key: {key}"
curl -v -X GET "{endpoint}/formrecognizer/documentModels/{modelId}/analyzeResults/{resultId}?api-version=2023-07-31" -H "Ocp-Apim-Subscription-Key: {key}"

curl -v -X GET "{endpoint}/formrecognizer/documentModels/{modelId}/analyzeResults/{resultId}?api-version=2022-08-31" -H "Ocp-Apim-Subscription-Key: {key}"

結果の確認

JSON 出力で 200 (Success) 応答を受信します。 最初のフィールド "status" は、操作の状態を示します。 操作が完了していない場合、"status" の値は "running" または "notStarted" であり、手動またはスクリプトでもう一度 API を呼び出す必要があります。 呼び出しの間隔は 1 秒以上あけることをお勧めします。

事前構築済み請求書のサンプル応答

{
    "status": "succeeded",
    "createdDateTime": "2024-03-25T19:31:37Z",
    "lastUpdatedDateTime": "2024-03-25T19:31:43Z",
    "analyzeResult": {
        "apiVersion": "2024-11-30",
        "modelId": "prebuilt-invoice",
        "stringIndexType": "textElements"...
    ..."pages": [
            {
                "pageNumber": 1,
                "angle": 0,
                "width": 8.5,
                "height": 11,
                "unit": "inch",
                "words": [
                    {
                        "content": "CONTOSO",
                        "boundingBox": [
                            0.5911,
                            0.6857,
                            1.7451,
                            0.6857,
                            1.7451,
                            0.8664,
                            0.5911,
                            0.8664
                        ],
                        "confidence": 1,
                        "span": {
                            "offset": 0,
                            "length": 7
                                }
                      }],
              }]
      }
}
{
    "status": "succeeded",
    "createdDateTime": "2023-08-25T19:31:37Z",
    "lastUpdatedDateTime": "2023-08-25T19:31:43Z",
    "analyzeResult": {
        "apiVersion": "2023-07-31",
        "modelId": "prebuilt-invoice",
        "stringIndexType": "textElements"...
    ..."pages": [
            {
                "pageNumber": 1,
                "angle": 0,
                "width": 8.5,
                "height": 11,
                "unit": "inch",
                "words": [
                    {
                        "content": "CONTOSO",
                        "boundingBox": [
                            0.5911,
                            0.6857,
                            1.7451,
                            0.6857,
                            1.7451,
                            0.8664,
                            0.5911,
                            0.8664
                        ],
                        "confidence": 1,
                        "span": {
                            "offset": 0,
                            "length": 7
                                }
                      }],
              }]
      }
}
{
    "status": "succeeded",
    "createdDateTime": "2022-09-25T19:31:37Z",
    "lastUpdatedDateTime": "2022-09-25T19:31:43Z",
    "analyzeResult": {
        "apiVersion": "2022-08-31",
        "modelId": "prebuilt-invoice",
        "stringIndexType": "textElements"...
    ..."pages": [
            {
                "pageNumber": 1,
                "angle": 0,
                "width": 8.5,
                "height": 11,
                "unit": "inch",
                "words": [
                    {
                        "content": "CONTOSO",
                        "boundingBox": [
                            0.5911,
                            0.6857,
                            1.7451,
                            0.6857,
                            1.7451,
                            0.8664,
                            0.5911,
                            0.8664
                        ],
                        "confidence": 1,
                        "span": {
                            "offset": 0,
                            "length": 7
                                }
                      }],
              }]
      }
}

サポートされているドキュメント フィールド

事前構築済みモデルは、事前定義済みドキュメント フィールドのセットを抽出します。 抽出されたフィールド名、型、説明、例については、「モデル データの抽出」を参照してください。

以上です。お疲れさまでした。

このクイックスタートでは、Document Intelligence モデルを使用して、さまざまなフォームとドキュメントを分析しました。 続けて、Document Intelligence Studio とリファレンス ドキュメントを確認して Document Intelligence API を深く知ってください。

次のステップ

このコンテンツの適用対象: checkmark v2.1 | 最新バージョン: 青のチェックマーク v4.0 (GA)

選択したプログラミング言語または REST API を使用して Azure AI Document Intelligence の利用を開始しましょう。 Document Intelligence は、機械学習を使用してドキュメントからキーと値のペア、テキスト、テーブルを抽出するクラウドベースの Azure AI サービスです。 テクノロジを学習している場合は、無料のサービスを使用することをお勧めします。 無料のページは 1 か月あたり 500 ページに制限されていることに注意してください。

Document Intelligence の機能と開発オプションの詳細を確認するには、「概要」ページにアクセスしてください。

リファレンスのドキュメント | ライブラリのソース コード | パッケージ (NuGet) | サンプル

このクイックスタートでは、次の API を使用して、フォームとドキュメントから構造化データを抽出します。

前提条件

  • Azure サブスクリプション - 無料アカウントを作成します

  • Visual Studio IDE の現在のバージョン。

  • Azure AI サービスまたは Document Intelligence リソース。 Azure サブスクリプションを用意できたら、Azure portal で単一サービスまたはマルチサービスの Document Intelligence リソースを作成し、キーとエンドポイントを取得します。 Free 価格レベル (F0) を使用してサービスを試用し、後から運用環境用の有料レベルにアップグレードすることができます。

    ヒント

    1 つのエンドポイント/キーで複数の Azure AI サービスにアクセスする予定の場合は、Azure AI サービス リソースを作成します。 Document Intelligence へのアクセスのみの場合は、Document Intelligence リソースを作成します。 Microsoft Entra 認証を使用する場合は、単一サービス リソースが必要になることに注意してください。

  • リソースがデプロイされたら、 [リソースに移動] を選択します。 アプリケーションを Document Intelligence API に接続するには、作成したリソースのキーとエンドポイントが必要になります。 このクイックスタートで後に示すコードに、自分のキーとエンドポイントを貼り付けます。

    Azure portal のキーとエンドポイントの場所のスクリーンショット。

設定

  1. Visual Studio 2019 を起動します。

  2. スタート ページで、[新しいプロジェクトの作成] を選択します。

    Visual Studio の開始ページのスクリーンショット。

  3. [新しいプロジェクトの作成] ページで、検索ボックスに「コンソール」と入力します。 [コンソール アプリケーション] テンプレートを選択し、 [次へ] を選択します。

    Visual Studio の [新しいプロジェクトの作成] ページのスクリーンショット。

  4. [新しいプロジェクトの構成] ダイアログ ウィンドウの [プロジェクト名] ボックスに「formRecognizer_quickstart」と入力します。 [次へ] を選びます。

    Visual Studio の [新しいプロジェクトの構成] ダイアログ ウィンドウのスクリーンショット。

  5. [追加情報] ダイアログ ウィンドウで、 [.NET 5.0 (最新)] を選択し、 [作成] を選択します。

    Visual Studio の [追加情報] ダイアログ ウィンドウのスクリーンショット。

NuGet を使用してクライアント ライブラリをインストールする

  1. formRecognizer_quickstart プロジェクトを右クリックし、 [NuGet パッケージの管理...] を選択します。

    [NuGet パッケージの選択] ウィンドウを示すスクリーンショット。

  2. [参照] タブを選択し、「Azure.AI.FormRecognizer」と入力します。

    [Document Intelligence パッケージの選択] ドロップダウン メニューを示すスクリーンショット。

  3. ドロップダウン メニューからバージョン 3.1.1 を選び、[インストール] を選択します。

アプリケーションをビルドする

Document Intelligence サービスとやり取りするには、FormRecognizerClient クラスのインスタンスを作成する必要があります。 これを行うには、キーを使用して AzureKeyCredential を作成し、その AzureKeyCredential と Document Intelligence の endpoint を使用して FormRecognizerClient インスタンスを作成します。

Note

  • .NET 6 以降では、console テンプレートを使用する新しいプロジェクトによって、以前のバージョンとは異なる新しいプログラム スタイルが生成されます。
  • この新しい出力では、記述する必要があるコードを簡素化できる最新の C# 機能が使用されています。
  • 新しいバージョンで使用する場合、記述する必要があるのは、`Main` メソッドの本体のみです。 最上位レベルのステートメント、グローバル using ディレクティブ、または暗黙的な using ディレクティブを含める必要はありません。
  • 詳細については、「C# コンソール アプリ テンプレートで最上位レベルのステートメントが生成される」を "参照してください"。
  1. Program.cs ファイルを開きます。

  2. 次の using ディレクティブを含めます。

using Azure;
using Azure.AI.FormRecognizer;
using Azure.AI.FormRecognizer.Models;
using System.Threading.Tasks;
  1. endpointkey の環境変数を設定し、AzureKeyCredentialFormRecognizerClient のインスタンスを作成します。
private static readonly string endpoint = "your-form-recognizer-endpoint";
private static readonly string key = "your-api-key";
private static readonly AzureKeyCredential credential = new AzureKeyCredential(key);
  1. Console.Writeline("Hello World!"); を削除し、Program.cs ファイルに試してみるのコード サンプルのいずれかを追加します。

    サンプル コードを Main メソッドに追加するスクリーンショット。

  2. アプリケーションの Main メソッドに貼り付けるコード サンプルを選択してコピーします。

重要

終わったらコードからキーを削除し、公開しないよう注意してください。 運用環境では、Azure Key Vault などの資格情報を格納してアクセスする安全な方法を使用します。 詳しくは、Azure AI サービスのセキュリティに関する記事を参照してください。

試してみる: レイアウト モデル

テキスト、選択マーク、テキスト スタイル、およびテーブルの構造を、対応する境界領域の座標と共にドキュメントから抽出します。

  • この例では、URI にドキュメント ファイルが必要になります。 このクイックスタートでは、サンプル ドキュメントを使用できます。
  • ファイル URI の値を formUri 変数に追加しました。
  • URI で指定されたファイルからレイアウトを抽出するには、StartRecognizeContentFromUriAsync メソッドを使用します。

レイアウト アプリケーションの Program.cs ファイルに次のコードを追加します。


FormRecognizerClient recognizerClient = AuthenticateClient();

Task recognizeContent = RecognizeContent(recognizerClient);
Task.WaitAll(recognizeContent);

private static FormRecognizerClient AuthenticateClient()
            {
                var credential = new AzureKeyCredential(key);
                var client = new FormRecognizerClient(new Uri(endpoint), credential);
                return client;
            }

            private static async Task RecognizeContent(FormRecognizerClient recognizerClient)
        {
            string formUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/sample-layout.pdf";
            FormPageCollection formPages = await recognizerClient
        .StartRecognizeContentFromUri(new Uri(formUrl))
        .WaitForCompletionAsync();

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

試してみる: 事前構築済みモデル

このサンプルでは、請求書を例に、事前トレーニング済みのモデルを使用して、特定の種類の共通ドキュメントのデータを分析する方法を示します。

  • この例では、事前構築済みモデルを使用して請求書ドキュメントを分析します。 このクイックスタートでは、Microsoft のサンプル請求書ドキュメントを使用できます。
  • Main メソッドの上部にある invoiceUri 変数にファイル URI 値が追加されています。
  • URI で指定されたファイルの内容を分析するには、StartRecognizeInvoicesFromUriAsync メソッドを使用します。
  • わかりやすくするために、サービスから返されるフィールドはすべてここには表示されません。 サポートされているすべてのフィールドと対応する型の一覧については、請求書の概念に関するページを参照してください。

事前構築済みモデルを選択する

請求書に限らず、複数の事前構築済みモデルから選択できます。各モデルには、独自のサポートされているフィールドのセットが含まれます。 分析操作に使用するモデルは、分析するドキュメントの種類によって異なります。 Document Intelligence サービスで現在サポートされている事前構築済みモデルを次に示します。

  • 請求書: 請求書からテキスト、選択マーク、テーブル、フィールド、キー情報を抽出します。
  • レシート: レシートからテキストとキー情報を抽出します。
  • 身分証明書: 運転免許証と国際パスポートからテキストとキー情報を抽出します。
  • 名刺: 名刺からテキストとキー情報を抽出します。

事前構築済みの請求書アプリケーションの Program.cs ファイル メソッドに次のコードを追加します

FormRecognizerClient recognizerClient = AuthenticateClient();

  Task analyzeinvoice = AnalyzeInvoice(recognizerClient, invoiceUrl);
  Task.WaitAll(analyzeinvoice);

   private static FormRecognizerClient AuthenticateClient() {
     var credential = new AzureKeyCredential(key);
     var client = new FormRecognizerClient(new Uri(endpoint), credential);
     return client;
   }

   static string invoiceUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/sample-invoice.pdf";

   private static async Task AnalyzeInvoice(FormRecognizerClient recognizerClient, string invoiceUrl) {
     var options = new RecognizeInvoicesOptions() {
       Locale = "en-US"
     };
     RecognizedFormCollection invoices = await recognizerClient.StartRecognizeInvoicesFromUriAsync(new Uri(invoiceUrl), options).WaitForCompletionAsync();

     RecognizedForm invoice = invoices[0];

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

アプリケーションを実行する

プログラムをビルドして実行するには、formRecognizer_quickstart の横にある緑色の [スタート] ボタンを選択するか、F5 キーを押します。

Visual Studioプログラムの実行のスクリーンショット。

リファレンスのドキュメント | ライブラリのソース コード | パッケージ (Maven) | サンプル

このクイックスタートでは、次の API を使用して、フォームとドキュメントから構造化データを抽出します。

前提条件

  • Azure サブスクリプション - 無料アカウントを作成します

  • Java Development Kit (JDK) バージョン 8 以降。 詳細については、「サポートされている Java バージョンと更新スケジュール」を "参照してください"。

  • Azure AI サービスまたは Document Intelligence リソース。 Azure サブスクリプションを用意できたら、Azure portal で単一サービスまたはマルチサービスの Document Intelligence リソースを作成し、キーとエンドポイントを取得します。 Free 価格レベル (F0) を使用してサービスを試用し、後から運用環境用の有料レベルにアップグレードすることができます。

  • リソースがデプロイされたら、 [リソースに移動] を選択します。 アプリケーションを Document Intelligence API に接続するには、作成したリソースのキーとエンドポイントが必要になります。 このクイックスタートで後に示すコードに、自分のキーとエンドポイントを貼り付けます。

    Azure portal のキーとエンドポイントの場所のスクリーンショット。

設定

新しい Gradle プロジェクトを作成する

コンソール ウィンドウ (cmd、PowerShell、Bash など) で、form-recognizer-app という名前のアプリ用に新しいディレクトリを作成し、そこに移動します。

mkdir form-recognizer-app && form-recognizer-app
  1. 作業ディレクトリから gradle init コマンドを実行します。 このコマンドによって、Gradle 用の重要なビルド ファイルが作成されます。たとえば、実行時にアプリケーションを作成して構成するために使用される build.gradle.kts などです。

    gradle init --type basic
    
  2. DSL を選択するよう求められたら、Kotlin を選択します。

  3. 既定のプロジェクト名 (form-recognizer-app) をそのまま使用する

クライアント ライブラリをインストールする

このクイックスタートでは、Gradle 依存関係マネージャーを使用します。 クライアント ライブラリとその他の依存関係マネージャーの情報については、Maven Central Repository を参照してください。

プロジェクトの 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

次のディレクトリ構造を作成します。

アプリケーションの Java ディレクトリ構造のスクリーンショット。

Java ディレクトリに移動し、FormRecognizer.java という名前のファイルを作成します。 それを任意のエディターまたは IDE で開き、次のパッケージ宣言と import ステートメントを追加します。

import com.azure.ai.formrecognizer.*;
import com.azure.ai.formrecognizer.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;

アプリケーションの Main メソッドに貼り付けるコード サンプルを選択してコピーします。

重要

終わったらコードからキーを削除し、公開しないよう注意してください。 運用環境では、Azure Key Vault などの資格情報を格納してアクセスする安全な方法を使用します。 詳しくは、Azure AI サービスのセキュリティを "参照してください"。

試してみる: レイアウト モデル

テキスト、選択マーク、テキスト スタイル、およびテーブルの構造を、対応する境界領域の座標と共にドキュメントから抽出します。

  • この例では、URI にドキュメント ファイルが必要になります。 このクイックスタートでは、サンプル ドキュメントを使用できます。
  • URI で指定されたファイルの内容を分析するには、beginRecognizeContentFromUrl メソッドを使用します。
  • Main メソッドの formUrl 変数にファイル URI 値を追加してあります。

次のコードを使用して、アプリケーションの FormRecognizer クラスを更新します (キーおよびエンドポイント変数は、Azure portal の Document Intelligence インスタンスの値で更新するようにしてください)。


static final String key = "PASTE_YOUR_FORM_RECOGNIZER_KEY_HERE";
static final String endpoint = "PASTE_YOUR_FORM_RECOGNIZER_ENDPOINT_HERE";

public static void main(String[] args) {FormRecognizerClient recognizerClient = new FormRecognizerClientBuilder()
                .credential(new AzureKeyCredential(key)).endpoint(endpoint).buildClient();

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

    System.out.println("Get form content...");
        GetContent(recognizerClient, formUrl);
  }
    private static void GetContent(FormRecognizerClient recognizerClient, String invoiceUri) {
        String analyzeFilePath = invoiceUri;
        SyncPoller<FormRecognizerOperationResult, List<FormPage>> recognizeContentPoller = recognizerClient
                .beginRecognizeContentFromUrl(analyzeFilePath);

        List<FormPage> contentResult = recognizeContentPoller.getFinalResult();
        // </snippet_getcontent_call>
        // <snippet_getcontent_print>
        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();
            });
        });
    }

試してみる: 事前構築済みモデル

このサンプルでは、請求書を例に、事前トレーニング済みのモデルを使用して、特定の種類の共通ドキュメントのデータを分析する方法を示します。

  • この例では、事前構築済みモデルを使用して請求書ドキュメントを分析します。 このクイックスタートでは、Microsoft のサンプル請求書ドキュメントを使用できます。
  • URI で指定されたファイルの内容を分析するには、beginRecognizeInvoicesFromUrl を使用します。
  • Main メソッドの invoiceUrl 変数にファイル URI 値を追加してあります。
  • わかりやすくするために、サービスから返されるフィールドはすべてここには表示されません。 サポートされているすべてのフィールドと対応する型の一覧については、請求書の概念に関するページを参照してください。

事前構築済みモデルを選択する

請求書に限らず、複数の事前構築済みモデルから選択できます。各モデルには、独自のサポートされているフィールドのセットが含まれます。 analyze 操作に使用するモデルは、分析するドキュメントの種類によって異なります。 Document Intelligence サービスで現在サポートされている事前構築済みモデルを次に示します。

  • 請求書: 請求書からテキスト、選択マーク、テーブル、フィールド、キー情報を抽出します。
  • レシート: レシートからテキストとキー情報を抽出します。
  • 身分証明書: 運転免許証と国際パスポートからテキストとキー情報を抽出します。
  • 名刺: 名刺からテキストとキー情報を抽出します。

次のコードを使用して、アプリケーションの FormRecognizer クラスを更新します (キーおよびエンドポイント変数は、Azure portal の Document Intelligence インスタンスの値で更新するようにしてください)。


static final String key = "PASTE_YOUR_FORM_RECOGNIZER_KEY_HERE";
static final String endpoint = "PASTE_YOUR_FORM_RECOGNIZER_ENDPOINT_HERE";

public static void main(String[] args) {
    FormRecognizerClient recognizerClient = new FormRecognizerClientBuilder().credential(new AzureKeyCredential(key)).endpoint(endpoint).buildClient();

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

    System.out.println("Analyze invoice...");
        AnalyzeInvoice(recognizerClient, invoiceUrl);
  }
    private static void AnalyzeInvoice(FormRecognizerClient recognizerClient, String invoiceUrl) {
      SyncPoller < FormRecognizerOperationResult,
        List < RecognizedForm >> recognizeInvoicesPoller = recognizerClient.beginRecognizeInvoicesFromUrl(invoiceUrl);
      List < RecognizedForm > recognizedInvoices = recognizeInvoicesPoller.getFinalResult();

      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());
            }
        }
    }
}

アプリケーションをビルドおよび実行する

メイン プロジェクト ディレクトリ form-recognizer-app に戻ります。

  1. build コマンドを使用してアプリケーションをビルドします。
gradle build
  1. run コマンドを使用してアプリケーションを実行します。
gradle run

リファレンスのドキュメント | ライブラリのソース コード | パッケージ (npm) | サンプル

このクイックスタートでは、次の API を使用して、フォームとドキュメントから構造化データを抽出します。

前提条件

  • Azure サブスクリプション - 無料アカウントを作成します

  • Visual Studio Code または好みの IDE の最新バージョン。

  • 最新 LTS バージョンの Node.js

  • Azure AI サービスまたは Document Intelligence リソース。 Azure サブスクリプションを用意できたら、Azure portal で単一サービスまたはマルチサービスの Document Intelligence リソースを作成し、キーとエンドポイントを取得します。 Free 価格レベル (F0) を使用してサービスを試用し、後から運用環境用の有料レベルにアップグレードすることができます。

    ヒント

    1 つのエンドポイント/キーで複数の Azure AI サービスにアクセスする予定の場合は、Azure AI サービス リソースを作成します。 Document Intelligence へのアクセスのみの場合は、Document Intelligence リソースを作成します。 Microsoft Entra 認証を使用する場合は、単一サービス リソースが必要になることに注意してください。

  • リソースがデプロイされたら、 [リソースに移動] を選択します。 アプリケーションを Document Intelligence API に接続するには、作成したリソースのキーとエンドポイントが必要になります。 このクイックスタートで後に示すコードに、自分のキーとエンドポイントを貼り付けます。

    Azure portal のキーとエンドポイントの場所のスクリーンショット。

設定

  1. 新しい Node.js アプリケーションを作成します。 コンソール ウィンドウ (cmd、PowerShell、Bash など) で、ご利用のアプリ用に新しいディレクトリを作成し、そこに移動します。

    mkdir form-recognizer-app && cd form-recognizer-app
    
  2. npm init コマンドを実行し、package.json ファイルを使用して node アプリケーションを作成します。

    npm init
    
  3. ai-form-recognizer クライアント ライブラリ npm パッケージをインストールします。

    npm install @azure/ai-form-recognizer
    

    アプリの package.json ファイルが依存関係によって更新されます。

  4. index.js という名前のファイルを作成して開き、次のライブラリをインポートします。

    const { FormRecognizerClient, AzureKeyCredential } = require("@azure/ai-form-recognizer");
    
  5. 自分のリソースの Azure エンドポイントおよびキー用の変数を作成します。

    const key = "PASTE_YOUR_FORM_RECOGNIZER_KEY_HERE";
    const endpoint = "PASTE_YOUR_FORM_RECOGNIZER_ENDPOINT_HERE";
    
  6. この時点で、JavaScript アプリケーションには次のコード行が含まれている必要があります。

    
    const { FormRecognizerClient, AzureKeyCredential } = require("@azure/ai-form-recognizer");
    
    const endpoint = "PASTE_YOUR_FORM_RECOGNIZER_ENDPOINT_HERE";
    const key = "PASTE_YOUR_FORM_RECOGNIZER_KEY_HERE";
    

コピーしてアプリケーションに貼り付けるコード サンプルを選択します。

重要

終わったらコードからキーを削除し、公開しないよう注意してください。 運用環境では、Azure Key Vault などの資格情報を格納してアクセスする安全な方法を使用します。 詳しくは、Azure AI サービスのセキュリティを "参照してください"。

試してみる: レイアウト モデル

  • この例では、URI にドキュメント ファイルが必要になります。 このクイックスタートでは、サンプル ドキュメントを使用できます。
  • ファイルの先頭付近にある formUrl 変数にファイル URI 値が追加されています。
  • URI で指定されたファイルの内容を分析するには、beginRecognizeContent メソッドを使用します。

レイアウト アプリケーションの key 変数の下の行に、次のコードを追加する

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

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

async function recognizeContent() {
    const client = new FormRecognizerClient(endpoint, new AzureKeyCredential(key));
    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);
});

試してみる: 事前構築済みモデル

このサンプルでは、請求書を例に、事前トレーニング済みのモデルを使用して、特定の種類の共通ドキュメントのデータを分析する方法を示します。 請求書のフィールドの一覧については、事前構築済みの概念のページを参照してください

  • この例では、事前構築済みモデルを使用して請求書ドキュメントを分析します。 このクイックスタートでは、Microsoft のサンプル請求書ドキュメントを使用できます。
  • ファイルの先頭にある invoiceUrl 変数にファイル URI 値が追加されています。
  • URI で指定されたファイルの内容を分析するには、beginRecognizeInvoices メソッドを使用します。
  • わかりやすくするために、サービスから返されるフィールドはすべてここには表示されません。 サポートされているすべてのフィールドと対応する型の一覧については、請求書の概念に関するページを参照してください。

事前構築済みモデルを選択する

請求書に限らず、複数の事前構築済みモデルから選択できます。各モデルには、独自のサポートされているフィールドのセットが含まれます。 analyze 操作に使用するモデルは、分析するドキュメントの種類によって異なります。 Document Intelligence サービスで現在サポートされている事前構築済みモデルを次に示します。

  • 請求書: 請求書からテキスト、選択マーク、テーブル、フィールド、キー情報を抽出します。
  • レシート: レシートからテキストとキー情報を抽出します。
  • 身分証明書: 運転免許証と国際パスポートからテキストとキー情報を抽出します。
  • 名刺: 名刺からテキストとキー情報を抽出します。

事前構築済みの請求書アプリケーションの key 変数の下に、次のコードを追加する


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

async function recognizeInvoices() {

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

    const poller = await client.beginRecognizeInvoicesFromUrl(invoiceUrl);
    const [invoice] = await poller.pollUntilDone();

    if (invoice === undefined) {
        throw new Error("Failed to extract data from at least one invoice.");
    }

    /**
     * This is a helper function for printing a simple field with an elemental type.
     */
    function fieldToString(field) {
        const {
            name,
            valueType,
            value,
            confidence
        } = field;
        return `${name} (${valueType}): '${value}' with confidence ${confidence}'`;
    }

    console.log("Invoice fields:");

    /**
     * Invoices contain a lot of optional fields, but they are all of elemental types
     * such as strings, numbers, and dates, so we will just enumerate them all.
     */
    for (const [name, field] of Object.entries(invoice.fields)) {
        if (field.valueType !== "array" && field.valueType !== "object") {
            console.log(`- ${name} ${fieldToString(field)}`);
        }
    }

    // Invoices also support nested line items, so we can iterate over them.
    let idx = 0;

    console.log("- Items:");

    const items = invoice.fields["Items"]?.value;
    for (const item of items ?? []) {
        const value = item.value;

        // Each item has several subfields that are nested within the item. We'll
        // map over this list of the subfields and filter out any fields that
        // weren't found. Not all fields will be returned every time, only those
        // that the service identified for the particular document in question.

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

リファレンス ドキュメント | ライブラリのソース コード | パッケージ (PyPi) | サンプル

このクイックスタートでは、次の API を使用して、フォームとドキュメントから構造化データを抽出します。

前提条件

  • Azure サブスクリプション - 無料アカウントを作成します

  • Python 3.x

    • Python のインストールには、pip が含まれている必要があります。 pip がインストールされているかどうかを確認するには、コマンド ラインで pip --version を実行します。 最新バージョンの Python をインストールして pip を入手してください。
  • Azure AI サービスまたは Document Intelligence リソース。 Azure サブスクリプションを用意できたら、Azure portal で単一サービスまたはマルチサービスの Document Intelligence リソースを作成し、キーとエンドポイントを取得します。 Free 価格レベル (F0) を使用してサービスを試用し、後から運用環境用の有料レベルにアップグレードすることができます。

    ヒント

    1 つのエンドポイント/キーで複数の Azure AI サービスにアクセスする予定の場合は、Azure AI サービス リソースを作成します。 Document Intelligence へのアクセスのみの場合は、Document Intelligence リソースを作成します。 Microsoft Entra 認証を使用する場合は、単一サービス リソースが必要になることに注意してください。

  • リソースがデプロイされたら、 [リソースに移動] を選択します。 アプリケーションを Document Intelligence API に接続するには、作成したリソースのキーとエンドポイントが必要になります。 このクイックスタートで後に示すコードに、自分のキーとエンドポイントを貼り付けます。

    Azure portal のキーとエンドポイントの場所のスクリーンショット。

設定

ローカル環境でターミナル ウィンドウを開き、次のように pip を使用して Python 用の Azure AI Document Intelligence クライアント ライブラリをインストールします。

pip install azure-ai-formrecognizer

新しい Python アプリケーションを作成する

任意のエディターまたは IDE で、form_recognizer_quickstart.py という新しい Python アプリケーションを作成します。 その後で、次のライブラリをインポートします。

import os
from azure.ai.formrecognizer import FormRecognizerClient
from azure.core.credentials import AzureKeyCredential

Azure リソースのエンドポイントおよびキー用の変数を作成する

endpoint = "YOUR_FORM_RECOGNIZER_ENDPOINT"
key = "YOUR_FORM_RECOGNIZER_KEY"

この時点で、Python アプリケーションには次のコード行が含まれている必要があります。

import os
from azure.core.exceptions import ResourceNotFoundError
from azure.ai.formrecognizer import DocumentAnalysisClient
from azure.core.credentials import AzureKeyCredential

endpoint = "YOUR_FORM_RECOGNIZER_ENDPOINT"
key = "YOUR_FORM_RECOGNIZER_KEY"

コピーしてアプリケーションに貼り付けるコード サンプルを選択します。

重要

終わったらコードからキーを削除し、公開しないよう注意してください。 運用環境では、Azure Key Vault などの資格情報を格納してアクセスする安全な方法を使用します。 詳しくは、Azure AI サービスのセキュリティを "参照してください"。

試してみる: レイアウト モデル

  • この例では、URI にドキュメント ファイルが必要になります。 このクイックスタートでは、サンプル ドキュメントを使用できます。
  • ファイルの先頭付近にある formUrl 変数にファイル URI 値が追加されています。
  • URI で指定されたファイルの内容を分析するには、begin_recognize_content_from_url メソッドを使用します。

レイアウト アプリケーションの key 変数の下の行に、次のコードを追加する


  def format_bounding_box(bounding_box):
    if not bounding_box:
        return "N/A"
    return ", ".join(["[{}, {}]".format(p.x, p.y) for p in bounding_box])

 def recognize_content():
    # sample document
    formUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/sample-layout.pdf"

    form_recognizer_client = FormRecognizerClient(
        endpoint=endpoint, credential=AzureKeyCredential(key)
    )

    poller = form_recognizer_client.begin_recognize_content_from_url(formUrl)
    form_pages = poller.result()

    for idx, content in enumerate(form_pages):
        print(
            "Page has width: {} and height: {}, measured with unit: {}".format(
                content.width, content.height, content.unit
            )
        )
        for table_idx, table in enumerate(content.tables):
            print(
                "Table # {} has {} rows and {} columns".format(
                    table_idx, table.row_count, table.column_count
                )
            )
            print(
                "Table # {} location on page: {}".format(
                    table_idx, format_bounding_box(table.bounding_box)
                )
            )
            for cell in table.cells:
                print(
                    "...Cell[{}][{}] has text '{}' within bounding box '{}'".format(
                        cell.row_index,
                        cell.column_index,
                        cell.text,
                        format_bounding_box(cell.bounding_box),
                    )
                )

        for line_idx, line in enumerate(content.lines):
            print(
                "Line # {} has word count '{}' and text '{}' within bounding box '{}'".format(
                    line_idx,
                    len(line.words),
                    line.text,
                    format_bounding_box(line.bounding_box),
                )
            )
            if line.appearance:
                if (
                    line.appearance.style_name == "handwriting"
                    and line.appearance.style_confidence > 0.8
                ):
                    print(
                        "Text line '{}' is handwritten and might be a signature.".format(
                            line.text
                        )
                    )
            for word in line.words:
                print(
                    "...Word '{}' has a confidence of {}".format(
                        word.text, word.confidence
                    )
                )

        for selection_mark in content.selection_marks:
            print(
                "Selection mark is '{}' within bounding box '{}' and has a confidence of {}".format(
                    selection_mark.state,
                    format_bounding_box(selection_mark.bounding_box),
                    selection_mark.confidence,
                )
            )
        print("----------------------------------------")


if __name__ == "__main__":
    recognize_content()

試してみる: 事前構築済みモデル

このサンプルでは、請求書を例に、事前トレーニング済みのモデルを使用して、特定の種類の共通ドキュメントのデータを分析する方法を示します。 請求書のフィールドの一覧については、事前構築済みの概念のページを参照してください

  • この例では、事前構築済みモデルを使用して請求書ドキュメントを分析します。 このクイックスタートでは、Microsoft のサンプル請求書ドキュメントを使用できます。
  • ファイルの上部の 'formUrl' 変数にファイル URI 値を追加しました。
  • 特定のファイルを URI で分析するには、''begin_recognize_invoices_from_url' メソッドを使用します。
  • わかりやすくするために、サービスから返されるフィールドはすべてここには表示されません。 サポートされているすべてのフィールドと対応する型の一覧については、請求書の概念に関するページを参照してください。

事前構築済みモデルを選択する

請求書に限らず、複数の事前構築済みモデルから選択できます。各モデルには、独自のサポートされているフィールドのセットが含まれます。 analyze 操作に使用するモデルは、分析するドキュメントの種類によって異なります。 Document Intelligence サービスで現在サポートされている事前構築済みモデルを次に示します。

  • 請求書: 請求書からテキスト、選択マーク、テーブル、フィールド、キー情報を抽出します。
  • レシート: レシートからテキストとキー情報を抽出します。
  • 身分証明書: 運転免許証と国際パスポートからテキストとキー情報を抽出します。
  • 名刺: 名刺からテキストとキー情報を抽出します。

事前構築済みの請求書アプリケーションの key 変数の下に、次のコードを追加する


def recognize_invoice():

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

    form_recognizer_client = FormRecognizerClient(
        endpoint=endpoint, credential=AzureKeyCredential(key)
    )

    poller = form_recognizer_client.begin_recognize_invoices_from_url(
        invoiceUrl, locale="en-US"
    )
    invoices = poller.result()

    for idx, invoice in enumerate(invoices):
        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):
            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,
                )
            )


if __name__ == "__main__":
    recognize_invoice()

アプリケーションを実行する

  1. form_recognizer_quickstart.py ファイルがあるフォルダーに移動します。

  2. ご利用のターミナルで、次のコマンドを入力します。

python form_recognizer_quickstart.py

| Document Intelligence REST API | Azure REST API リファレンス |

このクイックスタートでは、次の API を使用して、フォームとドキュメントから構造化データを抽出します。

前提条件

  • Azure サブスクリプション - 無料アカウントを作成します

  • インストールされた cURL

  • PowerShell バージョン 6.0 以降、または同様のコマンド ライン アプリケーション。

  • Azure AI サービスまたは Document Intelligence リソース。 Azure サブスクリプションを用意できたら、Azure portal で単一サービスまたはマルチサービスの Document Intelligence リソースを作成し、キーとエンドポイントを取得します。 Free 価格レベル (F0) を使用してサービスを試用し、後から運用環境用の有料レベルにアップグレードすることができます。

    ヒント

    1 つのエンドポイント/キーで複数の Azure AI サービスにアクセスする予定の場合は、Azure AI サービス リソースを作成します。 Document Intelligence へのアクセスのみの場合は、Document Intelligence リソースを作成します。 Microsoft Entra 認証を使用する場合は、単一サービス リソースが必要になることに注意してください。

  • リソースがデプロイされたら、 [リソースに移動] を選択します。 アプリケーションを Document Intelligence API に接続するには、作成したリソースのキーとエンドポイントが必要になります。 このクイックスタートで後に示すコードに、自分のキーとエンドポイントを貼り付けます。

    Azure portal のキーとエンドポイントの場所のスクリーンショット。

コピーしてアプリケーションに貼り付けるコード サンプルを選択します。

重要

終わったらコードからキーを削除し、公開しないよう注意してください。 運用環境では、Azure Key Vault などの資格情報を格納してアクセスする安全な方法を使用します。 詳しくは、Azure AI サービスのセキュリティを "参照してください"。

試してみる: レイアウト モデル

  • この例では、URI にドキュメント ファイルが必要になります。 このクイックスタートでは、サンプル ドキュメントを使用できます。
  1. {endpoint} を、Document Intelligence サブスクリプションで取得したエンドポイントで置き換えます。
  2. {key} を、前の手順からコピーしたキーに置き換えます。
  3. \"{your-document-url} をサンプル ドキュメントの URL に置き換えます。
https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/sample-layout.pdf

Request

curl -v -i POST "https://{endpoint}/formrecognizer/v2.1/layout/analyze" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: {key}" --data-ascii "{​​​​​​​'urlSource': '{your-document-url}'}​​​​​​​​"

Operation-Location

Operation-Location ヘッダーを含む 202 (Success) 応答を受信します。 このヘッダーの値に含まれる結果 ID を使用して、非同期操作の状態のクエリを実行し、結果を取得できます。

https://cognitiveservice/formrecognizer/v2.1/layout/analyzeResults/ {resultId}

次の例では、URL の一部として、analyzeResults/ の後の文字列が結果 ID になります。

https://cognitiveservice/formrecognizer/v2/layout/analyzeResults/54f0b076-4e38-43e5-81bd-b85b8835fdfb

レイアウトの結果を取得する

Analyze Layout API を呼び出した後、Get Analyze Layout Result API を呼び出して、操作の状態と抽出されたデータを取得します。 コマンドを実行する前に、次の変更を行います。

  1. {endpoint} を、Document Intelligence サブスクリプションで取得したエンドポイントで置き換えます。
  2. {key} を、前の手順からコピーしたキーに置き換えます。
  3. {resultId} を、前の手順の結果 ID に置き換えます。

Request

curl -v -X GET "https://{endpoint}/formrecognizer/v2.1/layout/analyzeResults/{resultId}" -H "Ocp-Apim-Subscription-Key: {key}"

結果を確認する

JSON コンテンツを含む 200 (success) 応答が返されます。

次の請求書の画像とそれに対応する JSON 出力をご覧ください。

  • "readResults" ノードには、あらゆるテキスト行が、ページ上の対応する境界ボックスの配置と共に表示されます。
  • selectionMarks ノードには、すべての選択マーク (チェック ボックス、ラジオ マーク) と、その状態が selectedunselected のどちらであるかが示されます。
  • 抽出された表は、"pageResults" セクションに含まれています。 それぞれの表について、テキスト、行インデックス、列インデックス、行スパン、列スパン、境界ボックスなどが抽出されます。

表を含む Contoso プロジェクト ステートメント ドキュメント。

応答本文

GitHub での完全なサンプル出力に関する記事を参照してください。

試してみる: 事前構築済みモデル

  • この例では、事前構築済みモデルを使用して請求書ドキュメントを分析します。 このクイックスタートでは、Microsoft のサンプル請求書ドキュメントを使用できます。

事前構築済みモデルを選択する

請求書に限らず、複数の事前構築済みモデルから選択できます。各モデルには、独自のサポートされているフィールドのセットが含まれます。 analyze 操作に使用するモデルは、分析するドキュメントの種類によって異なります。 Document Intelligence サービスで現在サポートされている事前構築済みモデルを次に示します。

  • 請求書: 請求書からテキスト、選択マーク、テーブル、フィールド、キー情報を抽出します。
  • レシート: レシートからテキストとキー情報を抽出します。
  • 身分証明書: 運転免許証と国際パスポートからテキストとキー情報を抽出します。
  • 名刺: 名刺からテキストとキー情報を抽出します。

コマンドを実行する前に、次の変更を行います。

  1. {endpoint} を、Document Intelligence サブスクリプションで取得したエンドポイントで置き換えます。

  2. {key} を、前の手順からコピーしたキーに置き換えます。

  3. \"{your-document-url} をサンプル請求書の URL に置き換えます。

    https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/sample-invoice.pdf
    

Request

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 "{​​​​​​​'urlSource': '{your invoice URL}'}​​​​​​​​"

Operation-Location

Operation-Location ヘッダーを含む 202 (Success) 応答を受信します。 このヘッダーの値に含まれる結果 ID を使用して、非同期操作の状態のクエリを実行し、結果を取得できます。

https://cognitiveservice/formrecognizer/v2.1/prebuilt/receipt/analyzeResults/ {resultId}

次の例では、URL の一部として、analyzeResults/ の後の文字列が結果 ID になります。

https://cognitiveservice/formrecognizer/v2.1/prebuilt/invoice/analyzeResults/54f0b076-4e38-43e5-81bd-b85b8835fdfb

請求書の結果を取得する

Analyze Invoice API を呼び出した後、Get Analyze Invoice Result API を呼び出して、操作の状態と抽出されたデータを取得します。 コマンドを実行する前に、次の変更を行います。

  1. {endpoint} を、Document Intelligence キーで取得したエンドポイントで置き換えます。 これは Document Intelligence リソースの [概要] タブで確認できます。
  2. {resultId} を、前の手順の結果 ID に置き換えます。
  3. {key} をご自分のキーに置き換えます。

Request

curl -v -X GET "https://{endpoint}/formrecognizer/v2.1/prebuilt/invoice/analyzeResults/{resultId}" -H "Ocp-Apim-Subscription-Key: {key}"

結果の確認

JSON 出力で 200 (Success) 応答を受信します。

  • "readResults" フィールドには、請求書から抽出された各テキスト行が含まれます。
  • "pageResults" には、請求書から抽出されたテーブルと選択マークが含まれます。
  • "documentResults" フィールドには、請求書の最も重要な部分のキーと値の情報が含まれます。

サンプル請求書に関するドキュメントを参照してください。

応答本文

GitHub で完全なサンプル出力を参照してください。

これで完了です。お疲れさまでした。

次のステップ

  • 強化されたエクスペリエンスと高度なモデル品質のためには、Document Intelligence Studio をお試しください。

    • Studio では、v2.1 ラベル付きデータでトレーニングされたすべてのモデルがサポートされます。

    • 変更ログでは、v3.1 から v4.0 への移行に関する詳細情報が提供されます。