다음을 통해 공유


문서 인텔리전스 시작

Important

  • Azure Cognitive Services Form Recognizer는 이제 Azure AI 문서 인텔리전스입니다.
  • 일부 플랫폼은 여전히 이름 변경 업데이트를 기다리고 있습니다.
  • 설명서에서 Form Recognizer 또는 문서 인텔리전스에 대한 모든 언급은 동일한 Azure 서비스를 나타냅니다.

이 콘텐츠의 적용 대상:확인 표시v4.0(미리 보기)이전 버전:파란색 확인 표시v3.1(GA)파란색 확인 표시v3.0(GA)

  • Azure AI 문서 인텔리전스 최신 미리 보기 버전(2024-07-31-preview)을 시작합니다.

이 콘텐츠의 적용 대상:확인 표시v3.1(GA)이전 버전:파란색 확인 표시v3.0파란색 확인 표시v2.1

  • Azure Form Recognizer 최신 GA 버전(2023-07-31)을 시작합니다.

이 콘텐츠의 적용 대상:확인 표시v3.0(GA)최신 버전:파란색 확인 표시v3.1파란색 확인 표시v2.1

  • Azure Form Recognizer 레거시 GA 버전(2022-08-31)을 시작합니다.
  • Azure AI 문서 인텔리전스/Form Recognizer는 기계 학습을 사용하여 문서에서 키-값 쌍, 텍스트, 테이블 및 주요 데이터를 추출하는 클라우드 기반 Azure AI 서비스입니다.

  • 프로그래밍 언어 SDK를 사용하거나 REST API를 호출하여 문서 처리 모델을 워크플로 및 애플리케이션에 쉽게 통합할 수 있습니다.

  • 이 빠른 시작의 경우 기술을 학습할 때 무료 서비스를 사용하는 것이 좋습니다. 체험판 페이지는 한 달에 500페이지로 제한됩니다.

API 기능 및 개발 옵션에 대한 자세한 내용은 개요 페이지를 참조하세요.

이 빠른 시작에서는 다음 기능을 사용하여 양식 및 문서에서 데이터와 값을 분석하고 추출합니다.

  • 레이아웃 모델 - 모델을 학습시킬 필요 없이 문서의 라디오 단추 및 확인란과 같은 테이블, 선, 단어, 선택 표시를 분석하고 추출합니다.

  • 미리 빌드된 모델 - 미리 빌드된 모델을 사용하여 특정 문서 형식에서 공통 필드를 분석하고 추출합니다.

필수 조건

  • Azure AI 서비스 또는 문서 인텔리전스 리소스입니다. Azure 구독이 있으면 Azure Portal에서 단일 서비스 또는 Azure AI 다중 서비스 리소스를 만들어 키와 엔드포인트를 가져옵니다.

  • 평가판 가격 책정 계층(F0)을 통해 서비스를 사용해보고, 나중에 프로덕션용 유료 계층으로 업그레이드할 수 있습니다.

단일 엔드포인트/키에서 여러 Azure AI 서비스에 액세스하려는 경우 Azure AI 서비스 리소스를 만듭니다. 문서 인텔리전스 액세스에 대해서만 문서 인텔리전스 리소스를 만듭니다. Microsoft Entra 인증을 사용하려는 경우 단일 서비스 리소스가 필요합니다.

  • 리소스를 배포한 후 리소스로 이동을 선택합니다. 애플리케이션을 문서 인텔리전스 API에 연결하려면 만든 리소스의 키와 엔드포인트가 필요합니다. 키와 엔드포인트는 이 빠른 시작의 뒷부분에서 코드에 붙여넣습니다.

    Azure Portal에서 키 및 엔드포인트 위치의 스크린샷

  • Azure AI 서비스 또는 Form Recognizer 리소스입니다. Azure 구독이 있으면 Azure Portal에서 단일 서비스 또는 Azure AI 다중 서비스 리소스를 만들어 키와 엔드포인트를 가져옵니다.

  • 평가판 가격 책정 계층(F0)을 통해 서비스를 사용해보고, 나중에 프로덕션용 유료 계층으로 업그레이드할 수 있습니다.

단일 엔드포인트/키에서 여러 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 프로젝트를 마우스 오른쪽 단추로 클릭하고 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 레거시 패키지 선택의 스크린샷.

애플리케이션 빌드

문서 인텔리전스 서비스와 상호 작용하려면 DocumentIntelligenceClient 클래스의 인스턴스를 만들어야 합니다. 이렇게 하려면 Azure Portal에서 key를 사용하여 AzureKeyCredential을 만들고, AzureKeyCredential 및 문서 인텔리전스 endpoint를 사용하여 DocumentIntelligenceClient 인스턴스를 만듭니다.

Form Recognizer 서비스와 상호 작용하려면 DocumentAnalysisClient 클래스의 인스턴스를 만들어야 합니다. 이렇게 하려면 Azure Portal에서 keyAzureKeyCredential을 만들고 AzureKeyCredential 및 Form Recognizer endpoint를 사용하여 DocumentAnalysisClient 인스턴스를 만듭니다.

참고 항목

  • .NET 6부터 console 템플릿을 사용하는 새 프로젝트는 이전 버전과 다른 새 프로그램 스타일을 생성합니다.
  • 새 출력에서는 작성해야 하는 코드를 간소화하는 최신 C# 기능을 사용합니다.
  • 최신 버전을 사용하는 경우 Main 메서드 본문을 작성하기만 하면 됩니다. 최상위 문, 전역 using 지시문 또는 암시적 using 지시문을 포함할 필요가 없습니다.
  • 자세한 내용은 최상위 문을 생성하는 새 C# 템플릿참조하세요.
  1. Program.cs 파일을 엽니다.

  2. Console.Writeline("Hello World!") 줄을 포함하여 기존 코드를 삭제하고 다음 코드 샘플 중 하나를 선택하여 복사하고 애플리케이션의 Program.cs 파일에 붙여넣습니다.

Important

완료되면 코드에서 키를 제거하고 공개적으로 게시하지 마세요. 프로덕션의 경우 Azure Key Vault와 같은 자격 증명을 안전하게 저장하고 액세스하는 방법을 사용합니다. 자세한 내용은 Azure AI 서비스 보안참조하세요.

레이아웃 모델

문서에서 텍스트, 선택 표시, 텍스트 스타일, 테이블 구조, 경계 영역 좌표를 추출합니다.

  • 이 예에서는 URI의 문서 파일이 필요합니다. 이 빠른 시작을 위해 샘플 문서를 사용할 수 있습니다.
  • 파일 URI 값을 스크립트 상단에 있는 Uri fileUri 변수에 추가합니다.
  • URI의 지정된 파일에서 레이아웃을 추출하려면 StartAnalyzeDocumentFromUri 메서드를 사용하고 prebuilt-layout을 모델 ID로 전달합니다. 반환된 값은 제출된 문서의 데이터가 포함된 AnalyzeResult 개체입니다.

Program.cs 파일에 다음 코드 샘플을 추가합니다. Azure Portal 문서 인텔리전스 인스턴스의 값으로 키 및 엔드포인트 변수를 업데이트해야 합니다.


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 작업에 사용할 모델은 분석할 문서 형식에 따라 달라집니다. 모델 데이터 추출을 참조하세요.

  • 미리 빌드된 청구서 모델을 사용하여 청구서를 분석합니다. 이 빠른 시작에는 샘플 청구서 문서를 사용할 수 있습니다.
  • 파일 URI 값을 Program.cs 파일의 상단에 있는 Uri invoiceUri 변수에 추가했습니다.
  • URI에서 지정된 파일을 분석하려면 StartAnalyzeDocumentFromUri 메서드를 사용하고 prebuilt-invoice를 모델 ID로 전달합니다. 반환된 값은 제출된 문서의 데이터가 포함된 AnalyzeResult 개체입니다.
  • 간단히 하기 위해 서비스에서 반환하는 모든 키-값 쌍이 여기에 표시되지는 않습니다. 지원되는 모든 필드 및 해당 형식의 목록을 보려면 청구서 개념 페이지를 참조하세요.

Program.cs 파일에 다음 코드 샘플을 추가합니다. Azure Portal 문서 인텔리전스 인스턴스의 값으로 키 및 엔드포인트 변수를 업데이트해야 합니다.


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 번들, JDK(Java Development Kit) 및 Microsoft에서 제안하는 확장 컬렉션입니다. 코딩 팩을 사용하여 기존 개발 환경을 수정할 수도 있습니다.
    • VS Code와 Java용 코딩 팩을 사용하는 경우 Java용 Gradle 확장을 설치합니다.
  • Visual Studio Code를 사용하지 않는 경우 개발 환경에 다음이 설치되어 있는지 확인합니다.

  • Azure AI 서비스 또는 문서 인텔리전스 리소스입니다. Azure 구독이 있으면 Azure Portal에서 단일 서비스 또는 다중 서비스 문서 인텔리전스 리소스를 만들어 키와 엔드포인트를 가져옵니다. 평가판 가격 책정 계층(F0)을 통해 서비스를 사용해보고, 나중에 프로덕션용 유료 계층으로 업그레이드할 수 있습니다.

    단일 엔드포인트/키에서 여러 Azure AI 서비스에 액세스하려는 경우 Azure AI 서비스 리소스를 만듭니다. 문서 인텔리전스 액세스에 대해서만 문서 인텔리전스 리소스를 만듭니다. Microsoft Entra 인증을 사용하려는 경우 단일 서비스 리소스가 필요합니다.

  • 리소스를 배포한 후 리소스로 이동을 선택합니다. 애플리케이션을 문서 인텔리전스 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 명령을 실행합니다. 이 명령은 build.gradle.kts를 포함하여 런타임에 애플리케이션을 만들고 구성하는 데 사용되는 Gradle용 필수 빌드 파일을 만듭니다.

    gradle init --type basic
    
  3. DSL을 선택하라는 메시지가 표시되면 Kotlin을 선택합니다.

  4. Return 또는 Enter를 선택하여 기본 프로젝트 이름(doc-intel-app)을 수락합니다.

  1. 콘솔 창(예: cmd, PowerShell 또는 Bash)에서 form-recognizer-app이라는 앱에 대한 새 디렉터리를 만들고 이 디렉터리로 이동합니다.

    mkdir form-recognize-app && form-recognize-app
    
    mkdir form-recognize-app; cd form-recognize-app
    
  2. 작업 디렉터리에서 gradle init 명령을 실행합니다. 이 명령은 build.gradle.kts를 포함하여 런타임에 애플리케이션을 만들고 구성하는 데 사용되는 Gradle용 필수 빌드 파일을 만듭니다.

    gradle init --type basic
    
  3. DSL을 선택하라는 메시지가 표시되면 Kotlin을 선택합니다.

  4. Return 또는 Enter를 선택하여 기본 프로젝트 이름(form-recognize-app)을 적용합니다.

클라이언트 라이브러리 설치

이 빠른 시작에서는 Gradle 종속성 관리자를 사용합니다. 다른 종속성 관리자에 대한 클라이언트 라이브러리 및 정보는 Maven 중앙 리포지토리에서 찾을 수 있습니다.

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 중앙 리포지토리에서 찾을 수 있습니다.

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 중앙 리포지토리에서 찾을 수 있습니다.

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 애플리케이션 만들기

문서 인텔리전스 서비스와 상호 작용하려면 DocumentIntelligenceClient 클래스의 인스턴스를 만들어야 합니다. 이렇게 하려면 Azure Portal에서 key를 사용하여 AzureKeyCredential을 만들고, AzureKeyCredential 및 문서 인텔리전스 endpoint를 사용하여 DocumentIntelligenceClient 인스턴스를 만듭니다.

문서 인텔리전스 서비스와 상호 작용하려면 DocumentAnalysisClient 클래스의 인스턴스를 만들어야 합니다. 이렇게 하려면 Azure Portal에서 key를 사용하여 AzureKeyCredential을 만들고, AzureKeyCredential 및 문서 인텔리전스 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 파일을 엽니다. 다음 코드 샘플 중 하나를 복사하여 애플리케이션에 붙여넣습니다.

Important

완료되면 코드에서 키를 제거하고 공개적으로 게시하지 마세요. 프로덕션의 경우 Azure Key Vault와 같은 자격 증명을 안전하게 저장하고 액세스하는 방법을 사용합니다. 자세한 내용은 Azure AI 서비스 보안참조하세요.

레이아웃 모델

문서에서 텍스트, 선택 표시, 텍스트 스타일, 테이블 구조, 경계 영역 좌표를 추출합니다.

  • 이 예에서는 URI에 문서 파일이 필요합니다. 이 빠른 시작을 위해 샘플 문서를 사용할 수 있습니다.
  • URI에서 지정된 파일을 분석하려면 beginAnalyzeDocumentFromUrl 메서드를 사용하고 prebuilt-layout을 모델 ID로 전달합니다. 반환된 값은 제출된 문서에 대한 데이터를 포함하는 AnalyzeResult 개체입니다.
  • 기본 메서드의 documentUrl 변수에 파일 URI 값을 추가했습니다.

DocIntelligence.java 파일에 다음 코드를 추가합니다. Azure Portal 문서 인텔리전스 인스턴스의 값으로 키 및 엔드포인트 변수를 업데이트해야 합니다.


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 문서 인텔리전스 인스턴스의 값으로 키 및 엔드포인트 변수를 업데이트해야 합니다.


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 문서 인텔리전스 인스턴스의 값으로 키 및 엔드포인트 변수를 업데이트해야 합니다.


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 작업에 사용할 모델은 분석할 문서 형식에 따라 달라집니다. 모델 데이터 추출을 참조하세요.

  • 미리 빌드된 청구서 모델을 사용하여 청구서를 분석합니다. 이 빠른 시작에는 샘플 청구서 문서를 사용할 수 있습니다.
  • 파일 URL 값을 파일 상단에 있는 invoiceUrl 변수에 추가했습니다.
  • URI에서 지정된 파일을 분석하기 위해 beginAnalyzeDocuments 메서드를 사용하고 모델 ID로 PrebuiltModels.Invoice을 전달합니다. 반환된 값은 제출된 문서에 대한 데이터가 포함된 result 개체입니다.
  • 간단히 하기 위해 서비스에서 반환하는 모든 키-값 쌍이 여기에 표시되지는 않습니다. 지원되는 모든 필드 및 해당 형식의 목록을 보려면 청구서 개념 페이지를 참조하세요.

DocIntelligence.java 파일에 다음 코드를 추가합니다. Azure Portal 문서 인텔리전스 인스턴스의 값으로 키 및 엔드포인트 변수를 업데이트해야 합니다.


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 문서 인텔리전스 인스턴스의 값으로 키 및 엔드포인트 변수를 업데이트해야 합니다.


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 문서 인텔리전스 인스턴스의 값으로 키 및 엔드포인트 변수를 업데이트해야 합니다.


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참조하세요.

  • Node.js의 최신 LTS 버전입니다.

  • Azure AI 서비스 또는 문서 인텔리전스 리소스입니다. Azure 구독이 있으면 Azure Portal에서 단일 서비스 또는 다중 서비스 문서 인텔리전스 리소스를 만들어 키와 엔드포인트를 가져옵니다. 평가판 가격 책정 계층(F0)을 통해 서비스를 사용해보고, 나중에 프로덕션용 유료 계층으로 업그레이드할 수 있습니다.

    단일 엔드포인트/키에서 여러 Azure AI 서비스에 액세스하려는 경우 Azure AI 서비스 리소스를 만듭니다. 문서 인텔리전스 액세스에 대해서만 문서 인텔리전스 리소스를 만듭니다. Microsoft Entra 인증을 사용하려는 경우 단일 서비스 리소스가 필요합니다.

  • 리소스를 배포한 후 리소스로 이동을 선택합니다. 애플리케이션을 문서 인텔리전스 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 리포지토리, 키워드, 작성자, 라이선스 정보는 선택적 특성이며 이 프로젝트에서 건너뛸 수 있습니다.
    • Return 또는 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 명령을 입력합니다.

애플리케이션 빌드

문서 인텔리전스 서비스와 상호 작용하려면 DocumentIntelligenceClient 클래스의 인스턴스를 만들어야 합니다. 이렇게 하려면 Azure Portal에서 key를 사용하여 AzureKeyCredential을 만들고, AzureKeyCredential 및 문서 인텔리전스 endpoint를 사용하여 DocumentIntelligenceClient 인스턴스를 만듭니다.

문서 인텔리전스 서비스와 상호 작용하려면 DocumentAnalysisClient 클래스의 인스턴스를 만들어야 합니다. 이렇게 하려면 Azure Portal에서 keyAzureKeyCredential을 만들고 AzureKeyCredential 및 Form Recognizer endpoint를 사용하여 DocumentAnalysisClient 인스턴스를 만듭니다.

  1. Visual Studio Code 또는 즐겨찾는 IDE에서 index.js 파일을 엽니다. 다음 코드 샘플 중 하나를 복사하여 애플리케이션에 붙여넣습니다.

Important

완료되면 코드에서 키를 제거하고 공개적으로 게시하지 마세요. 프로덕션의 경우 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. 문서 인텔리전스 애플리케이션(doc-intel-app)이 있는 폴더로 이동합니다.

  2. 터미널에 다음 명령을 입력합니다.

    node index.js
    

index.js 파일에 다음 코드를 추가합니다. Azure Portal 문서 인텔리전스 인스턴스의 값으로 키 및 엔드포인트 변수를 업데이트해야 합니다.


 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. 문서 인텔리전스 애플리케이션(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 작업에 사용할 모델은 분석할 문서 형식에 따라 달라집니다. 모델 데이터 추출을 참조하세요.

  • 미리 빌드된 청구서 모델을 사용하여 청구서를 분석합니다. 이 빠른 시작에는 샘플 청구서 문서를 사용할 수 있습니다.
  • 파일 URL 값을 파일 상단에 있는 invoiceUrl 변수에 추가했습니다.
  • 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. 문서 인텔리전스 애플리케이션(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. 문서 인텔리전스 애플리케이션(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. 문서 인텔리전스 애플리케이션(doc-intel-app)이 있는 폴더로 이동합니다.

  2. 터미널에 다음 명령을 입력합니다.

    node index.js
    

이 빠른 시작에서는 다음 기능을 사용하여 양식 및 문서에서 데이터를 분석하고 추출합니다.

  • 레이아웃 - 모델을 학습할 필요 없이 테이블, 선, 단어 및 선택 표시(예: 라디오 단추 및 확인란), 키-값 쌍을 분석하고 추출합니다.

  • 미리 빌드된 청구서—미리 학습된 모델을 사용하여 특정 문서 형식에서 공통 필드를 분석하고 추출합니다.

필수 조건

  • Azure 구독 - 체험 구독 만들기

  • Python 3.7 이상.

    • Python 설치에 pip가 포함되어야 합니다. 명령줄에서 pip --version을 실행하여 pip가 설치되어 있는지 확인할 수 있습니다. 최신 버전의 Python을 설치하여 pip를 받으세요.
  • 최신 버전의 Visual Studio Code 또는 선호하는 IDE 자세한 내용은 Visual Studio Code에서 Python 시작참조하세요.

  • Azure AI 서비스 또는 문서 인텔리전스 리소스입니다. Azure 구독이 있으면 Azure Portal에서 단일 서비스 또는 다중 서비스 문서 인텔리전스 리소스를 만들어 키와 엔드포인트를 가져옵니다. 평가판 가격 책정 계층(F0)을 통해 서비스를 사용해보고, 나중에 프로덕션용 유료 계층으로 업그레이드할 수 있습니다.

단일 엔드포인트/키에서 여러 Azure AI 서비스에 액세스하려는 경우 Azure AI 서비스 리소스를 만듭니다. 문서 인텔리전스 액세스에 대해서만 문서 인텔리전스 리소스를 만듭니다. Microsoft Entra 인증을 사용하려는 경우 단일 서비스 리소스가 필요합니다.

  • 리소스를 배포한 후 리소스로 이동을 선택합니다. 애플리케이션을 문서 인텔리전스 API에 연결하려면 만든 리소스의 키와 엔드포인트가 필요합니다. 키와 엔드포인트는 이 빠른 시작의 뒷부분에서 코드에 붙여넣습니다.

    Azure Portal에서 키 및 엔드포인트 위치의 스크린샷

설정

로컬 환경에서 터미널 창을 열고 pip를 사용하여 Python용 Azure AI 문서 인텔리전스 클라이언트 라이브러리를 설치합니다.

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 애플리케이션 만들기

문서 인텔리전스 서비스와 상호 작용하려면 DocumentIntelligenceClient 클래스의 인스턴스를 만들어야 합니다. 이렇게 하려면 Azure Portal에서 key를 사용하여 AzureKeyCredential을 만들고, AzureKeyCredential 및 문서 인텔리전스 endpoint를 사용하여 DocumentIntelligenceClient 인스턴스를 만듭니다.

  1. 원하는 편집기나 IDE에서 doc_intel_quickstart.py라는 새 Python 파일을 만듭니다.

  2. doc_intel_quickstart.py 파일을 열고 다음 코드 샘플 중 하나를 선택하여 복사하여 애플리케이션에 붙여넣습니다.

문서 인텔리전스 서비스와 상호 작용하려면 DocumentAnalysisClient 클래스의 인스턴스를 만들어야 합니다. 이렇게 하려면 Azure Portal에서 key를 사용하여 AzureKeyCredential을 만들고, AzureKeyCredential 및 문서 인텔리전스 endpoint를 사용하여 DocumentAnalysisClient 인스턴스를 만듭니다.

  1. 기본 설정 편집기 또는 IDE에서 form_recognizer_quickstart.py라는 새 Python 파일을 만듭니다.

  2. form_recognizer_quickstart.py 파일을 열고 다음 코드 샘플 중 하나를 선택하여 복사하여 애플리케이션에 붙여넣습니다.

Important

완료되면 코드에서 키를 제거하고 공개적으로 게시하지 마세요. 프로덕션의 경우 Azure Key Vault와 같은 자격 증명을 안전하게 저장하고 액세스하는 방법을 사용합니다. 자세한 내용은 Azure AI 서비스 보안참조하세요.

레이아웃 모델

문서에서 텍스트, 선택 표시, 텍스트 스타일, 테이블 구조, 경계 영역 좌표를 추출합니다.

  • 이 예에서는 URL의 문서 파일이 필요합니다. 이 빠른 시작을 위해 샘플 문서를 사용할 수 있습니다.
  • analyze_layout 함수의 formUrl 변수에 파일 URL 값을 추가했습니다.

doc_intel_quickstart.py 애플리케이션에 다음 코드 샘플을 추가합니다. Azure Portal 문서 인텔리전스 인스턴스의 값으로 키 및 엔드포인트 변수를 업데이트해야 합니다.


# 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 메서드를 사용하고 모델 ID로 prebuilt-layout를 전달합니다. 반환된 값은 제출된 문서에 대한 데이터가 포함된 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 작업에 사용할 모델은 분석할 문서 형식에 따라 달라집니다. 모델 데이터 추출을 참조하세요.

  • 미리 빌드된 청구서 모델을 사용하여 청구서를 분석합니다. 이 빠른 시작에는 샘플 청구서 문서를 사용할 수 있습니다.
  • 파일 URL 값을 파일 상단에 있는 invoiceUrl 변수에 추가했습니다.
  • 간단히 하기 위해 서비스에서 반환하는 모든 키-값 쌍이 여기에 표시되지는 않습니다. 지원되는 모든 필드 및 해당 형식의 목록을 보려면 청구서 개념 페이지를 참조하세요.

doc_intel_quickstart.py 애플리케이션에 다음 코드 샘플을 추가합니다. Azure Portal 문서 인텔리전스 인스턴스의 값으로 키 및 엔드포인트 변수를 업데이트해야 합니다.


# 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 메서드를 사용하고 모델 ID로 prebuilt-invoice을 전달합니다. 반환된 값은 제출된 문서에 대한 데이터가 포함된 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
    

이 빠른 시작에서는 문서 인텔리전스 REST API를 사용하여 문서에서 데이터와 값을 분석하고 추출하는 방법을 알아봅니다.

필수 조건

  • Azure 구독 - 체험 구독 만들기

  • curl 명령줄 도구가 설치되었습니다.

  • PowerShell 버전 7.*+(또는 비슷한 명령줄 애플리케이션):

  • PowerShell 버전을 확인하려면 운영 체제에 따라 다음 명령을 입력합니다.

    • Windows: Get-Host | Select-Object Version
    • macOS 또는 Linux: $PSVersionTable
  • 문서 인텔리전스(단일 서비스) 또는 Azure AI 서비스(다중 서비스) 리소스입니다. Azure 구독이 있으면 Azure Portal에서 단일 서비스 또는 다중 서비스 문서 인텔리전스 리소스를 만들어 키와 엔드포인트를 가져옵니다. 평가판 가격 책정 계층(F0)을 통해 서비스를 사용해보고, 나중에 프로덕션용 유료 계층으로 업그레이드할 수 있습니다.

단일 엔드포인트/키에서 여러 Azure AI 서비스에 액세스하려는 경우 Azure AI 서비스 리소스를 만듭니다. 문서 인텔리전스 액세스에 대해서만 문서 인텔리전스 리소스를 만듭니다. Microsoft Entra 인증을 사용하려는 경우 단일 서비스 리소스가 필요합니다.

  • 리소스를 배포한 후 리소스로 이동을 선택합니다. 애플리케이션을 문서 인텔리전스 API에 연결하려면 만든 리소스의 키와 엔드포인트가 필요합니다. 키와 엔드포인트는 이 빠른 시작의 뒷부분에서 코드에 붙여넣습니다.

    Azure Portal에서 키 및 엔드포인트 위치의 스크린샷

문서 분석 및 결과 가져오기

POST 요청은 미리 빌드된 또는 사용자 지정 모델로 문서를 분석하는 데 사용됩니다. GET 요청은 문서 분석 호출의 결과를 검색하는 데 사용됩니다. modelId는 POST 작업과 함께 사용되고 resultId는 GET 작업과 함께 사용됩니다.

문서 분석(POST 요청)

cURL 명령을 실행하기 전에 post 요청을 다음과 같이 변경합니다.

  1. {endpoint}를 Azure Portal 문서 인텔리전스 인스턴스의 엔드포인트 값으로 바꿉니다.

  2. {key}를 Azure Portal 문서 인텔리전스 인스턴스의 키 값으로 바꿉니다.

  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
레이아웃 prebuilt-layout 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
영수증 prebuilt-receipt https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/receipt.png
ID 문서 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}
일반 문서 prebuilt-document 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
레이아웃 prebuilt-layout 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
영수증 prebuilt-receipt https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/receipt.png
ID 문서 prebuilt-idDocument https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/rest-api/identity_documents.png
명함 prebuilt-businessCard https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/de5e0d8982ab754823c54de47a47e8e499351523/curl/form-recognizer/rest-api/business_card.jpg

Important

완료되면 코드에서 키를 제거하고 공개적으로 게시하지 마세요. 프로덕션의 경우 Azure Key Vault와 같은 자격 증명을 안전하게 저장하고 액세스하는 방법을 사용합니다. 자세한 내용은 Azure AI 서비스 보안참조하세요.

POST 요청

curl -v -i POST "{endpoint}/documentintelligence/documentModels/{modelId}:analyze?api-version=2024-07-31-preview" -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) 응답을 수신합니다. 이 헤더의 값에는 비동기 작업의 상태를 가져오고 동일한 리소스 구독 키를 사용하여 GET 요청을 사용하여 결과를 검색하기 위해 쿼리할 수 있는 resultID가 포함되어 있습니다.

{alt-text}

분석 결과 가져오기(GET 요청)

Analyze document API를 호출한 후 분석 결과 가져오기 API를 호출하여 작업 상태와 추출된 데이터를 가져옵니다. 명령을 실행하기 전에 다음과 같이 변경합니다.

Analyze document API를 호출한 후 분석 결과 가져오기 API를 호출하여 작업 상태와 추출된 데이터를 가져옵니다. 명령을 실행하기 전에 다음과 같이 변경합니다.

Analyze document API를 호출한 후 분석 결과 가져오기 API를 호출하여 작업 상태와 추출된 데이터를 가져옵니다. 명령을 실행하기 전에 다음과 같이 변경합니다.

  1. POST 응답에서 {resultID} Operation-location 헤더를 바꿉니다.

  2. {key}를 Azure Portal에 있는 문서 인텔리전스 인스턴스의 키 값으로 바꿉니다.

GET 요청

curl -v -X GET "{endpoint}/documentintelligence/documentModels/{modelId}/analyzeResults/{resultId}?api-version=2024-07-31-preview" -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초 이상의 간격을 사용하는 것이 좋습니다.

prebuilt-invoice의 샘플 응답

{
    "status": "succeeded",
    "createdDateTime": "2024-03-25T19:31:37Z",
    "lastUpdatedDateTime": "2024-03-25T19:31:43Z",
    "analyzeResult": {
        "apiVersion": "2024-07-31-preview",
        "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
                                }
                      }],
              }]
      }
}

지원되는 문서 필드

미리 빌드된 모델은 미리 정의된 문서 필드 집합을 추출합니다. 추출되는 필드 이름, 유형, 설명 및 예시는 모델 데이터 추출을 참조하세요.

완료되었습니다. 축하합니다!

이 빠른 시작에서는 문서 인텔리전스 모델을 사용하여 다양한 양식과 문서를 분석했습니다. 다음으로 문서 인텔리전스 스튜디오 및 참조 설명서를 탐색하여 문서 인텔리전스 API에 대해 자세히 알아봅니다.

다음 단계

이 콘텐츠의 적용 대상: 확인 표시 v2.1 | 최신 버전:파란색 확인 표시 v4.0(미리 보기)

선택한 프로그래밍 언어 또는 REST API를 사용하여 Azure AI 문서 인텔리전스를 시작합니다. 문서 인텔리전스는 기계 학습을 사용하여 문서에서 키-값 쌍, 텍스트 및 테이블을 추출하는 클라우드 기반 Azure AI 서비스입니다. 기술을 학습할 때 체험판 서비스를 이용하는 것이 좋습니다. 체험판 페이지는 한 달에 500페이지로 제한됩니다.

문서 인텔리전스 기능 및 개발 옵션에 대해 자세히 알아보려면 개요 페이지를 방문하세요.

참조 설명서 | 라이브러리 소스 코드 | 패키지(NuGet) | 샘플

이 빠른 시작에서는 다음 API를 사용하여 양식과 문서에서 구조화된 데이터를 추출합니다.

필수 조건

  • Azure 구독 - 체험 구독 만들기

  • 현재 버전의 Visual Studio IDE

  • Azure AI 서비스 또는 문서 인텔리전스 리소스입니다. Azure 구독이 있으면 Azure Portal에서 단일 서비스 또는 다중 서비스 문서 인텔리전스 리소스를 만들어 키와 엔드포인트를 가져옵니다. 평가판 가격 책정 계층(F0)을 통해 서비스를 사용해보고, 나중에 프로덕션용 유료 계층으로 업그레이드할 수 있습니다.

    단일 엔드포인트/키에서 여러 Azure AI 서비스에 액세스하려는 경우 Azure AI 서비스 리소스를 만듭니다. 문서 인텔리전스 액세스에 대해서만 문서 인텔리전스 리소스를 만듭니다. Microsoft Entra 인증을 사용하려는 경우 단일 서비스 리소스가 필요합니다.

  • 리소스를 배포한 후 리소스로 이동을 선택합니다. 애플리케이션을 문서 인텔리전스 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를 입력합니다.

    문서 인텔리전스 패키지 선택 드롭다운 메뉴를 보여 주는 스크린샷.

  3. 드롭다운 메뉴에서 버전 3.1.1을 선택하고, 설치를 선택합니다.

애플리케이션 빌드

문서 인텔리전스 서비스와 상호 작용하려면 FormRecognizerClient 클래스의 인스턴스를 만들어야 합니다. 이렇게 하려면 키를 사용하여 AzureKeyCredential을 만들고 AzureKeyCredential 및 문서 인텔리전스 endpoint를 사용하여 FormRecognizerClient 인스턴스를 만듭니다.

참고 항목

  • .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 메서드에 복사하여 붙여넣을 코드 샘플을 선택합니다.

Important

완료되면 코드에서 키를 제거하고 공개적으로 게시하지 마세요. 프로덕션의 경우 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}'.");
                    }
                }
            }
        }
    }
}

사용해 보기: 미리 빌드된 모델

이 샘플에서는 청구서를 예로 사용하여 미리 학습된 모델에서 특정 유형의 일반 문서에 있는 데이터를 분석하는 방법을 보여 줍니다.

  • 이 예제에서는 미리 빌드된 모델을 사용하여 청구서 문서를 분석합니다. 이 빠른 시작에는 샘플 청구서 문서를 사용할 수 있습니다.
  • 파일 URI 값을 Main 메서드의 파일 상단에 있는 invoiceUri 변수에 추가했습니다.
  • URI에서 지정된 파일을 분석하려면 StartRecognizeInvoicesFromUriAsync 메서드를 사용합니다.
  • 간단히 하기 위해 서비스가 반환하는 모든 필드가 여기에 표시되지는 않습니다. 지원되는 모든 필드 및 해당 형식의 목록을 보려면 청구서 개념 페이지를 참조하세요.

미리 빌드된 모델 선택

청구서에 국한되지 않습니다. 몇 가지 미리 빌드된 모델 중에서 선택할 수 있으며, 각 모델에는 자체 지원 필드 집합이 있습니다. 분석 작업에 사용할 모델은 분석할 문서 유형에 따라 달라집니다. 현재 문서 인텔리전스 서비스에서 지원되는 미리 빌드된 모델은 다음과 같습니다.

  • 청구서: 청구서에서 텍스트, 선택 표시, 테이블, 필드 및 키 정보를 추출합니다.
  • 영수증: 영수증에서 텍스트 및 키 정보를 추출합니다.
  • ID 문서: 운전 면허증과 국제 여권에서 텍스트 및 키 정보를 추출합니다.
  • 명함: 명함에서 텍스트 및 키 정보를 추출합니다.

다음 코드를 미리 빌드된 청구서 애플리케이션의 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 구독 - 체험 구독 만들기

  • JDK(Java Development Kit), 버전 8 이상 자세한 내용은 지원되는 Java 버전 및 업데이트 일정참조하세요.

  • Azure AI 서비스 또는 문서 인텔리전스 리소스입니다. Azure 구독이 있으면 Azure Portal에서 단일 서비스 또는 다중 서비스 문서 인텔리전스 리소스를 만들어 키와 엔드포인트를 가져옵니다. 평가판 가격 책정 계층(F0)을 통해 서비스를 사용해보고, 나중에 프로덕션용 유료 계층으로 업그레이드할 수 있습니다.

  • 리소스를 배포한 후 리소스로 이동을 선택합니다. 애플리케이션을 문서 인텔리전스 API에 연결하려면 만든 리소스의 키와 엔드포인트가 필요합니다. 키와 엔드포인트는 이 빠른 시작의 뒷부분에서 코드에 붙여넣습니다.

    Azure Portal에서 키 및 엔드포인트 위치의 스크린샷

설정

새 Gradle 프로젝트 만들기

콘솔 창(예: cmd, PowerShell 또는 Bash)에서 form-recognizer-app이라는 앱에 대한 새 디렉터리를 만들고 이 디렉터리로 이동합니다.

mkdir form-recognizer-app && form-recognizer-app
  1. 작업 디렉터리에서 gradle init 명령을 실행합니다. 이 명령은 build.gradle.kts를 포함하여 런타임에 애플리케이션을 만들고 구성하는 데 사용되는 Gradle용 필수 빌드 파일을 만듭니다.

    gradle init --type basic
    
  2. DSL을 선택하라는 메시지가 표시되면 Kotlin을 선택합니다.

  3. 기본 프로젝트 이름(form-recognizer-app)을 적용합니다.

클라이언트 라이브러리 설치

이 빠른 시작에서는 Gradle 종속성 관리자를 사용합니다. 다른 종속성 관리자에 대한 클라이언트 라이브러리 및 정보는 Maven 중앙 리포지토리에서 찾을 수 있습니다.

프로젝트의 build.gradle.kts 파일에서 필요한 플러그 인 및 설정과 함께 클라이언트 라이브러리를 implementation 문으로 포함합니다.

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

Java 파일 만들기

작업 디렉터리에서 다음 명령을 실행합니다.

mkdir -p src/main/java

다음 디렉터리 구조를 만듭니다.

애플리케이션의 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;

애플리케이션의 기본 메서드에 복사하여 붙여넣을 코드 샘플을 선택합니다.

Important

완료되면 코드에서 키를 제거하고 공개적으로 게시하지 마세요. 프로덕션의 경우 Azure Key Vault와 같은 자격 증명을 안전하게 저장하고 액세스하는 방법을 사용합니다. 자세한 내용은 Azure AI 서비스 보안참조하세요.

사용해 보기: 레이아웃 모델

문서에서 경계 영역 좌표와 함께 텍스트, 선택 표시, 텍스트 스타일 및 테이블 구조를 추출합니다.

  • 이 예에서는 URI에 문서 파일이 필요합니다. 이 빠른 시작을 위해 샘플 문서를 사용할 수 있습니다.
  • URI에서 지정된 파일을 분석하려면 beginRecognizeContentFromUrl 메서드를 사용합니다.
  • 기본 메서드의 formUrl 변수에 파일 URI 값을 추가했습니다.

다음 코드를 사용하여 애플리케이션의 FormRecognizer 클래스를 업데이트합니다(Azure Portal 문서 인텔리전스 인스턴스의 값으로 키 및 엔드포인트 변수를 업데이트해야 합니다).


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

사용해 보기: 미리 빌드된 모델

이 샘플에서는 청구서를 예로 사용하여 미리 학습된 모델에서 특정 유형의 일반 문서에 있는 데이터를 분석하는 방법을 보여 줍니다.

  • 이 예제에서는 미리 빌드된 모델을 사용하여 청구서 문서를 분석합니다. 이 빠른 시작에는 샘플 청구서 문서를 사용할 수 있습니다.
  • URI에서 지정된 파일을 분석하려면 beginRecognizeInvoicesFromUrl을 사용합니다.
  • 기본 메서드의 invoiceUrl 변수에 파일 URI 값을 추가했습니다.
  • 간단히 하기 위해 서비스가 반환하는 모든 필드가 여기에 표시되지는 않습니다. 지원되는 모든 필드 및 해당 형식의 목록을 보려면 청구서 개념 페이지를 참조하세요.

미리 빌드된 모델 선택

청구서에 국한되지 않습니다. 몇 가지 미리 빌드된 모델 중에서 선택할 수 있으며, 각 모델에는 자체 지원 필드 집합이 있습니다. 분석 작업에 사용할 모델은 분석할 문서 유형에 따라 달라집니다. 현재 문서 인텔리전스 서비스에서 지원되는 미리 빌드된 모델은 다음과 같습니다.

  • 청구서: 청구서에서 텍스트, 선택 표시, 테이블, 필드 및 키 정보를 추출합니다.
  • 영수증: 영수증에서 텍스트 및 키 정보를 추출합니다.
  • ID 문서: 운전 면허증과 국제 여권에서 텍스트 및 키 정보를 추출합니다.
  • 명함: 명함에서 텍스트 및 키 정보를 추출합니다.

다음 코드를 사용하여 애플리케이션의 FormRecognizer 클래스를 업데이트합니다(Azure Portal 문서 인텔리전스 인스턴스의 값으로 키 및 엔드포인트 변수를 업데이트해야 합니다).


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 서비스 또는 문서 인텔리전스 리소스입니다. Azure 구독이 있으면 Azure Portal에서 단일 서비스 또는 다중 서비스 문서 인텔리전스 리소스를 만들어 키와 엔드포인트를 가져옵니다. 평가판 가격 책정 계층(F0)을 통해 서비스를 사용해보고, 나중에 프로덕션용 유료 계층으로 업그레이드할 수 있습니다.

    단일 엔드포인트/키에서 여러 Azure AI 서비스에 액세스하려는 경우 Azure AI 서비스 리소스를 만듭니다. 문서 인텔리전스 액세스에 대해서만 문서 인텔리전스 리소스를 만듭니다. Microsoft Entra 인증을 사용하려는 경우 단일 서비스 리소스가 필요합니다.

  • 리소스를 배포한 후 리소스로 이동을 선택합니다. 애플리케이션을 문서 인텔리전스 API에 연결하려면 만든 리소스의 키와 엔드포인트가 필요합니다. 키와 엔드포인트는 이 빠른 시작의 뒷부분에서 코드에 붙여넣습니다.

    Azure Portal에서 키 및 엔드포인트 위치의 스크린샷

설정

  1. 새 Node.js 애플리케이션 만들기 콘솔 창(예: cmd, PowerShell 또는 Bash)에서 앱에 대한 새 디렉터리를 만들고 이 디렉터리로 이동합니다.

    mkdir form-recognizer-app && cd form-recognizer-app
    
  2. package.json 파일을 사용하여 노드 애플리케이션을 만들려면 npm init 명령을 실행합니다.

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

애플리케이션에 복사하여 붙여넣을 코드 샘플을 선택합니다.

Important

완료되면 코드에서 키를 제거하고 공개적으로 게시하지 마세요. 프로덕션의 경우 Azure Key Vault와 같은 자격 증명을 안전하게 저장하고 액세스하는 방법을 사용합니다. 자세한 내용은 Azure AI 서비스 보안참조하세요.

사용해 보기: 레이아웃 모델

  • 이 예에서는 URI에 문서 파일이 필요합니다. 이 빠른 시작을 위해 샘플 문서를 사용할 수 있습니다.
  • 파일 URI 값을 파일 상단 근처에 있는 formUrl 변수에 추가합니다.
  • 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);
});

사용해 보기: 미리 빌드된 모델

이 샘플에서는 청구서를 예로 사용하여 미리 학습된 모델에서 특정 유형의 일반 문서에 있는 데이터를 분석하는 방법을 보여 줍니다. 청구서 필드의 전체 목록은 미리 빌드된 개념 페이지를 참조하세요.

  • 이 예제에서는 미리 빌드된 모델을 사용하여 청구서 문서를 분석합니다. 이 빠른 시작에는 샘플 청구서 문서를 사용할 수 있습니다.
  • 파일 URI 값을 파일 상단에 있는 invoiceUrl 변수에 추가합니다.
  • URI에서 지정된 파일을 분석하려면 beginRecognizeInvoices 메서드를 사용합니다.
  • 간단히 하기 위해 서비스가 반환하는 모든 필드가 여기에 표시되지는 않습니다. 지원되는 모든 필드 및 해당 형식의 목록을 보려면 청구서 개념 페이지를 참조하세요.

미리 빌드된 모델 선택

청구서에 국한되지 않습니다. 몇 가지 미리 빌드된 모델 중에서 선택할 수 있으며, 각 모델에는 자체 지원 필드 집합이 있습니다. 분석 작업에 사용할 모델은 분석할 문서 유형에 따라 달라집니다. 현재 문서 인텔리전스 서비스에서 지원되는 미리 빌드된 모델은 다음과 같습니다.

  • 청구서: 청구서에서 텍스트, 선택 표시, 테이블, 필드 및 키 정보를 추출합니다.
  • 영수증: 영수증에서 텍스트 및 키 정보를 추출합니다.
  • ID 문서: 운전 면허증과 국제 여권에서 텍스트 및 키 정보를 추출합니다.
  • 명함: 명함에서 텍스트 및 키 정보를 추출합니다.

다음 코드를 미리 빌드된 청구서 애플리케이션의 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 --version을 실행하여 pip가 설치되어 있는지 확인할 수 있습니다. 최신 버전의 Python을 설치하여 pip를 받으세요.
  • Azure AI 서비스 또는 문서 인텔리전스 리소스입니다. Azure 구독이 있으면 Azure Portal에서 단일 서비스 또는 다중 서비스 문서 인텔리전스 리소스를 만들어 키와 엔드포인트를 가져옵니다. 평가판 가격 책정 계층(F0)을 통해 서비스를 사용해보고, 나중에 프로덕션용 유료 계층으로 업그레이드할 수 있습니다.

    단일 엔드포인트/키에서 여러 Azure AI 서비스에 액세스하려는 경우 Azure AI 서비스 리소스를 만듭니다. 문서 인텔리전스 액세스에 대해서만 문서 인텔리전스 리소스를 만듭니다. Microsoft Entra 인증을 사용하려는 경우 단일 서비스 리소스가 필요합니다.

  • 리소스를 배포한 후 리소스로 이동을 선택합니다. 애플리케이션을 문서 인텔리전스 API에 연결하려면 만든 리소스의 키와 엔드포인트가 필요합니다. 키와 엔드포인트는 이 빠른 시작의 뒷부분에서 코드에 붙여넣습니다.

    Azure Portal에서 키 및 엔드포인트 위치의 스크린샷

설정

로컬 환경에서 터미널 창을 열고 pip를 사용하여 Python용 Azure AI 문서 인텔리전스 클라이언트 라이브러리를 설치합니다.

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"

애플리케이션에 복사하여 붙여넣을 코드 샘플을 선택합니다.

Important

완료되면 코드에서 키를 제거하고 공개적으로 게시하지 마세요. 프로덕션의 경우 Azure Key Vault와 같은 자격 증명을 안전하게 저장하고 액세스하는 방법을 사용합니다. 자세한 내용은 Azure AI 서비스 보안참조하세요.

사용해 보기: 레이아웃 모델

  • 이 예에서는 URI에 문서 파일이 필요합니다. 이 빠른 시작을 위해 샘플 문서를 사용할 수 있습니다.
  • 파일 URI 값을 파일 상단 근처에 있는 formUrl 변수에 추가합니다.
  • 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()

사용해 보기: 미리 빌드된 모델

이 샘플에서는 청구서를 예로 사용하여 미리 학습된 모델에서 특정 유형의 일반 문서에 있는 데이터를 분석하는 방법을 보여 줍니다. 청구서 필드의 전체 목록은 미리 빌드된 개념 페이지를 참조하세요.

  • 이 예제에서는 미리 빌드된 모델을 사용하여 청구서 문서를 분석합니다. 이 빠른 시작에는 샘플 청구서 문서를 사용할 수 있습니다.
  • 파일 상단에 있는 ``formUrl` 변수에 파일 URI 값을 추가했습니다.
  • URI에서 지정된 파일을 분석하려면 ``begin_recognize_invoices_from_url` 메서드를 사용합니다.
  • 간단히 하기 위해 서비스가 반환하는 모든 필드가 여기에 표시되지는 않습니다. 지원되는 모든 필드 및 해당 형식의 목록을 보려면 청구서 개념 페이지를 참조하세요.

미리 빌드된 모델 선택

청구서에 국한되지 않습니다. 몇 가지 미리 빌드된 모델 중에서 선택할 수 있으며, 각 모델에는 자체 지원 필드 집합이 있습니다. 분석 작업에 사용할 모델은 분석할 문서 유형에 따라 달라집니다. 현재 문서 인텔리전스 서비스에서 지원되는 미리 빌드된 모델은 다음과 같습니다.

  • 청구서: 청구서에서 텍스트, 선택 표시, 테이블, 필드 및 키 정보를 추출합니다.
  • 영수증: 영수증에서 텍스트 및 키 정보를 추출합니다.
  • ID 문서: 운전 면허증과 국제 여권에서 텍스트 및 키 정보를 추출합니다.
  • 명함: 명함에서 텍스트 및 키 정보를 추출합니다.

다음 코드를 미리 빌드된 청구서 애플리케이션의 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

| 문서 인텔리전스 REST API | Azure REST API 참조 |

이 빠른 시작에서는 다음 API를 사용하여 양식과 문서에서 구조화된 데이터를 추출합니다.

필수 조건

  • Azure 구독 - 체험 구독 만들기

  • cURL 설치

  • PowerShell 버전 6.0 이상 또는 유사한 명령줄 애플리케이션.

  • Azure AI 서비스 또는 문서 인텔리전스 리소스입니다. Azure 구독이 있으면 Azure Portal에서 단일 서비스 또는 다중 서비스 문서 인텔리전스 리소스를 만들어 키와 엔드포인트를 가져옵니다. 평가판 가격 책정 계층(F0)을 통해 서비스를 사용해보고, 나중에 프로덕션용 유료 계층으로 업그레이드할 수 있습니다.

    단일 엔드포인트/키에서 여러 Azure AI 서비스에 액세스하려는 경우 Azure AI 서비스 리소스를 만듭니다. 문서 인텔리전스 액세스에 대해서만 문서 인텔리전스 리소스를 만듭니다. Microsoft Entra 인증을 사용하려는 경우 단일 서비스 리소스가 필요합니다.

  • 리소스를 배포한 후 리소스로 이동을 선택합니다. 애플리케이션을 문서 인텔리전스 API에 연결하려면 만든 리소스의 키와 엔드포인트가 필요합니다. 키와 엔드포인트는 이 빠른 시작의 뒷부분에서 코드에 붙여넣습니다.

    Azure Portal에서 키 및 엔드포인트 위치의 스크린샷

애플리케이션에 복사하여 붙여넣을 코드 샘플을 선택합니다.

Important

완료되면 코드에서 키를 제거하고 공개적으로 게시하지 마세요. 프로덕션의 경우 Azure Key Vault와 같은 자격 증명을 안전하게 저장하고 액세스하는 방법을 사용합니다. 자세한 내용은 Azure AI 서비스 보안참조하세요.

사용해 보기: 레이아웃 모델

  • 이 예에서는 URI에 문서 파일이 필요합니다. 이 빠른 시작을 위해 샘플 문서를 사용할 수 있습니다.
  1. {endpoint}를 문서 인텔리전스 구독으로 가져오는 엔드포인트로 바꿉니다.
  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

요청

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}를 문서 인텔리전스 구독으로 가져오는 엔드포인트로 바꿉니다.
  2. {key}를 이전 단계에서 복사한 키로 바꿉니다.
  3. {resultId}를 이전 단계의 결과 ID로 바꿉니다.

요청

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

결과 검사

JSON 콘텐츠가 있는 200 (success) 응답을 받습니다.

다음 청구서 이미지와 해당 JSON 출력을 참조하세요.

  • "readResults" 노드에는 페이지의 각 경계 상자 배치가 있는 모든 텍스트 줄이 포함되어 있습니다.
  • selectionMarks 노드는 모든 선택 표시(확인란, 라디오 표시) 및 상태가 selected 또는 unselected인지 여부를 표시합니다.
  • "pageResults" 섹션에는 추출된 표가 포함됩니다. 각 표에서 텍스트, 행 및 열 인덱스, 행 및 열 스패닝, 경계 상자 등이 추출됩니다.

테이블이 포함된 Contoso 프로젝트 문 문서.

응답 본문

GitHub의 전체 샘플 출력을 확인할 수 있습니다.

사용해 보기: 미리 빌드된 모델

  • 이 예제에서는 미리 빌드된 모델을 사용하여 청구서 문서를 분석합니다. 이 빠른 시작에는 샘플 청구서 문서를 사용할 수 있습니다.

미리 빌드된 모델 선택

청구서에 국한되지 않습니다. 몇 가지 미리 빌드된 모델 중에서 선택할 수 있으며, 각 모델에는 자체 지원 필드 집합이 있습니다. 분석 작업에 사용할 모델은 분석할 문서 유형에 따라 달라집니다. 현재 문서 인텔리전스 서비스에서 지원되는 미리 빌드된 모델은 다음과 같습니다.

  • 청구서: 청구서에서 텍스트, 선택 표시, 테이블, 필드 및 키 정보를 추출합니다.
  • 영수증: 영수증에서 텍스트 및 키 정보를 추출합니다.
  • ID 문서: 운전 면허증과 국제 여권에서 텍스트 및 키 정보를 추출합니다.
  • 명함: 명함에서 텍스트 및 키 정보를 추출합니다.

명령을 실행하기 전에 다음과 같이 변경합니다.

  1. {endpoint}를 문서 인텔리전스 구독으로 가져오는 엔드포인트로 바꿉니다.

  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
    

요청

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}를 문서 인텔리전스 키로 가져오는 엔드포인트로 바꿉니다. 문서 인텔리전스 리소스 개요 탭에서 찾을 수 있습니다.
  2. {resultId}를 이전 단계의 결과 ID로 바꿉니다.
  3. {key}를 원하는 키로 바꿉니다.

요청

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의 전체 샘플 출력을 참조하세요.

이젠 끝입니다. 잘하셨습니다!

다음 단계

  • 향상된 환경과 고급 모델 품질을 위해 문서 인텔리전스 스튜디오를 사용해 보세요.

    • 스튜디오는 v2.1 레이블이 지정된 데이터로 학습된 모든 모델을 지원합니다.

    • 변경 로그는 v3.1에서 v4.0으로 마이그레이션하는 방법에 대한 자세한 정보를 제공합니다.