Menggunakan Form Recognizer SDKs atau REST API

Dalam panduan cara ini, Anda akan belajar cara menambahkan Form Recognizer ke aplikasi dan alur kerja menggunakan SDK, dalam bahasa pemrograman pilihan Anda, atau API REST. Azure Form Recognizer adalah Azure Applied AI Service berbasis cloud yang menggunakan pembelajaran mesin untuk mengekstrak pasangan kunci-nilai, teks, dan tabel dari dokumen Anda. Kami sarankan agar Anda menggunakan layanan gratis saat mempelajari teknologi ini. Ingatlah bahwa jumlah halaman gratis dibatasi hingga 500 per bulan.

Anda akan menggunakan API berikut untuk mengekstrak data terstruktur dari formulir dan dokumen:

Penting

  • Proyek ini menargetkan Form Recognizer REST API v2.1.

  • Kode dalam artikel ini menggunakan metode sinkron dan penyimpanan informasi masuk yang tidak aman untuk alasan kesederhanaan.

Dokumentasi referensi | Kode sumber pustaka | Paket (NuGet) | Sampel

Prasyarat

  • Langganan Azure - Membuat langganan gratis
  • IDE Visual Studio atau versi .NET Core saat ini.
  • Blob Azure Storage yang berisi set data pelatihan. Lihat Membangun himpunan data pelatihan untuk model kustom untuk tips dan opsi dalam menyusun himpunan data pelatihan Anda. Untuk proyek ini, Anda dapat menggunakan file dalam folder Latihan dari himpunan data sampel (unduh dan ekstrak sample_data.zip).
  • Setelah Anda berlangganan Azure, buat sumber daya Form Recognizer di portal Microsoft Azure untuk mendapatkan kunci dan titik akhir Anda. Setelah menyebar, pilih Buka sumber daya.
    • Anda akan memerlukan kunci dan titik akhir sumber daya yang Anda buat untuk menghubungkan aplikasi ke API Form Recognizer. Tempelkan kunci dan titik akhir ke dalam kode di bawah ini dalam proyek nanti.
    • Anda dapat menggunakan tingkat harga gratis (F0) untuk mencoba layanan, lalu meningkatkannya ke tingkat berbayar untuk produksi.

Tip

Buat sumber daya Cognitive Services jika Anda berencana untuk mengakses beberapa layanan kognitif di bawah satu titik akhir/kunci. Hanya untuk akses Form Recognizer, buat sumber daya Form Recognizer. Harap perhatikan bahwa Anda memerlukan sumber daya layanan tunggal jika ingin menggunakan Autentikasi Azure Active Directory.

Persiapan

Di jendela konsol (seperti cmd, PowerShell, atau Bash), gunakan perintah dotnet new untuk membuat aplikasi konsol baru dengan nama formrecognizer-project. Perintah ini membuat proyek C# "Halo Dunia" sederhana dengan satu file sumber: program.cs.

dotnet new console -n formrecognizer-project

Ubah direktori Anda ke folder aplikasi yang baru dibuat. Anda dapat membuat aplikasi dengan:

dotnet build

Output build tidak boleh berisi peringatan atau kesalahan.

...
Build succeeded.
 0 Warning(s)
 0 Error(s)
...

Memasang pustaka klien

Di dalam direktori aplikasi, pasang pustaka klien Azure Form Recognizer untuk .NET dengan perintah berikut:

dotnet add package Azure.AI.FormRecognizer --version 3.1.1

Dari direktori proyek, buka file Program.cs di editor atau IDE pilihan Anda. Tambahkan arahan using berikut:

using Azure;
using Azure.AI.FormRecognizer;  
using Azure.AI.FormRecognizer.Models;
using Azure.AI.FormRecognizer.Training;

using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;

Di kelas Program aplikasi, buat variabel untuk kunci dan titik akhir sumber daya Anda.

Penting

Masuk ke portal Microsoft Azure. Jika sumber daya Azure Form Recognizer yang Anda buat di bagian Prasyarat berhasil disebarkan, klik tombol Buka Sumber daya di bawah Langkah Berikutnya. Anda dapat menemukan kunci dan titik akhir Anda di halaman kunci dan titik akhir sumber daya, di bawah manajemen sumber daya.

Ingatlah untuk menghapus kunci dari kode Anda setelah selesai, dan jangan pernah memposting kode secara publik. Untuk produksi, gunakan metode aman untuk menyimpan dan mengakses info masuk Anda. Untuk informasi selengkapnya, lihat artikel keamanan Cognitive Services.

private static readonly string endpoint = "PASTE_YOUR_FORM_RECOGNIZER_ENDPOINT_HERE";
private static readonly string apiKey = "PASTE_YOUR_FORM_RECOGNIZER_SUBSCRIPTION_KEY_HERE";
private static readonly AzureKeyCredential credential = new AzureKeyCredential(apiKey);

Dalam metode Utama aplikasi, tambahkan panggilan ke tugas asinkron yang digunakan dalam proyek ini. Anda akan menerapkannya nanti:

static void Main(string[] args) {
  // new code:
  var recognizeContent = RecognizeContent(recognizerClient);
  Task.WaitAll(recognizeContent);

  var analyzeReceipt = AnalyzeReceipt(recognizerClient, receiptUrl);
  Task.WaitAll(analyzeReceipt);

  var analyzeBusinessCard = AnalyzeBusinessCard(recognizerClient, bcUrl);
  Task.WaitAll(analyzeBusinessCard);

  var analyzeInvoice = AnalyzeInvoice(recognizerClient, invoiceUrl);
  Task.WaitAll(analyzeInvoice);

  var analyzeId = AnalyzeId(recognizerClient, idUrl);
  Task.WaitAll(analyzeId);

  var trainModel = TrainModel(trainingClient, trainingDataUrl);
  Task.WaitAll(trainModel);

  var trainModelWithLabels = TrainModelWithLabels(trainingClient, trainingDataUrl);
  Task.WaitAll(trainModel);

  var analyzeForm = AnalyzePdfForm(recognizerClient, modelId, formUrl);
  Task.WaitAll(analyzeForm);

  var manageModels = ManageModels(trainingClient, trainingDataUrl);
  Task.WaitAll(manageModels);

}

Model objek

Dengan Azure Form Recognizer, Anda dapat membuat dua jenis klien yang berbeda. Yang pertama, FormRecognizerClient digunakan untuk mengkueri layanan ke bidang isian borang dan konten yang dikenali. Yang kedua, FormTrainingClient digunakan untuk membuat dan mengelola model kustom agar lebih dikenali.

FormRecognizerClient

FormRecognizerClient menyediakan operasi berikut:

  • Mengenali bidang dan konten formulir, menggunakan model kustom yang dilatih untuk menganalisis formulir kustom Anda. Nilai ini ditampilkan dalam kumpulan objek RecognizedForm. Lihat contoh Menganalisis formulir kustom.
  • Mengenali isi formulir, termasuk tabel, garis, dan kata, tanpa perlu melatih model. Konten formulir dikembalikan dalam kumpulan objek FormPage. Lihat contoh Analisis tata letak.
  • Mengenali bidang umum dari tanda terima, kartu nama, faktur, dan dokumen ID AS menggunakan model yang telah dilatih sebelumnya pada layanan Form Recognizer.

FormTrainingClient

FormTrainingClient menyediakan operasi untuk:

  • Pelatihan model kustom untuk menganalisis semua bidang dan nilai yang ditemukan di formulir kustom Anda. CustomFormModel ditampilkan yang menunjukkan jenis formulir yang akan dianalisis model, dan bidang yang akan diekstrak untuk setiap jenis formulir.
  • Pelatihan model kustom untuk menganalisis bidang dan nilai tertentu yang Anda tentukan dengan memberi label pada formulir kustom. CustomFormModel dikembalikan yang menunjukkan bidang yang akan diekstrak oleh model, serta perkiraan akurasi untuk setiap bidang.
  • Mengelola model yang dibuat di akun Anda.
  • Menyalin model kustom dari satu sumber daya Azure Form Recognizer ke sumber daya lainnya.

Lihat contoh untuk Melatih Model dan Mengelola Model Kustom.

Catatan

Model juga dapat dilatih menggunakan antarmuka pengguna grafis seperti Alat Pelabelan Azure Form Recognizer.

Autentikasi klien

Di bawah Utama, buat metode baru bernama AuthenticateClient. Anda akan menggunakan metode ini dalam tugas lain untuk mengautentikasi permintaan ke layanan Form Recognizer. Metode ini menggunakan objek AzureKeyCredential, sehingga jika diperlukan, Anda dapat memperbarui kunci tanpa membuat objek klien baru.

Penting

Dapatkan kunci dan titik akhir Anda dari portal Microsoft Azure. Jika sumber daya Azure Form Recognizer yang Anda buat di bagian Prasyarat berhasil disebarkan, klik tombol Buka Sumber daya di bawah Langkah Berikutnya. Anda dapat menemukan kunci dan titik akhir Anda di halaman kunci dan titik akhir sumber daya, di bawah manajemen sumber daya.

Ingatlah untuk menghapus kunci dari kode Anda setelah selesai, dan jangan pernah memposting kode secara publik. Untuk produksi, gunakan metode aman untuk menyimpan dan mengakses info masuk Anda. Misalnya, Brankas kunci Azure.

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

Ulangi langkah-langkah di atas untuk metode baru yang mengautentikasi klien pelatihan.

static private FormTrainingClient AuthenticateTrainingClient()
{
    var credential = new AzureKeyCredential(apiKey);
    var client = new FormTrainingClient(new Uri(endpoint), credential);
    return client;
}

Menddapatkan aset untuk pengujian

Anda juga harus menambahkan referensi ke URL untuk data pelatihan dan pengujian. Tambahkan referensi ini ke akar kelas Program Anda.

  • Untuk mengambil URL SAS untuk data pelatihan model kustom Anda, buka sumber daya penyimpanan di portal Microsoft Azure dan pilih tab Penjelajah Penyimpanan. Navigasikan ke kontainer Anda, klik kanan, dan pilih Dapatkan tanda tangan akses berbagi. Sangat penting untuk mendapatkan SAS untuk kontainer Anda, bukan untuk akun penyimpanan itu sendiri. Pastikan izin Baca, Tulis, Hapus, dan Cantumkan dicentang, lalu klik Buat. Kemudian salin nilai di bagian URL ke lokasi sementara. Ini harus memiliki format: https://<storage account>.blob.core.windows.net/<container name>?<SAS value>.

    Pengambilan URL SAS

  • Kemudian, ulangi langkah-langkah di atas untuk mendapatkan URL SAS dari masing-masing dokumen dalam kontainer penyimpanan blob. Simpan ke lokasi sementara juga.

  • Terakhir, simpan URL gambar sampel yang disertakan di bawah (juga tersedia di GitHub).

string trainingDataUrl = "PASTE_YOUR_SAS_URL_OF_YOUR_FORM_FOLDER_IN_BLOB_STORAGE_HERE";
string formUrl = "PASTE_YOUR_FORM_RECOGNIZER_FORM_URL_HERE";
string receiptUrl = "https://docs.microsoft.com/azure/cognitive-services/form-recognizer/media" + "/contoso-allinone.jpg";
string bcUrl = "https://raw.githubusercontent.com/Azure/azure-sdk-for-python/master/sdk/formrecognizer/azure-ai-formrecognizer/samples/sample_forms/business_cards/business-card-english.jpg";
string invoiceUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/simple-invoice.png";

string idUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/id-license.jpg";

Menganalisis tata letak

Anda dapat menggunakan Form Recognizer untuk menganalisis tabel, garis, dan kata-kata dalam dokumen, tanpa perlu melatih model. Nilai yang ditampilkan adalah kumpulan objek FormPage: satu untuk setiap halaman dalam dokumen yang dikirimkan. Untuk informasi selengkapnya tentang ekstraksi tata letak, lihat Panduan konseptual tata letak.

Untuk menganalisis konten file pada URL yang diberikan, gunakan metode StartRecognizeContentFromUri.

private static async Task RecognizeContent(FormRecognizerClient recognizerClient)
{
    var invoiceUri = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/simple-invoice.png";
    FormPageCollection formPages = await recognizerClient
        .StartRecognizeContentFromUri(new Uri(invoiceUri))
        .WaitForCompletionAsync();

Tip

Anda juga bisa mendapatkan konten dari file lokal. Lihat metode FormRecognizerClient, seperti StartRecognizeContent. Atau, lihat sampel kode pada GitHub untuk skenario yang melibatkan gambar lokal.

Sisa tugas ini mencetak informasi konten ke konsol.

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

Output

Form Page 1 has 18 lines.
    Line 0 has 1 word, and text: 'Contoso'.
    Line 1 has 1 word, and text: 'Address:'.
    Line 2 has 3 words, and text: 'Invoice For: Microsoft'.
    Line 3 has 4 words, and text: '1 Redmond way Suite'.
    Line 4 has 3 words, and text: '1020 Enterprise Way'.
    Line 5 has 3 words, and text: '6000 Redmond, WA'.
    Line 6 has 3 words, and text: 'Sunnayvale, CA 87659'.
    Line 7 has 1 word, and text: '99243'.
    Line 8 has 2 words, and text: 'Invoice Number'.
    Line 9 has 2 words, and text: 'Invoice Date'.
    Line 10 has 3 words, and text: 'Invoice Due Date'.
    Line 11 has 1 word, and text: 'Charges'.
    Line 12 has 2 words, and text: 'VAT ID'.
    Line 13 has 1 word, and text: '34278587'.
    Line 14 has 1 word, and text: '6/18/2017'.
    Line 15 has 1 word, and text: '6/24/2017'.
    Line 16 has 1 word, and text: '$56,651.49'.
    Line 17 has 1 word, and text: 'PT'.
Table 0 has 2 rows and 6 columns.
    Cell (0, 0) contains text: 'Invoice Number'.
    Cell (0, 1) contains text: 'Invoice Date'.
    Cell (0, 2) contains text: 'Invoice Due Date'.
    Cell (0, 3) contains text: 'Charges'.
    Cell (0, 5) contains text: 'VAT ID'.
    Cell (1, 0) contains text: '34278587'.
    Cell (1, 1) contains text: '6/18/2017'.
    Cell (1, 2) contains text: '6/24/2017'.
    Cell (1, 3) contains text: '$56,651.49'.
    Cell (1, 5) contains text: 'PT'.

Menganalisis tanda terima

Bagian ini menunjukkan cara menganalisis dan mengekstrak bidang umum dari tanda terima US, menggunakan model tanda terima yang telah dilatih sebelumnya. Untuk informasi selengkapnya tentang analisis tanda terima, lihat Panduan konseptual tanda terima.

Untuk menganalisis tanda terima dari URL, gunakan metode StartRecognizeReceiptsFromUri.

private static async Task AnalyzeReceipt(
    FormRecognizerClient recognizerClient, string receiptUri)
{
    RecognizedFormCollection receipts = await recognizerClient.StartRecognizeReceiptsFromUri(new Uri(receiptUrl)).WaitForCompletionAsync();

Tip

Anda juga dapat menganalisis gambar tanda terima lokal. Lihat metode FormRecognizerClient, seperti StartRecognizeReceipts. Atau, lihat sampel kode pada GitHub untuk skenario yang melibatkan gambar lokal.

Nilai yang ditampilkan adalah kumpulan objek RecognizedForm: satu untuk setiap halaman dalam dokumen yang dikirimkan. Kode berikut memproses tanda terima di URI yang diberikan dan mencetak bidang dan nilai utama ke konsol.

    foreach (RecognizedForm receipt in receipts)
    {
        FormField merchantNameField;
        if (receipt.Fields.TryGetValue("MerchantName", out merchantNameField))
        {
            if (merchantNameField.Value.ValueType == FieldValueType.String)
            {
                string merchantName = merchantNameField.Value.AsString();

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

        FormField transactionDateField;
        if (receipt.Fields.TryGetValue("TransactionDate", out transactionDateField))
        {
            if (transactionDateField.Value.ValueType == FieldValueType.Date)
            {
                DateTime transactionDate = transactionDateField.Value.AsDate();

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

        FormField itemsField;
        if (receipt.Fields.TryGetValue("Items", out itemsField))
        {
            if (itemsField.Value.ValueType == FieldValueType.List)
            {
                foreach (FormField itemField in itemsField.Value.AsList())
                {
                    Console.WriteLine("Item:");

                    if (itemField.Value.ValueType == FieldValueType.Dictionary)
                    {
                        IReadOnlyDictionary<string, FormField> itemFields = itemField.Value.AsDictionary();

                        FormField itemNameField;
                        if (itemFields.TryGetValue("Name", out itemNameField))
                        {
                            if (itemNameField.Value.ValueType == FieldValueType.String)
                            {
                                string itemName = itemNameField.Value.AsString();

                                Console.WriteLine($"    Name: '{itemName}', with confidence {itemNameField.Confidence}");
                            }
                        }

                        FormField itemTotalPriceField;
                        if (itemFields.TryGetValue("TotalPrice", out itemTotalPriceField))
                        {
                            if (itemTotalPriceField.Value.ValueType == FieldValueType.Float)
                            {
                                float itemTotalPrice = itemTotalPriceField.Value.AsFloat();

                                Console.WriteLine($"    Total Price: '{itemTotalPrice}', with confidence {itemTotalPriceField.Confidence}");
                            }
                        }
                    }
                }
            }
        }
        FormField totalField;
        if (receipt.Fields.TryGetValue("Total", out totalField))
        {
            if (totalField.Value.ValueType == FieldValueType.Float)
            {
                float total = totalField.Value.AsFloat();

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

Output

Form Page 1 has 18 lines.
    Line 0 has 1 word, and text: 'Contoso'.
    Line 1 has 1 word, and text: 'Address:'.
    Line 2 has 3 words, and text: 'Invoice For: Microsoft'.
    Line 3 has 4 words, and text: '1 Redmond way Suite'.
    Line 4 has 3 words, and text: '1020 Enterprise Way'.
    Line 5 has 3 words, and text: '6000 Redmond, WA'.
    Line 6 has 3 words, and text: 'Sunnayvale, CA 87659'.
    Line 7 has 1 word, and text: '99243'.
    Line 8 has 2 words, and text: 'Invoice Number'.
    Line 9 has 2 words, and text: 'Invoice Date'.
    Line 10 has 3 words, and text: 'Invoice Due Date'.
    Line 11 has 1 word, and text: 'Charges'.
    Line 12 has 2 words, and text: 'VAT ID'.
    Line 13 has 1 word, and text: '34278587'.
    Line 14 has 1 word, and text: '6/18/2017'.
    Line 15 has 1 word, and text: '6/24/2017'.
    Line 16 has 1 word, and text: '$56,651.49'.
    Line 17 has 1 word, and text: 'PT'.
Table 0 has 2 rows and 6 columns.
    Cell (0, 0) contains text: 'Invoice Number'.
    Cell (0, 1) contains text: 'Invoice Date'.
    Cell (0, 2) contains text: 'Invoice Due Date'.
    Cell (0, 3) contains text: 'Charges'.
    Cell (0, 5) contains text: 'VAT ID'.
    Cell (1, 0) contains text: '34278587'.
    Cell (1, 1) contains text: '6/18/2017'.
    Cell (1, 2) contains text: '6/24/2017'.
    Cell (1, 3) contains text: '$56,651.49'.
    Cell (1, 5) contains text: 'PT'.
Merchant Name: 'Contoso Contoso', with confidence 0.516
Transaction Date: '6/10/2019 12:00:00 AM', with confidence 0.985
Item:
    Name: '8GB RAM (Black)', with confidence 0.916
    Total Price: '999', with confidence 0.559
Item:
    Name: 'SurfacePen', with confidence 0.858
    Total Price: '99.99', with confidence 0.386
Total: '1203.39', with confidence '0.774'

Menganalisis kartu nama

Bagian ini menunjukkan cara menganalisis dan mengekstrak bidang umum dari kartu bisnis berbahasa Inggris menggunakan model yang dilatih sebelumnya. Untuk informasi selengkapnya tentang analisis kartu bisnis, lihat Panduan konseptual kartu bisnis.

Untuk menganalisis kartu bisnis dari URL, gunakan metode StartRecognizeBusinessCardsFromUriAsync.

private static async Task AnalyzeBusinessCard(
FormRecognizerClient recognizerClient, string bcUrl) {
  RecognizedFormCollection businessCards = await recognizerClient.StartRecognizeBusinessCardsFromUriAsync(bcUrl).WaitForCompletionAsync();

Tip

Anda juga dapat menganalisis gambar tanda terima lokal. Lihat metode FormRecognizerClient, seperti StartRecognizeBusinessCards. Atau, lihat sampel kode pada GitHub untuk skenario yang melibatkan gambar lokal.

Kode berikut memproses kartu bisnis di URI yang diberikan dan mencetak bidang dan nilai utama ke konsol.

  foreach(RecognizedForm businessCard in businessCards) {
    FormField ContactNamesField;
    if (businessCard.Fields.TryGetValue("ContactNames", out ContactNamesField)) {
      if (ContactNamesField.Value.ValueType == FieldValueType.List) {
        foreach(FormField contactNameField in ContactNamesField.Value.AsList()) {
          Console.WriteLine($ "Contact Name: {contactNameField.ValueData.Text}");

          if (contactNameField.Value.ValueType == FieldValueType.Dictionary) {
            IReadOnlyDictionary < string,
            FormField > contactNameFields = contactNameField.Value.AsDictionary();

            FormField firstNameField;
            if (contactNameFields.TryGetValue("FirstName", out firstNameField)) {
              if (firstNameField.Value.ValueType == FieldValueType.String) {
                string firstName = firstNameField.Value.AsString();

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

            FormField lastNameField;
            if (contactNameFields.TryGetValue("LastName", out lastNameField)) {
              if (lastNameField.Value.ValueType == FieldValueType.String) {
                string lastName = lastNameField.Value.AsString();

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

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

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

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

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

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

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

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

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

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

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

    FormField otherPhonesFields;
    if (businessCard.Fields.TryGetValue("OtherPhones", out otherPhonesFields)) {
      if (otherPhonesFields.Value.ValueType == FieldValueType.List) {
        foreach(FormField otherPhoneField in otherPhonesFields.Value.AsList()) {
          if (otherPhoneField.Value.ValueType == FieldValueType.PhoneNumber) {
            string otherPhone = otherPhoneField.Value.AsPhoneNumber();

            Console.WriteLine($ "  Other phone number: '{otherPhone}', with confidence {otherPhoneField.Confidence}");
          }
        }
      }
    }

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

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

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

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

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

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

Menganalisis faktur

Bagian ini menunjukkan cara menganalisis dan mengekstrak bidang umum dari faktur penjualan, menggunakan model yang sudah dilatih sebelumnya. Untuk mengetahui informasi selengkapnya tentang analisis faktur, lihat Panduan konseptual faktur.

Untuk menganalisis faktur dari URL, gunakan metode StartRecognizeInvoicesFromUriAsync.

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

Tip

Anda juga dapat menganalisis gambar faktur lokal. Lihat metode FormRecognizerClient, seperti StartRecognizeInvoices. Atau, lihat sampel kode pada GitHub untuk skenario yang melibatkan gambar lokal.

Kode berikut memproses faktur di URI yang diberikan dan mencetak bidang dan nilai utama ke konsol.

  RecognizedForm invoice = invoices.Single();

  FormField invoiceIdField;
  if (invoice.Fields.TryGetValue("InvoiceId", out invoiceIdField)) {
    if (invoiceIdField.Value.ValueType == FieldValueType.String) {
      string invoiceId = invoiceIdField.Value.AsString();
      Console.WriteLine($ "    Invoice Id: '{invoiceId}', with confidence {invoiceIdField.Confidence}");
    }
  }

  FormField invoiceDateField;
  if (invoice.Fields.TryGetValue("InvoiceDate", out invoiceDateField)) {
    if (invoiceDateField.Value.ValueType == FieldValueType.Date) {
      DateTime invoiceDate = invoiceDateField.Value.AsDate();
      Console.WriteLine($ "    Invoice Date: '{invoiceDate}', with confidence {invoiceDateField.Confidence}");
    }
  }

  FormField dueDateField;
  if (invoice.Fields.TryGetValue("DueDate", out dueDateField)) {
    if (dueDateField.Value.ValueType == FieldValueType.Date) {
      DateTime dueDate = dueDateField.Value.AsDate();
      Console.WriteLine($ "    Due Date: '{dueDate}', with confidence {dueDateField.Confidence}");
    }
  }

  FormField vendorNameField;
  if (invoice.Fields.TryGetValue("VendorName", out vendorNameField)) {
    if (vendorNameField.Value.ValueType == FieldValueType.String) {
      string vendorName = vendorNameField.Value.AsString();
      Console.WriteLine($ "    Vendor Name: '{vendorName}', with confidence {vendorNameField.Confidence}");
    }
  }

  FormField vendorAddressField;
  if (invoice.Fields.TryGetValue("VendorAddress", out vendorAddressField)) {
    if (vendorAddressField.Value.ValueType == FieldValueType.String) {
      string vendorAddress = vendorAddressField.Value.AsString();
      Console.WriteLine($ "    Vendor Address: '{vendorAddress}', with confidence {vendorAddressField.Confidence}");
    }
  }

  FormField customerNameField;
  if (invoice.Fields.TryGetValue("CustomerName", out customerNameField)) {
    if (customerNameField.Value.ValueType == FieldValueType.String) {
      string customerName = customerNameField.Value.AsString();
      Console.WriteLine($ "    Customer Name: '{customerName}', with confidence {customerNameField.Confidence}");
    }
  }

  FormField customerAddressField;
  if (invoice.Fields.TryGetValue("CustomerAddress", out customerAddressField)) {
    if (customerAddressField.Value.ValueType == FieldValueType.String) {
      string customerAddress = customerAddressField.Value.AsString();
      Console.WriteLine($ "    Customer Address: '{customerAddress}', with confidence {customerAddressField.Confidence}");
    }
  }

  FormField customerAddressRecipientField;
  if (invoice.Fields.TryGetValue("CustomerAddressRecipient", out customerAddressRecipientField)) {
    if (customerAddressRecipientField.Value.ValueType == FieldValueType.String) {
      string customerAddressRecipient = customerAddressRecipientField.Value.AsString();
      Console.WriteLine($ "    Customer address recipient: '{customerAddressRecipient}', with confidence {customerAddressRecipientField.Confidence}");
    }
  }

  FormField invoiceTotalField;
  if (invoice.Fields.TryGetValue("InvoiceTotal", out invoiceTotalField)) {
    if (invoiceTotalField.Value.ValueType == FieldValueType.Float) {
      float invoiceTotal = invoiceTotalField.Value.AsFloat();
      Console.WriteLine($ "    Invoice Total: '{invoiceTotal}', with confidence {invoiceTotalField.Confidence}");
    }
  }
}

Menganalisis dokumen ID

Bagian ini menunjukkan cara menganalisis dan mengekstrak informasi kunci dari dokumen identifikasi yang dikeluarkan pemerintah—paspor di seluruh dunia dan SIM AS—menggunakan model ID bawaan Form Recognizer. Untuk mengetahui informasi selengkapnya tentang analisis dokumen identitas, lihat panduan konseptual model identifikasi bawaan kami.

Untuk menganalisis dokumen ID dari URI, gunakan metode StartRecognizeIdentityDocumentsFromUriAsync.

private static async Task AnalyzeId(
FormRecognizerClient recognizerClient, string idUrl) {
  RecognizedFormCollection identityDocument = await recognizerClient.StartRecognizeIdDocumentsFromUriAsync(idUrl).WaitForCompletionAsync();

Tip

Anda juga dapat menganalisis gambar dokumen ID lokal. Lihat metode FormRecognizerClient, seperti StartRecognizeIdentityDocumentsAsync. Atau, lihat kode sampel do GitHub untuk skenario yang melibatkan gambar lokal.

Kode berikut memproses dokumen ID di URI tertentu dan mencetak bidang serta nilai utama ke konsol.

RecognizedForm identityDocument = identityDocuments.Single();

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

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

if (identityDocument.Fields.TryGetValue("DateOfBirth", out FormField dateOfBirthField)) {
  if (dateOfBirthField.Value.ValueType == FieldValueType.Date) {
    DateTime dateOfBirth = dateOfBirthField.Value.AsDate();
    Console.WriteLine($ "Date Of Birth: '{dateOfBirth}', with confidence {dateOfBirthField.Confidence}");
  }
}

if (identityDocument.Fields.TryGetValue("DateOfExpiration", out FormField dateOfExpirationField)) {
  if (dateOfExpirationField.Value.ValueType == FieldValueType.Date) {
    DateTime dateOfExpiration = dateOfExpirationField.Value.AsDate();
    Console.WriteLine($ "Date Of Expiration: '{dateOfExpiration}', with confidence {dateOfExpirationField.Confidence}");
  }
}

if (identityDocument.Fields.TryGetValue("DocumentNumber", out FormField documentNumberField)) {
  if (documentNumberField.Value.ValueType == FieldValueType.String) {
    string documentNumber = documentNumberField.Value.AsString();
    Console.WriteLine($ "Document Number: '{documentNumber}', with confidence {documentNumberField.Confidence}");
  }
  RecognizedForm identityDocument = identityDocuments.Single();

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

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

  if (identityDocument.Fields.TryGetValue("DateOfBirth", out FormField dateOfBirthField)) {
    if (dateOfBirthField.Value.ValueType == FieldValueType.Date) {
      DateTime dateOfBirth = dateOfBirthField.Value.AsDate();
      Console.WriteLine($ "Date Of Birth: '{dateOfBirth}', with confidence {dateOfBirthField.Confidence}");
    }
  }

  if (identityDocument.Fields.TryGetValue("DateOfExpiration", out FormField dateOfExpirationField)) {
    if (dateOfExpirationField.Value.ValueType == FieldValueType.Date) {
      DateTime dateOfExpiration = dateOfExpirationField.Value.AsDate();
      Console.WriteLine($ "Date Of Expiration: '{dateOfExpiration}', with confidence {dateOfExpirationField.Confidence}");
    }
  }

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

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

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

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

Melatih model kustom

Bagian ini menunjukkan cara melatih model dengan data Anda sendiri. Model terlatih dapat menampilkan data terstruktur yang menyertakan hubungan kunci/nilai dalam dokumen formulir asli. Setelah melatih model, Anda dapat menguji, melatih kembali, dan akhirnya menggunakannya untuk mengekstrak data secara andal dari lebih banyak formulir sesuai kebutuhan Anda.

Catatan

Anda juga dapat melatih model dengan antarmuka pengguna grafis seperti alat Pelabelan Sampel Form Recognizer.

Melatih model tanpa label

Latih model kustom untuk menganalisis semua bidang dan nilai yang ditemukan di formulir kustom Anda tanpa memberi label secara manual pada dokumen pelatihan. Metode berikut melatih model pada kumpulan dokumen tertentu dan mencetak status model ke konsol.

private static async Task<String> TrainModel(
    FormTrainingClient trainingClient, string trainingDataUrl)
{
    CustomFormModel model = await trainingClient
    .StartTrainingAsync(new Uri(trainingDataUrl), useTrainingLabels: false)
    .WaitForCompletionAsync();

    Console.WriteLine($"Custom Model Info:");
    Console.WriteLine($"    Model Id: {model.ModelId}");
    Console.WriteLine($"    Model Status: {model.Status}");
    Console.WriteLine($"    Training model started on: {model.TrainingStartedOn}");
    Console.WriteLine($"    Training model completed on: {model.TrainingCompletedOn}");

Objek CustomFormModel yang dikembalikan berisi informasi tentang jenis formulir yang dapat dianalisis model dan bidang yang dapat diekstrak dari setiap jenis formulir. Blok kode berikut mencetak informasi ini ke konsol.

foreach (CustomFormSubmodel submodel in model.Submodels)
{
    Console.WriteLine($"Submodel Form Type: {submodel.FormType}");
    foreach (CustomFormModelField field in submodel.Fields.Values)
    {
        Console.Write($"    FieldName: {field.Name}");
        if (field.Label != null)
        {
            Console.Write($", FieldLabel: {field.Label}");
        }
        Console.WriteLine("");
    }
}

Terakhir, kembalikan ID model terlatih untuk digunakan di langkah selanjutnya.

    return model.ModelId;
}

Output

Respons ini telah dipotong agar mudah dibaca.

Merchant Name: 'Contoso Contoso', with confidence 0.516
Transaction Date: '6/10/2019 12:00:00 AM', with confidence 0.985
Item:
    Name: '8GB RAM (Black)', with confidence 0.916
    Total Price: '999', with confidence 0.559
Item:
    Name: 'SurfacePen', with confidence 0.858
    Total Price: '99.99', with confidence 0.386
Total: '1203.39', with confidence '0.774'
Form Page 1 has 18 lines.
    Line 0 has 1 word, and text: 'Contoso'.
    Line 1 has 1 word, and text: 'Address:'.
    Line 2 has 3 words, and text: 'Invoice For: Microsoft'.
    Line 3 has 4 words, and text: '1 Redmond way Suite'.
    Line 4 has 3 words, and text: '1020 Enterprise Way'.
    ...
Table 0 has 2 rows and 6 columns.
    Cell (0, 0) contains text: 'Invoice Number'.
    Cell (0, 1) contains text: 'Invoice Date'.
    Cell (0, 2) contains text: 'Invoice Due Date'.
    Cell (0, 3) contains text: 'Charges'.
    ...
Custom Model Info:
    Model Id: 95035721-f19d-40eb-8820-0c806b42798b
    Model Status: Ready
    Training model started on: 8/24/2020 6:36:44 PM +00:00
    Training model completed on: 8/24/2020 6:36:50 PM +00:00
Submodel Form Type: form-95035721-f19d-40eb-8820-0c806b42798b
    FieldName: CompanyAddress
    FieldName: CompanyName
    FieldName: CompanyPhoneNumber
    ...
Custom Model Info:
    Model Id: e7a1181b-1fb7-40be-bfbe-1ee154183633
    Model Status: Ready
    Training model started on: 8/24/2020 6:36:44 PM +00:00
    Training model completed on: 8/24/2020 6:36:52 PM +00:00
Submodel Form Type: form-0
    FieldName: field-0, FieldLabel: Additional Notes:
    FieldName: field-1, FieldLabel: Address:
    FieldName: field-2, FieldLabel: Company Name:
    FieldName: field-3, FieldLabel: Company Phone:
    FieldName: field-4, FieldLabel: Dated As:
    FieldName: field-5, FieldLabel: Details
    FieldName: field-6, FieldLabel: Email:
    FieldName: field-7, FieldLabel: Hero Limited
    FieldName: field-8, FieldLabel: Name:
    FieldName: field-9, FieldLabel: Phone:
    ...

Melatih model dengan label

Anda juga dapat melatih model kustom dengan memberi label secara manual pada dokumen pelatihan. Pelatihan dengan label berdampak pada performa yang lebih baik dalam beberapa skenario. Untuk berlatih dengan label, Anda harus memiliki file informasi label khusus (\<filename\>.pdf.labels.json) di kontainer penyimpanan blob Anda bersama dengan dokumen pelatihan. Alat Pelabelan Sampel Form Recognizer menyediakan UI untuk membantu Anda membuat file label ini. Setelah mendapatkannya, Anda dapat memanggil metode StartTrainingAsync dengan parameter uselabels diatur ke true.

private static async Task<Guid> TrainModelWithLabelsAsync(
    FormRecognizerClient trainingClient, string trainingDataUrl)
{
    CustomFormModel model = await trainingClient
    .StartTrainingAsync(new Uri(trainingDataUrl), useTrainingLabels: true)
    .WaitForCompletionAsync();
    Console.WriteLine($"Custom Model Info:");
    Console.WriteLine($"    Model Id: {model.ModelId}");
    Console.WriteLine($"    Model Status: {model.Status}");
    Console.WriteLine($"    Training model started on: {model.TrainingStartedOn}");
    Console.WriteLine($"    Training model completed on: {model.TrainingCompletedOn}");

CustomFormModel yang ditampilkan menunjukkan bidang yang dapat diekstrak model, bersama dengan perkiraan akurasinya di setiap bidang. Blok kode berikut mencetak informasi ini ke konsol.

    foreach (CustomFormSubmodel submodel in model.Submodels)
    {
        Console.WriteLine($"Submodel Form Type: {submodel.FormType}");
        foreach (CustomFormModelField field in submodel.Fields.Values)
        {
            Console.Write($"    FieldName: {field.Name}");
            if (field.Label != null)
            {
                Console.Write($", FieldLabel: {field.Label}");
            }
            Console.WriteLine("");
        }
    }
    return model.ModelId;
}

Output

Respons ini telah dipotong agar mudah dibaca.

Form Page 1 has 18 lines.
    Line 0 has 1 word, and text: 'Contoso'.
    Line 1 has 1 word, and text: 'Address:'.
    Line 2 has 3 words, and text: 'Invoice For: Microsoft'.
    Line 3 has 4 words, and text: '1 Redmond way Suite'.
    Line 4 has 3 words, and text: '1020 Enterprise Way'.
    Line 5 has 3 words, and text: '6000 Redmond, WA'.
    ...
Table 0 has 2 rows and 6 columns.
    Cell (0, 0) contains text: 'Invoice Number'.
    Cell (0, 1) contains text: 'Invoice Date'.
    Cell (0, 2) contains text: 'Invoice Due Date'.
    ...
Merchant Name: 'Contoso Contoso', with confidence 0.516
Transaction Date: '6/10/2019 12:00:00 AM', with confidence 0.985
Item:
    Name: '8GB RAM (Black)', with confidence 0.916
    Total Price: '999', with confidence 0.559
Item:
    Name: 'SurfacePen', with confidence 0.858
    Total Price: '99.99', with confidence 0.386
Total: '1203.39', with confidence '0.774'
Custom Model Info:
    Model Id: 63c013e3-1cab-43eb-84b0-f4b20cb9214c
    Model Status: Ready
    Training model started on: 8/24/2020 6:42:54 PM +00:00
    Training model completed on: 8/24/2020 6:43:01 PM +00:00
Submodel Form Type: form-63c013e3-1cab-43eb-84b0-f4b20cb9214c
    FieldName: CompanyAddress
    FieldName: CompanyName
    FieldName: CompanyPhoneNumber
    FieldName: DatedAs
    FieldName: Email
    FieldName: Merchant
    ...

Menganalisis formulir dengan model kustom

Bagian ini menunjukkan cara mengekstrak informasi kunci/nilai dan konten lainnya dari jenis templat kustom Anda, menggunakan model yang Anda latih dengan formulir Anda sendiri.

Penting

Untuk menerapkan skenario ini, Anda harus sudah melatih model sehingga dapat meneruskan ID model ke metode di bawah ini.

Anda akan menggunakan metode StartRecognizeCustomFormsFromUri.

// Analyze PDF form data
private static async Task AnalyzePdfForm(
    FormRecognizerClient recognizerClient, String modelId, string formUrl)
{
    RecognizedFormCollection forms = await recognizerClient
    .StartRecognizeCustomFormsFromUri(modelId, new Uri(formUrl))
    .WaitForCompletionAsync();

Tip

Anda juga dapat menganalisis file lokal. Lihat metode FormRecognizerClient, seperti StartRecognizeCustomForms. Atau, lihat sampel kode pada GitHub untuk skenario yang melibatkan gambar lokal.

Nilai yang ditampilkan adalah kumpulan objek RecognizedForm: satu untuk setiap halaman dalam dokumen yang dikirimkan. Kode berikut mencetak hasil analisis ke konsol. Kode mencetak setiap bidang yang dikenali dan nilai yang sesuai, bersama dengan skor keyakinan.

    foreach (RecognizedForm form in forms)
    {
        Console.WriteLine($"Form of type: {form.FormType}");
        foreach (FormField field in form.Fields.Values)
        {
            Console.WriteLine($"Field '{field.Name}: ");

            if (field.LabelData != null)
            {
                Console.WriteLine($"    Label: '{field.LabelData.Text}");
            }

            Console.WriteLine($"    Value: '{field.ValueData.Text}");
            Console.WriteLine($"    Confidence: '{field.Confidence}");
        }
        Console.WriteLine("Table data:");
        foreach (FormPage page in form.Pages)
        {
            for (int i = 0; i < page.Tables.Count; i++)
            {
                FormTable table = page.Tables[i];
                Console.WriteLine($"Table {i} has {table.RowCount} rows and {table.ColumnCount} columns.");
                foreach (FormTableCell cell in table.Cells)
                {
                    Console.WriteLine($"    Cell ({cell.RowIndex}, {cell.ColumnIndex}) contains {(cell.IsHeader ? "header" : "text")}: '{cell.Text}'");
                }
            }
        }
    }
}

Output

Respons ini telah dipotong agar mudah dibaca.

Custom Model Info:
    Model Id: 9b0108ee-65c8-450e-b527-bb309d054fc4
    Model Status: Ready
    Training model started on: 8/24/2020 7:00:31 PM +00:00
    Training model completed on: 8/24/2020 7:00:32 PM +00:00
Submodel Form Type: form-9b0108ee-65c8-450e-b527-bb309d054fc4
    FieldName: CompanyAddress
    FieldName: CompanyName
    FieldName: CompanyPhoneNumber
    ...
Form Page 1 has 18 lines.
    Line 0 has 1 word, and text: 'Contoso'.
    Line 1 has 1 word, and text: 'Address:'.
    Line 2 has 3 words, and text: 'Invoice For: Microsoft'.
    Line 3 has 4 words, and text: '1 Redmond way Suite'.
    ...

Table 0 has 2 rows and 6 columns.
    Cell (0, 0) contains text: 'Invoice Number'.
    Cell (0, 1) contains text: 'Invoice Date'.
    Cell (0, 2) contains text: 'Invoice Due Date'.
    ...
Merchant Name: 'Contoso Contoso', with confidence 0.516
Transaction Date: '6/10/2019 12:00:00 AM', with confidence 0.985
Item:
    Name: '8GB RAM (Black)', with confidence 0.916
    Total Price: '999', with confidence 0.559
Item:
    Name: 'SurfacePen', with confidence 0.858
    Total Price: '99.99', with confidence 0.386
Total: '1203.39', with confidence '0.774'
Custom Model Info:
    Model Id: dc115156-ce0e-4202-bbe4-7426e7bee756
    Model Status: Ready
    Training model started on: 8/24/2020 7:00:31 PM +00:00
    Training model completed on: 8/24/2020 7:00:41 PM +00:00
Submodel Form Type: form-0
    FieldName: field-0, FieldLabel: Additional Notes:
    FieldName: field-1, FieldLabel: Address:
    FieldName: field-2, FieldLabel: Company Name:
    FieldName: field-3, FieldLabel: Company Phone:
    FieldName: field-4, FieldLabel: Dated As:
    ...
Form of type: custom:form
Field 'Azure.AI.FormRecognizer.Models.FieldValue:
    Value: '$56,651.49
    Confidence: '0.249
Field 'Azure.AI.FormRecognizer.Models.FieldValue:
    Value: 'PT
    Confidence: '0.245
Field 'Azure.AI.FormRecognizer.Models.FieldValue:
    Value: '99243
    Confidence: '0.114
   ...

Mengelola model kustom

Bagian ini menunjukkan cara mengelola model kustom yang disimpan di akun Anda. Anda akan melakukan beberapa operasi dalam metode berikut:

private static async Task ManageModels(
    FormTrainingClient trainingClient, string trainingFileUrl)
{

Memeriksa jumlah model di akun sumber daya FormRecognizer

Blok kode berikut memeriksa banyaknya model yang Anda simpan di akun Form Recognizer dan membandingkannya dengan batas akun.

// Check number of models in the FormRecognizer account, 
// and the maximum number of models that can be stored.
AccountProperties accountProperties = trainingClient.GetAccountProperties();
Console.WriteLine($"Account has {accountProperties.CustomModelCount} models.");
Console.WriteLine($"It can have at most {accountProperties.CustomModelLimit} models.");

Output

Account has 20 models.
It can have at most 5000 models.

Mencantumkan model yang saat ini disimpan di akun sumber daya

Kode berikut memblokir model saat ini di akun Anda dan mencetak detailnya ke konsol.

Pageable<CustomFormModelInfo> models = trainingClient.GetCustomModels();

foreach (CustomFormModelInfo modelInfo in models)
{
    Console.WriteLine($"Custom Model Info:");
    Console.WriteLine($"    Model Id: {modelInfo.ModelId}");
    Console.WriteLine($"    Model Status: {modelInfo.Status}");
    Console.WriteLine($"    Training model started on: {modelInfo.TrainingStartedOn}");
    Console.WriteLine($"    Training model completed on: {modelInfo.TrainingCompletedOn}");
}

Output

Respons ini telah dipotong agar mudah dibaca.

Custom Model Info:
    Model Id: 05932d5a-a2f8-4030-a2ef-4e5ed7112515
    Model Status: Creating
    Training model started on: 8/24/2020 7:35:02 PM +00:00
    Training model completed on: 8/24/2020 7:35:02 PM +00:00
Custom Model Info:
    Model Id: 150828c4-2eb2-487e-a728-60d5d504bd16
    Model Status: Ready
    Training model started on: 8/24/2020 7:33:25 PM +00:00
    Training model completed on: 8/24/2020 7:33:27 PM +00:00
Custom Model Info:
    Model Id: 3303e9de-6cec-4dfb-9e68-36510a6ecbb2
    Model Status: Ready
    Training model started on: 8/24/2020 7:29:27 PM +00:00
    Training model completed on: 8/24/2020 7:29:36 PM +00:00

Mendapatkan model tertentu menggunakan ID model

Blok kode berikut melatih model baru (seperti di bagian Melatih model) dan kemudian mengambil referensi kedua menggunakan ID model baru.

// Create a new model to store in the account
CustomFormModel model = await trainingClient.StartTrainingAsync(
    new Uri(trainingFileUrl)).WaitForCompletionAsync();

// Get the model that was just created
CustomFormModel modelCopy = trainingClient.GetCustomModel(model.ModelId);

Console.WriteLine($"Custom Model {modelCopy.ModelId} recognizes the following form types:");

foreach (CustomFormSubmodel submodel in modelCopy.Submodels)
{
    Console.WriteLine($"Submodel Form Type: {submodel.FormType}");
    foreach (CustomFormModelField field in submodel.Fields.Values)
    {
        Console.Write($"    FieldName: {field.Name}");
        if (field.Label != null)
        {
            Console.Write($", FieldLabel: {field.Label}");
        }
        Console.WriteLine("");
    }
}

Output

Respons ini telah dipotong agar mudah dibaca.

Custom Model Info:
    Model Id: 150828c4-2eb2-487e-a728-60d5d504bd16
    Model Status: Ready
    Training model started on: 8/24/2020 7:33:25 PM +00:00
    Training model completed on: 8/24/2020 7:33:27 PM +00:00
Submodel Form Type: form-150828c4-2eb2-487e-a728-60d5d504bd16
    FieldName: CompanyAddress
    FieldName: CompanyName
    FieldName: CompanyPhoneNumber
    FieldName: DatedAs
    FieldName: Email
    FieldName: Merchant
    FieldName: PhoneNumber
    FieldName: PurchaseOrderNumber
    FieldName: Quantity
    FieldName: Signature
    FieldName: Subtotal
    FieldName: Tax
    FieldName: Total
    FieldName: VendorName
    FieldName: Website
...

Menghapus model dari akun sumber daya

Anda juga dapat menghapus model dari akun dengan merujuk ID model. Langkah ini juga menutup metode.

    // Delete the model from the account.
    trainingClient.DeleteModel(model.ModelId);
}

Menjalankan aplikasi

Menjalankan aplikasi dari direktori aplikasi Anda dengan perintah dotnet run.

dotnet run

Membersihkan sumber daya

Jika ingin membersihkan dan menghapus langganan Cognitive Services, Anda dapat menghapus sumber daya atau grup sumber daya. Menghapus grup sumber daya juga menghapus sumber daya apa pun yang terkait dengannya.

Pemecahan Masalah

Saat Anda berinteraksi dengan pustaka klien Azure Form Recognizer, Azure Cognitive Services menggunakan SDK .NET, kesalahan yang dihasilkan oleh layanan akan menghasilkan RequestFailedException. Layanan akan menyertakan kode status HTTP yang sama yang akan ditampilkan oleh permintaan REST API.

Misalnya, jika Anda mengirimkan gambar tanda terima dengan URI yang tidak valid, kesalahan 400 akan ditampilkan, yang menunjukkan "Permintaan Buruk".

try
{
    RecognizedReceiptCollection receipts = await client.StartRecognizeReceiptsFromUri(new Uri(receiptUri)).WaitForCompletionAsync();
}
catch (RequestFailedException e)
{
    Console.WriteLine(e.ToString());
}

Anda akan melihat bahwa informasi tambahan, seperti ID permintaan klien dari operasi, dicatat.


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

Content:
    {"error":{"code":"FailedToDownloadImage","innerError":
    {"requestId":"8ca04feb-86db-4552-857c-fde903251518"},
    "message":"Failed to download image from input URL."}}

Headers:
    Transfer-Encoding: chunked
    x-envoy-upstream-service-time: REDACTED
    apim-request-id: REDACTED
    Strict-Transport-Security: REDACTED
    X-Content-Type-Options: REDACTED
    Date: Mon, 20 Apr 2020 22:48:35 GMT
    Content-Type: application/json; charset=utf-8

Langkah berikutnya

Untuk proyek ini, Anda menggunakan pustaka klien .NET Form Recognizer untuk melatih model dan menganalisis formulir dengan cara yang berbeda. Selanjutnya, pelajari tips untuk membuat himpunan data pelatihan yang lebih baik dan membuat model yang lebih akurat.

Penting

  • Proyek ini menargetkan Form Recognizer REST API versi 2.1.

Dokumentasi referensi | Kode sumber pustaka | Paket (Maven) | Sampel

Prasyarat

  • Langganan Azure - Membuat langganan gratis
  • Java Development Kit (JDK) versi terbaru
  • Alat build Gradle, atau manajer dependensi lainnya.
  • Setelah Anda berlangganan Azure, buat sumber daya Form Recognizer di portal Microsoft Azure untuk mendapatkan kunci dan titik akhir Anda. Setelah menyebar, pilih Buka sumber daya.
    • Anda akan memerlukan kunci dan titik akhir sumber daya yang Anda buat untuk menghubungkan aplikasi ke API Form Recognizer. Tempelkan kunci dan titik akhir ke dalam kode di bawah ini.
    • Anda dapat menggunakan tingkat harga gratis (F0) untuk mencoba layanan, lalu meningkatkannya ke tingkat berbayar untuk produksi.
  • Blob Azure Storage yang berisi set data pelatihan. Lihat Membangun himpunan data pelatihan untuk model kustom untuk tips dan opsi dalam menyusun himpunan data pelatihan Anda. Untuk proyek ini, Anda dapat menggunakan file dalam folder Latihan dari himpunan data sampel (unduh dan ekstrak sample_data.zip).

Tip

Buat sumber daya Cognitive Services jika Anda berencana untuk mengakses beberapa layanan kognitif di bawah satu titik akhir/kunci. Hanya untuk akses Form Recognizer, buat sumber daya Form Recognizer. Harap perhatikan bahwa Anda memerlukan sumber daya layanan tunggal jika ingin menggunakan Autentikasi Azure Active Directory.

Persiapan

Membuat proyek Gradle baru

Di jendela konsol (seperti cmd, PowerShell, atau Bash), buat direktori baru untuk aplikasi Anda, dan arahkan ke sana.

mkdir myapp && cd myapp
    mkdir myapp; cd myapp

Jalankan perintah gradle init dari direktori yang berfungsi. Perintah ini akan membuat file build penting untuk Gradle, termasuk build.gradle.kts yang digunakan saat runtime bahasa umum untuk membuat dan mengonfigurasi aplikasi Anda.

gradle init --type basic

Saat diminta untuk memilih DSL, pilih Kotlin.

Memasang pustaka klien

Proyek ini menggunakan manajer dependensi Gradle. Anda dapat menemukan pustaka klien dan informasi untuk pengelola dependensi lain di Repositori Pusat Maven.

Di file build.gradle.kts proyek Anda, sertakan pustaka klien sebagai pernyataan implementation, bersama dengan plugin dan pengaturan yang diperlukan.

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

Membuat file Java

Dari direktori kerja Anda, jalankan perintah berikut:

mkdir -p src/main/java

Buka folder baru dan buat file bernama FormRecognizer.java. Buka di editor atau IDE pilihan Anda, lalu tambahkan pernyataan import berikut:

import com.azure.ai.formrecognizer.*;
import com.azure.ai.formrecognizer.training.*;
import com.azure.ai.formrecognizer.models.*;
import com.azure.ai.formrecognizer.training.models.*;

import java.util.concurrent.atomic.AtomicReference;
import java.util.List;
import java.util.Map;
import java.time.LocalDate;

import com.azure.core.credential.AzureKeyCredential;
import com.azure.core.http.rest.PagedIterable;
import com.azure.core.util.Context;
import com.azure.core.util.polling.SyncPoller;

Di kelas FormRecognizer aplikasi, buat variabel untuk kunci dan titik akhir sumber daya Anda.

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

Penting

Masuk ke portal Microsoft Azure. Jika sumber daya Azure Form Recognizer yang Anda buat di bagian Prasyarat berhasil disebarkan, klik tombol Buka Sumber daya di bawah Langkah Berikutnya. Anda dapat menemukan kunci dan titik akhir Anda di halaman kunci dan titik akhir sumber daya, di bawah manajemen sumber daya.

Ingatlah untuk menghapus kunci dari kode Anda setelah selesai, dan jangan pernah memposting kode secara publik. Untuk produksi, gunakan metode aman untuk menyimpan dan mengakses info masuk Anda. Untuk mengetahui informasi selengkapnya, lihatKeamanan Cognitive Services.

Dalam metode utama aplikasi, tambahkan panggilan untuk metode yang digunakan dalam proyek ini. Anda akan menentukan panggilan ini nanti. Anda juga harus menambahkan referensi ke URL untuk data pelatihan dan pengujian.

  • Untuk mengambil URL SAS untuk data pelatihan model kustom Anda, buka sumber daya penyimpanan di portal Microsoft Azure dan pilih tab Penjelajah Penyimpanan. Buka kontainer Anda, klik kanan, lalu pilih Dapatkan tanda tangan akses bersama. Sangat penting untuk mendapatkan SAS untuk kontainer Anda, bukan untuk akun penyimpanan itu sendiri. Pastikan izin Baca, Tulis, Hapus, dan Cantumkan dicentang, lalu klik Buat. Kemudian salin nilai di bagian URL ke lokasi sementara. Ini harus memiliki format: https://<storage account>.blob.core.windows.net/<container name>?<SAS value>.

    Pengambilan URL SAS

  • Untuk mendapatkan URL formulir yang akan diuji, Anda dapat menggunakan langkah di atas untuk mendapatkan URL SAS dari dokumen individual dalam penyimpanan blob. Atau, ambil URL dokumen yang berada di tempat lain.

  • Gunakan metode di atas agar mendapatkan URL gambar tanda terima juga.

String trainingDataUrl = "PASTE_YOUR_SAS_URL_OF_YOUR_FORM_FOLDER_IN_BLOB_STORAGE_HERE";
String formUrl = "PASTE_YOUR_FORM_RECOGNIZER_FORM_URL_HERE";
String receiptUrl = "https://docs.microsoft.com/azure/cognitive-services/form-recognizer/media" + "/contoso-allinone.jpg";
String bcUrl = "https://raw.githubusercontent.com/Azure/azure-sdk-for-python/master/sdk/formrecognizer/azure-ai-formrecognizer/samples/sample_forms/business_cards/business-card-english.jpg";
String invoiceUrl = "https://raw.githubusercontent.com/Azure/azure-sdk-for-python/master/sdk/formrecognizer/azure-ai-formrecognizer/samples/sample_forms/forms/Invoice_1.pdf";
String idUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/id-license.jpg"
// Call Form Recognizer scenarios:
System.out.println("Get form content...");
GetContent(recognizerClient, formUrl);

System.out.println("Analyze receipt...");
AnalyzeReceipt(recognizerClient, receiptUrl);

System.out.println("Analyze business card...");
AnalyzeBusinessCard(recognizerClient, bcUrl);

System.out.println("Analyze invoice...");
AnalyzeInvoice(recognizerClient, invoiceUrl);

System.out.println("Analyze id...");
AnalyzeId(recognizerClient, idUrl);

System.out.println("Train Model with training data...");
String modelId = TrainModel(trainingClient, trainingDataUrl);

System.out.println("Analyze PDF form...");
AnalyzePdfForm(recognizerClient, modelId, formUrl);

System.out.println("Manage models...");
ManageModels(trainingClient, trainingDataUrl);

Model objek

Dengan Azure Form Recognizer, Anda dapat membuat dua jenis klien yang berbeda. Yang pertama, FormRecognizerClient digunakan untuk mengkueri layanan ke bidang isian borang dan konten yang dikenali. Yang kedua, FormTrainingClient digunakan untuk membuat dan mengelola model kustom agar lebih dikenali.

FormRecognizerClient

FormRecognizerClient menyediakan operasi untuk tugas-tugas berikut:

  • Mengenali bidang dan konten formulir, menggunakan model kustom yang dilatih untuk menganalisis formulir kustom Anda. Nilai ini ditampilkan dalam kumpulan objek RecognizedForm. Lihat contoh Menganalisis formulir kustom.
  • Mengenali isi formulir, termasuk tabel, garis, dan kata, tanpa perlu melatih model. Konten formulir dikembalikan dalam kumpulan objek FormPage. Lihat contoh Analisis tata letak.
  • Mengenali bidang umum dari tanda terima, kartu nama, faktur, dan dokumen ID AS menggunakan model yang telah dilatih sebelumnya pada layanan Form Recognizer.

FormTrainingClient

FormTrainingClient menyediakan operasi untuk:

  • Pelatihan model kustom untuk menganalisis semua bidang dan nilai yang ditemukan di formulir kustom Anda. CustomFormModel ditampilkan yang menunjukkan jenis formulir yang akan dianalisis model, dan bidang yang akan diekstrak untuk setiap jenis formulir.
  • Pelatihan model kustom untuk menganalisis bidang dan nilai tertentu yang Anda tentukan dengan memberi label pada formulir kustom. CustomFormModel ditampilkan yang menunjukkan bidang yang akan diekstrak oleh model serta perkiraan akurasi untuk setiap bidang.
  • Mengelola model yang dibuat di akun Anda.
  • Menyalin model kustom dari satu sumber daya Azure Form Recognizer ke sumber daya lainnya.

Catatan

Model juga dapat dilatih menggunakan antarmuka pengguna grafis seperti Alat Pelabelan Azure Form Recognizer.

Autentikasi klien

Di bagian atas metode utama, tambahkan kode berikut. Di sini, Anda akan mengautentikasi dua objek klien menggunakan variabel langganan yang ditentukan di atas. Anda akan menggunakan objek AzureKeyCredential, sehingga jika diperlukan, Anda dapat memperbarui kunci tanpa membuat objek klien baru.

FormRecognizerClient recognizerClient = new FormRecognizerClientBuilder()
        .credential(new AzureKeyCredential(key)).endpoint(endpoint).buildClient();

FormTrainingClient trainingClient = new FormTrainingClientBuilder().credential(new AzureKeyCredential(key))
        .endpoint(endpoint).buildClient();

Menganalisis tata letak

Anda dapat menggunakan Form Recognizer untuk menganalisis tabel, garis, dan kata-kata dalam dokumen, tanpa perlu melatih model. Untuk informasi selengkapnya tentang ekstraksi tata letak, lihat Panduan konseptual tata letak.

Untuk menganalisis konten file di URL tertentu, gunakan metode beginRecognizeContentFromUrl.

private static void GetContent(FormRecognizerClient recognizerClient, String invoiceUri) {
    String analyzeFilePath = invoiceUri;
    SyncPoller<FormRecognizerOperationResult, List<FormPage>> recognizeContentPoller = recognizerClient
            .beginRecognizeContentFromUrl(analyzeFilePath);

    List<FormPage> contentResult = recognizeContentPoller.getFinalResult();

Tip

Anda juga bisa mendapatkan konten dari file lokal. Lihat metode FormRecognizerClient, seperti beginRecognizeContent. Atau, lihat sampel kode di GitHub untuk skenario yang melibatkan gambar lokal.

Nilai yang ditampilkan adalah kumpulan objek FormPage: satu objek untuk setiap halaman dalam dokumen yang dikirimkan. Kode berikut melakukan perulangan melalui objek ini dan mencetak pasangan kunci/nilai yang diekstraksi dan data tabel.

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

Output

Get form content...
----Recognizing content ----
Has width: 8.500000 and height: 11.000000, measured with unit: inch.
Table has 2 rows and 6 columns.
Cell has text Invoice Number.
Cell has text Invoice Date.
Cell has text Invoice Due Date.
Cell has text Charges.
Cell has text VAT ID.
Cell has text 458176.
Cell has text 3/28/2018.
Cell has text 4/16/2018.
Cell has text $89,024.34.
Cell has text ET.

Menganalisis tanda terima

Bagian ini menunjukkan cara menganalisis dan mengekstrak bidang umum dari tanda terima US, menggunakan model tanda terima yang telah dilatih sebelumnya. Untuk mengetahui informasi selengkapnya tentang analisis tanda terima, lihat Panduan konseptual tanda terima.

Untuk menganalisis tanda terima dari URI, gunakan metode beginRecognizeReceiptsFromUrl.

private static void AnalyzeReceipt(FormRecognizerClient recognizerClient, String receiptUri) {
    SyncPoller<FormRecognizerOperationResult, List<RecognizedForm>> syncPoller = recognizerClient
            .beginRecognizeReceiptsFromUrl(receiptUri);
    List<RecognizedForm> receiptPageResults = syncPoller.getFinalResult();

Tip

Anda juga dapat menganalisis gambar tanda terima lokal. Lihat metode FormRecognizerClient, seperti beginRecognizeReceipts. Atau, lihat sampel kode di GitHub untuk skenario yang melibatkan gambar lokal.

Nilai yang ditampilkan adalah kumpulan objek RecognizedReceipt : satu objek untuk setiap halaman dalam dokumen yang dikirimkan. Blok kode berikutnya mengulangi melalui tanda terima dan mencetak detailnya ke konsol.

for (int i = 0; i < receiptPageResults.size(); i++) {
    RecognizedForm recognizedForm = receiptPageResults.get(i);
    Map<String, FormField> recognizedFields = recognizedForm.getFields();
    System.out.printf("----------- Recognized Receipt page %d -----------%n", i);
    FormField merchantNameField = recognizedFields.get("MerchantName");
    if (merchantNameField != null) {
        if (FieldValueType.STRING == merchantNameField.getValue().getValueType()) {
            String merchantName = merchantNameField.getValue().asString();
            System.out.printf("Merchant Name: %s, confidence: %.2f%n", merchantName,
                    merchantNameField.getConfidence());
        }
    }
    FormField merchantAddressField = recognizedFields.get("MerchantAddress");
    if (merchantAddressField != null) {
        if (FieldValueType.STRING == merchantAddressField.getValue().getValueType()) {
            String merchantAddress = merchantAddressField.getValue().asString();
            System.out.printf("Merchant Address: %s, confidence: %.2f%n", merchantAddress,
                    merchantAddressField.getConfidence());
        }
    }
    FormField transactionDateField = recognizedFields.get("TransactionDate");
    if (transactionDateField != null) {
        if (FieldValueType.DATE == transactionDateField.getValue().getValueType()) {
            LocalDate transactionDate = transactionDateField.getValue().asDate();
            System.out.printf("Transaction Date: %s, confidence: %.2f%n", transactionDate,
                    transactionDateField.getConfidence());
        }
    }

Blok kode berikutnya mengulangi melalui item individual yang terdeteksi pada tanda terima dan mencetak detailnya ke konsol.

        FormField receiptItemsField = recognizedFields.get("Items");
        if (receiptItemsField != null) {
            System.out.printf("Receipt Items: %n");
            if (FieldValueType.LIST == receiptItemsField.getValue().getValueType()) {
                List<FormField> receiptItems = receiptItemsField.getValue().asList();
                receiptItems.stream()
                        .filter(receiptItem -> FieldValueType.MAP == receiptItem.getValue().getValueType())
                        .map(formField -> formField.getValue().asMap())
                        .forEach(formFieldMap -> formFieldMap.forEach((key, formField) -> {
                            if ("Name".equals(key)) {
                                if (FieldValueType.STRING == formField.getValue().getValueType()) {
                                    String name = formField.getValue().asString();
                                    System.out.printf("Name: %s, confidence: %.2fs%n", name,
                                            formField.getConfidence());
                                }
                            }
                            if ("Quantity".equals(key)) {
                                if (FieldValueType.FLOAT == formField.getValue().getValueType()) {
                                    Float quantity = formField.getValue().asFloat();
                                    System.out.printf("Quantity: %f, confidence: %.2f%n", quantity,
                                            formField.getConfidence());
                                }
                            }
                            if ("Price".equals(key)) {
                                if (FieldValueType.FLOAT == formField.getValue().getValueType()) {
                                    Float price = formField.getValue().asFloat();
                                    System.out.printf("Price: %f, confidence: %.2f%n", price,
                                            formField.getConfidence());
                                }
                            }
                            if ("TotalPrice".equals(key)) {
                                if (FieldValueType.FLOAT == formField.getValue().getValueType()) {
                                    Float totalPrice = formField.getValue().asFloat();
                                    System.out.printf("Total Price: %f, confidence: %.2f%n", totalPrice,
                                            formField.getConfidence());
                                }
                            }
                        }));
            }
        }
    }
}

Output

Analyze receipt...
----------- Recognized Receipt page 0 -----------
Merchant Name: Contoso Contoso, confidence: 0.62
Merchant Address: 123 Main Street Redmond, WA 98052, confidence: 0.99
Transaction Date: 2020-06-10, confidence: 0.90
Receipt Items:
Name: Cappuccino, confidence: 0.96s
Quantity: null, confidence: 0.957s]
Total Price: 2.200000, confidence: 0.95
Name: BACON & EGGS, confidence: 0.94s
Quantity: null, confidence: 0.927s]
Total Price: null, confidence: 0.93

Menganalisis kartu bisnis

Bagian ini menunjukkan cara menganalisis dan mengekstrak bidang umum dari kartu bisnis berbahasa Inggris menggunakan model yang dilatih sebelumnya. Untuk informasi selengkapnya tentang analisis kartu bisnis, lihat Panduan konseptual kartu bisnis.

Untuk menganalisis kartu bisnis dari URL, gunakan metode beginRecognizeBusinessCardsFromUrl.

private static void AnalyzeBusinessCard(FormRecognizerClient recognizerClient, String bcUrl) {
    SyncPoller < FormRecognizerOperationResult,
    List < RecognizedForm >> recognizeBusinessCardPoller = client.beginRecognizeBusinessCardsFromUrl(businessCardUrl);

    List < RecognizedForm > businessCardPageResults = recognizeBusinessCardPoller.getFinalResult();

Tip

Anda juga dapat menganalisis gambar kartu bisnis lokal. Lihat metode FormRecognizerClient, seperti beginRecognizeBusinessCards. Atau, lihat sampel kode di GitHub untuk skenario yang melibatkan gambar lokal.

Nilai yang ditampilkan adalah kumpulan objek RecognizedForm: satu untuk setiap kartu dalam dokumen. Kode berikut memproses kartu bisnis di URI tertentu dan mencetak bidang dan nilai utama ke konsol.

    for (int i = 0; i < businessCardPageResults.size(); i++) {
        RecognizedForm recognizedForm = businessCardPageResults.get(i);
        Map < String,
        FormField > recognizedFields = recognizedForm.getFields();
        System.out.printf("----------- Recognized business card info for page %d -----------%n", i);
        FormField contactNamesFormField = recognizedFields.get("ContactNames");
        if (contactNamesFormField != null) {
            if (FieldValueType.LIST == contactNamesFormField.getValue().getValueType()) {
                List < FormField > contactNamesList = contactNamesFormField.getValue().asList();
                contactNamesList.stream().filter(contactName - >FieldValueType.MAP == contactName.getValue().getValueType()).map(contactName - >{
                    System.out.printf("Contact name: %s%n", contactName.getValueData().getText());
                    return contactName.getValue().asMap();
                }).forEach(contactNamesMap - >contactNamesMap.forEach((key, contactName) - >{
                    if ("FirstName".equals(key)) {
                        if (FieldValueType.STRING == contactName.getValue().getValueType()) {
                            String firstName = contactName.getValue().asString();
                            System.out.printf("\tFirst Name: %s, confidence: %.2f%n", firstName, contactName.getConfidence());
                        }
                    }
                    if ("LastName".equals(key)) {
                        if (FieldValueType.STRING == contactName.getValue().getValueType()) {
                            String lastName = contactName.getValue().asString();
                            System.out.printf("\tLast Name: %s, confidence: %.2f%n", lastName, contactName.getConfidence());
                        }
                    }
                }));
            }
        }

        FormField jobTitles = recognizedFields.get("JobTitles");
        if (jobTitles != null) {
            if (FieldValueType.LIST == jobTitles.getValue().getValueType()) {
                List < FormField > jobTitlesItems = jobTitles.getValue().asList();
                jobTitlesItems.stream().forEach(jobTitlesItem - >{
                    if (FieldValueType.STRING == jobTitlesItem.getValue().getValueType()) {
                        String jobTitle = jobTitlesItem.getValue().asString();
                        System.out.printf("Job Title: %s, confidence: %.2f%n", jobTitle, jobTitlesItem.getConfidence());
                    }
                });
            }
        }

        FormField departments = recognizedFields.get("Departments");
        if (departments != null) {
            if (FieldValueType.LIST == departments.getValue().getValueType()) {
                List < FormField > departmentsItems = departments.getValue().asList();
                departmentsItems.stream().forEach(departmentsItem - >{
                    if (FieldValueType.STRING == departmentsItem.getValue().getValueType()) {
                        String department = departmentsItem.getValue().asString();
                        System.out.printf("Department: %s, confidence: %.2f%n", department, departmentsItem.getConfidence());
                    }
                });
            }
        }

        FormField emails = recognizedFields.get("Emails");
        if (emails != null) {
            if (FieldValueType.LIST == emails.getValue().getValueType()) {
                List < FormField > emailsItems = emails.getValue().asList();
                emailsItems.stream().forEach(emailsItem - >{
                    if (FieldValueType.STRING == emailsItem.getValue().getValueType()) {
                        String email = emailsItem.getValue().asString();
                        System.out.printf("Email: %s, confidence: %.2f%n", email, emailsItem.getConfidence());
                    }
                });
            }
        }

        FormField websites = recognizedFields.get("Websites");
        if (websites != null) {
            if (FieldValueType.LIST == websites.getValue().getValueType()) {
                List < FormField > websitesItems = websites.getValue().asList();
                websitesItems.stream().forEach(websitesItem - >{
                    if (FieldValueType.STRING == websitesItem.getValue().getValueType()) {
                        String website = websitesItem.getValue().asString();
                        System.out.printf("Web site: %s, confidence: %.2f%n", website, websitesItem.getConfidence());
                    }
                });
            }
        }

        FormField mobilePhones = recognizedFields.get("MobilePhones");
        if (mobilePhones != null) {
            if (FieldValueType.LIST == mobilePhones.getValue().getValueType()) {
                List < FormField > mobilePhonesItems = mobilePhones.getValue().asList();
                mobilePhonesItems.stream().forEach(mobilePhonesItem - >{
                    if (FieldValueType.PHONE_NUMBER == mobilePhonesItem.getValue().getValueType()) {
                        String mobilePhoneNumber = mobilePhonesItem.getValue().asPhoneNumber();
                        System.out.printf("Mobile phone number: %s, confidence: %.2f%n", mobilePhoneNumber, mobilePhonesItem.getConfidence());
                    }
                });
            }
        }

        FormField otherPhones = recognizedFields.get("OtherPhones");
        if (otherPhones != null) {
            if (FieldValueType.LIST == otherPhones.getValue().getValueType()) {
                List < FormField > otherPhonesItems = otherPhones.getValue().asList();
                otherPhonesItems.stream().forEach(otherPhonesItem - >{
                    if (FieldValueType.PHONE_NUMBER == otherPhonesItem.getValue().getValueType()) {
                        String otherPhoneNumber = otherPhonesItem.getValue().asPhoneNumber();
                        System.out.printf("Other phone number: %s, confidence: %.2f%n", otherPhoneNumber, otherPhonesItem.getConfidence());
                    }
                });
            }
        }

        FormField faxes = recognizedFields.get("Faxes");
        if (faxes != null) {
            if (FieldValueType.LIST == faxes.getValue().getValueType()) {
                List < FormField > faxesItems = faxes.getValue().asList();
                faxesItems.stream().forEach(faxesItem - >{
                    if (FieldValueType.PHONE_NUMBER == faxesItem.getValue().getValueType()) {
                        String faxPhoneNumber = faxesItem.getValue().asPhoneNumber();
                        System.out.printf("Fax phone number: %s, confidence: %.2f%n", faxPhoneNumber, faxesItem.getConfidence());
                    }
                });
            }
        }

        FormField addresses = recognizedFields.get("Addresses");
        if (addresses != null) {
            if (FieldValueType.LIST == addresses.getValue().getValueType()) {
                List < FormField > addressesItems = addresses.getValue().asList();
                addressesItems.stream().forEach(addressesItem - >{
                    if (FieldValueType.STRING == addressesItem.getValue().getValueType()) {
                        String address = addressesItem.getValue().asString();
                        System.out.printf("Address: %s, confidence: %.2f%n", address, addressesItem.getConfidence());
                    }
                });
            }
        }

        FormField companyName = recognizedFields.get("CompanyNames");
        if (companyName != null) {
            if (FieldValueType.LIST == companyName.getValue().getValueType()) {
                List < FormField > companyNameItems = companyName.getValue().asList();
                companyNameItems.stream().forEach(companyNameItem - >{
                    if (FieldValueType.STRING == companyNameItem.getValue().getValueType()) {
                        String companyNameValue = companyNameItem.getValue().asString();
                        System.out.printf("Company name: %s, confidence: %.2f%n", companyNameValue, companyNameItem.getConfidence());
                    }
                });
            }
        }
    }
}

Menganalisis faktur

Bagian ini menunjukkan cara menganalisis dan mengekstrak bidang umum dari faktur penjualan, menggunakan model yang sudah dilatih sebelumnya. Untuk mengetahui informasi selengkapnya tentang analisis faktur, lihat Panduan konseptual faktur.

Untuk menganalisis faktur dari URL, gunakan metode beginRecognizeInvoicesFromUrl.

private static void AnalyzeInvoice(FormRecognizerClient recognizerClient, String invoiceUrl) {
    SyncPoller < FormRecognizerOperationResult,
    List < RecognizedForm >> recognizeInvoicesPoller = client.beginRecognizeInvoicesFromUrl(invoiceUrl);

    List < RecognizedForm > recognizedInvoices = recognizeInvoicesPoller.getFinalResult();

Tip

Anda juga dapat menganalisis faktur lokal. Lihat metode FormRecognizerClient, seperti beginRecognizeInvoices. Atau, lihat sampel kode di GitHub untuk skenario yang melibatkan gambar lokal.

Nilai yang ditampilkan adalah kumpulan objek RecognizedForm: satu untuk setiap faktur dalam dokumen. Kode berikut memproses faktur di URI tertentu dan mencetak bidang dan nilai utama ke konsol.

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

Menganalisis dokumen ID

Bagian ini menunjukkan cara menganalisis dan mengekstrak informasi kunci dari dokumen identifikasi yang dikeluarkan pemerintah—paspor di seluruh dunia dan SIM AS—menggunakan model ID bawaan Form Recognizer. Untuk mengetahui informasi selengkapnya tentang analisis dokumen identitas, lihat panduan konseptual model identifikasi bawaan kami.

Untuk menganalisis dokumen ID dari URI, gunakan metode beginRecognizeIdentityDocumentsFromUrl.

private static void AnalyzeId(FormRecognizerClient client, String idUrl) {
    SyncPoller < FormRecognizerOperationResult,
    List < RecognizedForm >> analyzeIdentityDocumentPoller = client.beginRecognizeIdentityDocumentsFromUrl(licenseDocumentUrl);

    List < RecognizedForm > identityDocumentResults = analyzeIdentityDocumentPoller.getFinalResult();

Tip

Anda juga dapat menganalisis gambar dokumen ID lokal. Lihat metode FormRecognizerClient, seperti beginRecognizeIdDocuments. Atau, lihat kode sampel do GitHub untuk skenario yang melibatkan gambar lokal.

Kode berikut memproses dokumen ID di URI tertentu dan mencetak bidang serta nilai utama ke konsol.

for (int i = 0; i < identityDocumentResults.size(); i++) {
    RecognizedForm recognizedForm = identityDocumentResults.get(i);
    Map < String,
    FormField > recognizedFields = recognizedForm.getFields();
    System.out.printf("----------- Recognized license info for page %d -----------%n", i);
    FormField addressField = recognizedFields.get("Address");
    if (addressField != null) {
        if (FieldValueType.STRING == addressField.getValue().getValueType()) {
            String address = addressField.getValue().asString();
            System.out.printf("Address: %s, confidence: %.2f%n", address, addressField.getConfidence());
        }
    }

    FormField countryRegionFormField = recognizedFields.get("CountryRegion");
    if (countryRegionFormField != null) {
        if (FieldValueType.STRING == countryRegionFormField.getValue().getValueType()) {
            String countryRegion = countryRegionFormField.getValue().asCountryRegion();
            System.out.printf("Country or region: %s, confidence: %.2f%n", countryRegion, countryRegionFormField.getConfidence());
        }
    }

    FormField dateOfBirthField = recognizedFields.get("DateOfBirth");
    if (dateOfBirthField != null) {
        if (FieldValueType.DATE == dateOfBirthField.getValue().getValueType()) {
            LocalDate dateOfBirth = dateOfBirthField.getValue().asDate();
            System.out.printf("Date of Birth: %s, confidence: %.2f%n", dateOfBirth, dateOfBirthField.getConfidence());
        }
    }

    FormField dateOfExpirationField = recognizedFields.get("DateOfExpiration");
    if (dateOfExpirationField != null) {
        if (FieldValueType.DATE == dateOfExpirationField.getValue().getValueType()) {
            LocalDate expirationDate = dateOfExpirationField.getValue().asDate();
            System.out.printf("Document date of expiration: %s, confidence: %.2f%n", expirationDate, dateOfExpirationField.getConfidence());
        }
    }

    FormField documentNumberField = recognizedFields.get("DocumentNumber");
    if (documentNumberField != null) {
        if (FieldValueType.STRING == documentNumberField.getValue().getValueType()) {
            String documentNumber = documentNumberField.getValue().asString();
            System.out.printf("Document number: %s, confidence: %.2f%n", documentNumber, documentNumberField.getConfidence());
        }
    }

    FormField firstNameField = recognizedFields.get("FirstName");
    if (firstNameField != null) {
        if (FieldValueType.STRING == firstNameField.getValue().getValueType()) {
            String firstName = firstNameField.getValue().asString();
            System.out.printf("First Name: %s, confidence: %.2f%n", firstName, documentNumberField.getConfidence());
        }
    }

    FormField lastNameField = recognizedFields.get("LastName");
    if (lastNameField != null) {
        if (FieldValueType.STRING == lastNameField.getValue().getValueType()) {
            String lastName = lastNameField.getValue().asString();
            System.out.printf("Last name: %s, confidence: %.2f%n", lastName, lastNameField.getConfidence());
        }
    }

    FormField regionField = recognizedFields.get("Region");
    if (regionField != null) {
        if (FieldValueType.STRING == regionField.getValue().getValueType()) {
            String region = regionField.getValue().asString();
            System.out.printf("Region: %s, confidence: %.2f%n", region, regionField.getConfidence());
        }
    }
}

Melatih model kustom

Bagian ini menunjukkan cara melatih model dengan data Anda sendiri. Model terlatih dapat menampilkan data terstruktur yang menyertakan hubungan kunci/nilai dalam dokumen formulir asli. Setelah melatih model, Anda dapat menguji, melatih kembali, dan akhirnya menggunakannya untuk mengekstrak data secara andal dari lebih banyak formulir sesuai kebutuhan Anda.

Catatan

Anda juga dapat melatih model dengan antarmuka pengguna grafis seperti alat Pelabelan Sampel Form Recognizer.

Melatih model tanpa label

Latih model kustom untuk menganalisis semua bidang dan nilai yang ditemukan dalam formulir kustom tanpa memberi label dokumen pelatihan secara manual.

Metode berikut melatih model pada kumpulan dokumen tertentu dan mencetak status model ke konsol.

private static String TrainModel(FormTrainingClient trainingClient, String trainingDataUrl) {
    SyncPoller<FormRecognizerOperationResult, CustomFormModel> trainingPoller = trainingClient
            .beginTraining(trainingDataUrl, false);

    CustomFormModel customFormModel = trainingPoller.getFinalResult();

    // Model Info
    System.out.printf("Model Id: %s%n", customFormModel.getModelId());
    System.out.printf("Model Status: %s%n", customFormModel.getModelStatus());
    System.out.printf("Training started on: %s%n", customFormModel.getTrainingStartedOn());
    System.out.printf("Training completed on: %s%n%n", customFormModel.getTrainingCompletedOn());

Objek CustomFormModel yang ditampilkan berisi informasi tentang jenis formulir yang dapat dianalisis model dan bidang yang dapat diekstrak dari setiap jenis formulir. Blok kode berikut mencetak informasi ini ke konsol.

System.out.println("Recognized Fields:");
// looping through the subModels, which contains the fields they were trained on
// Since the given training documents are unlabeled, we still group them but
// they do not have a label.
customFormModel.getSubmodels().forEach(customFormSubmodel -> {
    // Since the training data is unlabeled, we are unable to return the accuracy of
    // this model
    System.out.printf("The subModel has form type %s%n", customFormSubmodel.getFormType());
    customFormSubmodel.getFields().forEach((field, customFormModelField) -> System.out
            .printf("The model found field '%s' with label: %s%n", field, customFormModelField.getLabel()));
});

Terakhir, metode ini menampilkan ID unik model.

    return customFormModel.getModelId();
}

Output

Train Model with training data...
Model Id: 20c3544d-97b4-49d9-b39b-dc32d85f1358
Model Status: ready
Training started on: 2020-08-31T16:52:09Z
Training completed on: 2020-08-31T16:52:23Z

Recognized Fields:
The subModel has form type form-0
The model found field 'field-0' with label: Address:
The model found field 'field-1' with label: Charges
The model found field 'field-2' with label: Invoice Date
The model found field 'field-3' with label: Invoice Due Date
The model found field 'field-4' with label: Invoice For:
The model found field 'field-5' with label: Invoice Number
The model found field 'field-6' with label: VAT ID

Melatih model dengan label

Anda juga dapat melatih model kustom dengan memberi label secara manual pada dokumen pelatihan. Pelatihan dengan label berdampak pada performa yang lebih baik dalam beberapa skenario. Untuk berlatih dengan label, Anda harus memiliki file informasi label khusus (<namafile>.pdf.labels.json) di kontainer penyimpanan blob Anda di samping dokumen pelatihan. Alat Pelabelan Sampel Form Recognizer menyediakan UI untuk membantu Anda membuat file label ini. Setelah mendapatkannya, Anda dapat memanggil metode beginTraining dengan parameter useTrainingLabels diatur ke true.

private static String TrainModelWithLabels(FormTrainingClient trainingClient, String trainingDataUrl) {
    // Train custom model
    String trainingSetSource = trainingDataUrl;
    SyncPoller<FormRecognizerOperationResult, CustomFormModel> trainingPoller = trainingClient
            .beginTraining(trainingSetSource, true);

    CustomFormModel customFormModel = trainingPoller.getFinalResult();

    // Model Info
    System.out.printf("Model Id: %s%n", customFormModel.getModelId());
    System.out.printf("Model Status: %s%n", customFormModel.getModelStatus());
    System.out.printf("Training started on: %s%n", customFormModel.getTrainingStartedOn());
    System.out.printf("Training completed on: %s%n%n", customFormModel.getTrainingCompletedOn());

CustomFormModel yang ditampilkan menunjukkan bidang yang dapat diekstrak model, bersama dengan perkiraan akurasinya di setiap bidang. Blok kode berikut mencetak informasi ini ke konsol.

    // looping through the subModels, which contains the fields they were trained on
    // The labels are based on the ones you gave the training document.
    System.out.println("Recognized Fields:");
    // Since the data is labeled, we are able to return the accuracy of the model
    customFormModel.getSubmodels().forEach(customFormSubmodel -> {
        System.out.printf("The subModel with form type %s has accuracy: %.2f%n", customFormSubmodel.getFormType(),
                customFormSubmodel.getAccuracy());
        customFormSubmodel.getFields()
                .forEach((label, customFormModelField) -> System.out.printf(
                        "The model found field '%s' to have name: %s with an accuracy: %.2f%n", label,
                        customFormModelField.getName(), customFormModelField.getAccuracy()));
    });
    return customFormModel.getModelId();
}

Output

Train Model with training data...
Model Id: 20c3544d-97b4-49d9-b39b-dc32d85f1358
Model Status: ready
Training started on: 2020-08-31T16:52:09Z
Training completed on: 2020-08-31T16:52:23Z

Recognized Fields:
The subModel has form type form-0
The model found field 'field-0' with label: Address:
The model found field 'field-1' with label: Charges
The model found field 'field-2' with label: Invoice Date
The model found field 'field-3' with label: Invoice Due Date
The model found field 'field-4' with label: Invoice For:
The model found field 'field-5' with label: Invoice Number
The model found field 'field-6' with label: VAT ID

Menganalisis formulir dengan model kustom

Bagian ini menunjukkan cara mengekstrak informasi kunci/nilai dan konten lainnya dari jenis templat kustom Anda, menggunakan model yang Anda latih dengan formulir Anda sendiri.

Penting

Untuk menerapkan skenario ini, Anda harus sudah melatih model sehingga dapat meneruskan ID model ke metode di bawah ini. Lihat bagianMelatih model.

Anda akan menggunakan metode beginRecognizeCustomFormsFromUrl.

// Analyze PDF form data
private static void AnalyzePdfForm(FormRecognizerClient formClient, String modelId, String pdfFormUrl) {
    SyncPoller<FormRecognizerOperationResult, List<RecognizedForm>> recognizeFormPoller = formClient
            .beginRecognizeCustomFormsFromUrl(modelId, pdfFormUrl);

    List<RecognizedForm> recognizedForms = recognizeFormPoller.getFinalResult();

Tip

Anda juga dapat menganalisis file lokal. Lihat metode FormRecognizerClient, seperti beginRecognizeCustomForms. Atau, lihat sampel kode di GitHub untuk skenario yang melibatkan gambar lokal.

Nilai yang dikembalikan adalah kumpulan objek RecognizedForm: satu objek untuk setiap halaman dalam dokumen yang dikirimkan. Kode berikut mencetak hasil analisis ke konsol. Kode mencetak setiap bidang yang dikenali dan nilai yang sesuai, bersama dengan skor keyakinan.

    for (int i = 0; i < recognizedForms.size(); i++) {
        final RecognizedForm form = recognizedForms.get(i);
        System.out.printf("----------- Recognized custom form info for page %d -----------%n", i);
        System.out.printf("Form type: %s%n", form.getFormType());
        form.getFields().forEach((label, formField) ->
        // label data is populated if you are using a model trained with unlabeled data,
        // since the service needs to make predictions for labels if not explicitly
        // given to it.
        System.out.printf("Field '%s' has label '%s' with a confidence " + "score of %.2f.%n", label,
                formField.getLabelData().getText(), formField.getConfidence()));
    }
}

Output

Analyze PDF form...
----------- Recognized custom template info for page 0 -----------
Form type: form-0
Field 'field-0' has label 'Address:' with a confidence score of 0.91.
Field 'field-1' has label 'Invoice For:' with a confidence score of 1.00.
Field 'field-2' has label 'Invoice Number' with a confidence score of 1.00.
Field 'field-3' has label 'Invoice Date' with a confidence score of 1.00.
Field 'field-4' has label 'Invoice Due Date' with a confidence score of 1.00.
Field 'field-5' has label 'Charges' with a confidence score of 1.00.
Field 'field-6' has label 'VAT ID' with a confidence score of 1.00.

Mengelola model kustom

Bagian ini menunjukkan cara mengelola model kustom yang disimpan di akun Anda. Kode berikut melakukan semua tugas pengelolaan model dalam satu metode, sebagai contoh. Mulai dengan menyalin tanda tangan metode di bawah:

private static void ManageModels(FormTrainingClient trainingClient, String trainingFileUrl) {

Memeriksa jumlah model di akun sumber daya FormRecognizer

Blok kode berikut memeriksa banyaknya model yang Anda simpan di akun Form Recognizer dan membandingkannya dengan batas akun.

AtomicReference<String> modelId = new AtomicReference<>();

// First, we see how many custom models we have, and what our limit is
AccountProperties accountProperties = trainingClient.getAccountProperties();
System.out.printf("The account has %s custom models, and we can have at most %s custom models",
        accountProperties.getCustomModelCount(), accountProperties.getCustomModelLimit());

Output

The account has 12 custom models, and we can have at most 250 custom models

Mencantumkan model yang saat ini disimpan di akun sumber daya

Kode berikut memblokir model saat ini di akun Anda dan mencetak detailnya ke konsol.

// Next, we get a paged list of all of our custom models
PagedIterable<CustomFormModelInfo> customModels = trainingClient.listCustomModels();
System.out.println("We have following models in the account:");
customModels.forEach(customFormModelInfo -> {
    System.out.printf("Model Id: %s%n", customFormModelInfo.getModelId());
    // get custom model info
    modelId.set(customFormModelInfo.getModelId());
    CustomFormModel customModel = trainingClient.getCustomModel(customFormModelInfo.getModelId());
    System.out.printf("Model Id: %s%n", customModel.getModelId());
    System.out.printf("Model Status: %s%n", customModel.getModelStatus());
    System.out.printf("Training started on: %s%n", customModel.getTrainingStartedOn());
    System.out.printf("Training completed on: %s%n", customModel.getTrainingCompletedOn());
    customModel.getSubmodels().forEach(customFormSubmodel -> {
        System.out.printf("Custom Model Form type: %s%n", customFormSubmodel.getFormType());
        System.out.printf("Custom Model Accuracy: %.2f%n", customFormSubmodel.getAccuracy());
        if (customFormSubmodel.getFields() != null) {
            customFormSubmodel.getFields().forEach((fieldText, customFormModelField) -> {
                System.out.printf("Field Text: %s%n", fieldText);
                System.out.printf("Field Accuracy: %.2f%n", customFormModelField.getAccuracy());
            });
        }
    });
});

Output

Respons ini telah dipotong agar mudah dibaca.

We have following models in the account:
Model Id: 0b048b60-86cc-47ec-9782-ad0ffaf7a5ce
Model Id: 0b048b60-86cc-47ec-9782-ad0ffaf7a5ce
Model Status: ready
Training started on: 2020-06-04T18:33:08Z
Training completed on: 2020-06-04T18:33:10Z
Custom Model Form type: form-0b048b60-86cc-47ec-9782-ad0ffaf7a5ce
Custom Model Accuracy: 1.00
Field Text: invoice date
Field Accuracy: 1.00
Field Text: invoice number
Field Accuracy: 1.00
...

Menghapus model dari akun sumber daya

Anda juga dapat menghapus model dari akun dengan mereferensikan ID-nya.

    // Delete Custom Model
    System.out.printf("Deleted model with model Id: %s, operation completed with status: %s%n", modelId.get(),
            trainingClient.deleteModelWithResponse(modelId.get(), Context.NONE).getStatusCode());
}

Menjalankan aplikasi

Buka kembali direktori proyek utama. Kemudian, jalankan aplikasi dengan perintah berikut:

gradle build

Jalankan aplikasi dengan tujuan run:

gradle run

Membersihkan sumber daya

Jika ingin membersihkan dan menghapus langganan Cognitive Services, Anda dapat menghapus sumber daya atau grup sumber daya. Menghapus grup sumber daya juga menghapus sumber daya apa pun yang terkait dengannya.

Pemecahan Masalah

Klien Form Recognizer mengajukan pengecualian ErrorResponseException. Misalnya, jika Anda mencoba memberikan URL sumber file yang tidak valid, ErrorResponseException akan dinaikkan dengan kesalahan yang menunjukkan penyebab kegagalan. Dalam cuplikan kode berikut, kesalahan ditangani dengan baik dengan menangkap pengecualian dan menampilkan informasi tambahan tentang kesalahan tersebut.

try {
    formRecognizerClient.beginRecognizeContentFromUrl("invalidSourceUrl");
} catch (ErrorResponseException e) {
    System.out.println(e.getMessage());
}

Mengaktifkan pengelogan klien

Azure SDK untuk Java menawarkan kisah pengelogan yang konsisten untuk membantu memecahkan masalah kesalahan aplikasi dan mempercepat resolusinya. Log yang dihasilkan akan menangkap alur aplikasi sebelum mencapai status terminal untuk membantu menemukan masalah akar. Lihat wiki pengelogan untuk panduan tentang mengaktifkan pengelogan.

Langkah berikutnya

Untuk proyek ini, Anda menggunakan pustaka klien Java Form Recognizer untuk melatih model dan menganalisis formulir dengan cara yang berbeda. Selanjutnya, pelajari tips untuk membuat himpunan data pelatihan yang lebih baik dan membuat model yang lebih akurat.

Penting

Proyek ini menargetkan Form Recognizer REST API versi 2.1.

Dokumentasi referensi | Kode sumber pustaka | Paket (npm) | Sampel

Prasyarat

  • Langganan Azure - Membuat langganan gratis
  • Versi terbaru Node.js
  • Blob Azure Storage yang berisi set data pelatihan. Lihat Membangun himpunan data pelatihan untuk model kustom untuk tips dan opsi dalam menyusun himpunan data pelatihan Anda. Untuk proyek ini, Anda dapat menggunakan file dalam folder Latihan dari himpunan data sampel (unduh dan ekstrak sample_data.zip).
  • Setelah Anda berlangganan Azure, buat sumber daya Form Recognizer di portal Microsoft Azure untuk mendapatkan kunci dan titik akhir Anda. Setelah menyebar, pilih Buka sumber daya.
    • Anda akan memerlukan kunci dan titik akhir sumber daya yang Anda buat untuk menghubungkan aplikasi ke API Form Recognizer. Anda akan menempelkan kunci dan titik akhir Anda ke dalam kode di bawah ini nanti di proyek
    • Anda bisa menggunakan tingkat harga gratis (F0) untuk mencoba layanan, lalu meningkatkan ke tingkat berbayar untuk produksi.

Tip

Buat sumber daya Cognitive Services jika Anda berencana untuk mengakses beberapa layanan kognitif di bawah satu titik akhir/kunci. Hanya untuk akses Form Recognizer, buat sumber daya Form Recognizer. Harap perhatikan bahwa Anda memerlukan sumber daya layanan tunggal jika ingin menggunakan Autentikasi Azure Active Directory.

Persiapan

Buat aplikasi Node.js baru

Di jendela konsol (seperti cmd, PowerShell, atau Bash), buat direktori baru untuk aplikasi Anda, dan arahkan ke sana.

mkdir myapp && cd myapp

Jalankan perintah npm init untuk membuat aplikasi node dengan file package.json.

npm init

Memasang pustaka klien

Instal paket npm ai-form-recognizer:

npm install @azure/ai-form-recognizer

File aplikasi Anda package.json akan diperbarui dengan dependensi.

Buat file bernama index.js, buka, dan impor pustaka berikut ini:

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

Buat variabel untuk titik akhir dan kunci Azure dari sumber daya Anda.

const apiKey = "PASTE_YOUR_FORM_RECOGNIZER_SUBSCRIPTION_KEY_HERE";
const endpoint = "PASTE_YOUR_FORM_RECOGNIZER_ENDPOINT_HERE";

Penting

Masuk ke portal Microsoft Azure. Jika sumber daya Azure Form Recognizer yang Anda buat di bagian Prasyarat berhasil disebarkan, klik tombol Buka Sumber daya di bawah Langkah Berikutnya. Anda dapat menemukan kunci dan titik akhir Anda di halaman kunci dan titik akhir sumber daya, di bawah manajemen sumber daya.

Ingatlah untuk menghapus kunci dari kode Anda setelah selesai, dan jangan pernah memposting kode secara publik. Untuk produksi, gunakan metode aman untuk menyimpan dan mengakses info masuk Anda. Untuk informasi selengkapnya, lihat artikel keamanan Cognitive Services.

Model objek

Dengan Azure Form Recognizer, Anda dapat membuat dua jenis klien yang berbeda. Yang pertama, FormRecognizerClient digunakan untuk mengkueri layanan ke bidang isian borang dan konten yang dikenali. Yang kedua, FormTrainingClient digunakan untuk membuat dan mengelola model kustom agar lebih dikenali.

FormRecognizerClient

FormRecognizerClient menyediakan operasi berikut:

  • Mengenali bidang formulir dan konten menggunakan model kustom yang dilatih untuk menganalisis formulir kustom Anda. Nilai ini ditampilkan dalam kumpulan objek RecognizedForm.
  • Mengenali isi formulir, termasuk tabel, garis, dan kata, tanpa perlu melatih model. Konten formulir dikembalikan dalam kumpulan objek FormPage.
  • Mengenali bidang umum dari tanda terima, kartu nama, faktur, dan dokumen ID AS menggunakan model yang telah dilatih sebelumnya pada layanan Form Recognizer.

FormTrainingClient

FormTrainingClient menyediakan operasi untuk:

  • Pelatihan model kustom untuk menganalisis semua bidang dan nilai yang ditemukan di formulir kustom Anda. CustomFormModel ditampilkan yang menunjukkan jenis formulir yang akan dianalisis model, dan bidang yang akan diekstrak untuk setiap jenis formulir. Untuk informasi selengkapnya, lihatdokumentasi layanan tentang pelatihan model tanpa label.
  • Pelatihan model kustom untuk menganalisis bidang dan nilai tertentu yang Anda tentukan dengan memberi label pada formulir kustom. CustomFormModel dikembalikan yang menunjukkan bidang yang akan diekstrak oleh model, serta perkiraan akurasi untuk setiap bidang. Lihat dokumentasi layanan tentang pelatihan model berlabel untuk penjelasan lebih mendetail tentang menerapkan label pada himpunan data pelatihan.
  • Mengelola model yang dibuat di akun Anda.
  • Menyalin model kustom dari satu sumber daya Azure Form Recognizer ke sumber daya lainnya.

Catatan

Model juga dapat dilatih menggunakan antarmuka pengguna grafis seperti Alat Pelabelan Azure Form Recognizer.

Autentikasi klien

Mengautentikasi objek klien menggunakan variabel langganan yang Anda tentukan. Anda akan menggunakan objek AzureKeyCredential, sehingga jika diperlukan, Anda dapat memperbarui kunci tanpa membuat objek klien baru. Anda juga akan membuat objek klien pelatihan.

const trainingClient = new FormTrainingClient(endpoint, new AzureKeyCredential(apiKey));
const client = new FormRecognizerClient(endpoint, new AzureKeyCredential(apiKey));

Mendapatkan aset untuk pengujian

Anda juga harus menambahkan referensi ke URL untuk data pelatihan dan pengujian.

  • Untuk mengambil URL SAS untuk data pelatihan model kustom Anda, buka sumber daya penyimpanan di portal Microsoft Azure dan pilih tab Penjelajah Penyimpanan. Buka kontainer Anda, klik kanan, lalu pilih Dapatkan tanda tangan akses bersama. Sangat penting untuk mendapatkan SAS untuk kontainer Anda, bukan untuk akun penyimpanan itu sendiri. Pastikan izin Baca, Tulis, Hapus, dan Cantumkan dicentang, lalu klik Buat. Kemudian salin nilai di bagian URL ke lokasi sementara. Ini harus memiliki format: https://<storage account>.blob.core.windows.net/<container name>?<SAS value>.

    Pengambilan URL SAS

  • Gunakan contoh dari dan gambar tanda terima yang disertakan dalam contoh di bawah ini (juga tersedia di GitHub). Anda dapat menggunakan langkah-langkah di atas untuk mendapatkan URL SAS dari masing-masing dokumen dalam penyimpanan blob.

Menganalisis tata letak

Anda dapat menggunakan Form Recognizer untuk menganalisis tabel, garis, dan kata-kata dalam dokumen, tanpa perlu melatih model. Untuk informasi selengkapnya tentang ekstraksi tata letak, lihat Panduan konseptual tata letak. Untuk menganalisis konten file pada URI yang diberikan, gunakan metode beginRecognizeContentFromUrl.

async function recognizeContent() {
    const formUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/simple-invoice.png";
    const poller = await client.beginRecognizeContentFromUrl(formUrl);
    const pages = await poller.pollUntilDone();

    if (!pages || pages.length === 0) {
        throw new Error("Expecting non-empty list of pages!");
    }

    for (const page of pages) {
        console.log(
            `Page ${page.pageNumber}: width ${page.width} and height ${page.height} with unit ${page.unit}`
        );
        for (const table of page.tables) {
            for (const cell of table.cells) {
                console.log(`cell [${cell.rowIndex},${cell.columnIndex}] has text ${cell.text}`);
            }
        }
    }
}

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

Tip

Anda juga bisa mendapatkan konten dari file lokal dengan metode FormRecognizerClient, seperti beginRecognizeContent.

Output

Page 1: width 8.5 and height 11 with unit inch
cell [0,0] has text Invoice Number
cell [0,1] has text Invoice Date
cell [0,2] has text Invoice Due Date
cell [0,3] has text Charges
cell [0,5] has text VAT ID
cell [1,0] has text 34278587
cell [1,1] has text 6/18/2017
cell [1,2] has text 6/24/2017
cell [1,3] has text $56,651.49
cell [1,5] has text PT

Menganalisis tanda terima

Bagian ini menunjukkan cara menganalisis dan mengekstrak bidang umum dari tanda terima US, menggunakan model tanda terima yang telah dilatih sebelumnya. Untuk informasi selengkapnya tentang analisis tanda terima, lihat Panduan konseptual tanda terima.

Untuk menganalisis tanda terima dari URI, gunakan metode beginRecognizeReceiptsFromUrl. Kode berikut memproses tanda terima di URI yang diberikan serta menampilkan bidang dan nilai utama pada konsol.

async function recognizeReceipt() {
    receiptUrl = "https://raw.githubusercontent.com/Azure/azure-sdk-for-python/master/sdk/formrecognizer/azure-ai-formrecognizer/tests/sample_forms/receipt/contoso-receipt.png";
    const poller = await client.beginRecognizeReceiptsFromUrl(receiptUrl, {
        onProgress: (state) => { console.log(`status: ${state.status}`); }
    });

    const receipts = await poller.pollUntilDone();

    if (!receipts || receipts.length <= 0) {
        throw new Error("Expecting at lease one receipt in analysis result");
    }

    const receipt = receipts[0];
    console.log("First receipt:");
    const receiptTypeField = receipt.fields["ReceiptType"];
    if (receiptTypeField.valueType === "string") {
        console.log(`  Receipt Type: '${receiptTypeField.value || "<missing>"}', with confidence of ${receiptTypeField.confidence}`);
    }
    const merchantNameField = receipt.fields["MerchantName"];
    if (merchantNameField.valueType === "string") {
        console.log(`  Merchant Name: '${merchantNameField.value || "<missing>"}', with confidence of ${merchantNameField.confidence}`);
    }
    const transactionDate = receipt.fields["TransactionDate"];
    if (transactionDate.valueType === "date") {
        console.log(`  Transaction Date: '${transactionDate.value || "<missing>"}', with confidence of ${transactionDate.confidence}`);
    }
    const itemsField = receipt.fields["Items"];
    if (itemsField.valueType === "array") {
        for (const itemField of itemsField.value || []) {
            if (itemField.valueType === "object") {
                const itemNameField = itemField.value["Name"];
                if (itemNameField.valueType === "string") {
                    console.log(`    Item Name: '${itemNameField.value || "<missing>"}', with confidence of ${itemNameField.confidence}`);
                }
            }
        }
    }
    const totalField = receipt.fields["Total"];
    if (totalField.valueType === "number") {
        console.log(`  Total: '${totalField.value || "<missing>"}', with confidence of ${totalField.confidence}`);
    }
}

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

Tip

Anda juga dapat menganalisis gambar tanda terima lokal dengan metode FormRecognizerClient, seperti beginRecognizeReceipts.

Output

status: notStarted
status: running
status: succeeded
First receipt:
  Receipt Type: 'Itemized', with confidence of 0.659
  Merchant Name: 'Contoso Contoso', with confidence of 0.516
  Transaction Date: 'Sun Jun 09 2019 17:00:00 GMT-0700 (Pacific Daylight Time)', with confidence of 0.985
    Item Name: '8GB RAM (Black)', with confidence of 0.916
    Item Name: 'SurfacePen', with confidence of 0.858
  Total: '1203.39', with confidence of 0.774

Menganalisis kartu nama

Bagian ini menunjukkan cara menganalisis dan mengekstrak bidang umum dari kartu nama berbahasa Inggris, menggunakan model yang sudah dilatih sebelumnya. Untuk informasi selengkapnya tentang analisis kartu bisnis, lihat Panduan konseptual kartu bisnis.

Untuk menganalisis kartu bisnis dari URL, gunakan metode beginRecognizeBusinessCardsFromURL.

async function recognizeBusinessCards() {
    bcUrl = "https://github.com/Azure-Samples/cognitive-services-REST-api-samples/curl/form-recognizer/businessCard.png";
    const poller = await client.beginRecognizeBusinessCardsFromUrl(bcUrl, {
        onProgress: (state) => {
            console.log(`status: ${state.status}`);
        }
    });

    const [businessCard] = await poller.pollUntilDone();

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

    const contactNames = businessCard.fields["ContactNames"].value;
    if (Array.isArray(contactNames)) {
        console.log("- Contact Names:");
        for (const contactName of contactNames) {
            if (contactName.valueType === "object") {
                const firstName = contactName.value?.["FirstName"].value ?? "<no first name>";
                const lastName = contactName.value?.["LastName"].value ?? "<no last name>";
                console.log(`  - ${firstName} ${lastName} (${contactName.confidence} confidence)`);
            }
        }
    }

    printSimpleArrayField(businessCard, "CompanyNames");
    printSimpleArrayField(businessCard, "Departments");
    printSimpleArrayField(businessCard, "JobTitles");
    printSimpleArrayField(businessCard, "Emails");
    printSimpleArrayField(businessCard, "Websites");
    printSimpleArrayField(businessCard, "Addresses");
    printSimpleArrayField(businessCard, "MobilePhones");
    printSimpleArrayField(businessCard, "Faxes");
    printSimpleArrayField(businessCard, "WorkPhones");
    printSimpleArrayField(businessCard, "OtherPhones");
}

// Helper function to print array field values. 
function printSimpleArrayField(businessCard, fieldName) {
    const fieldValues = businessCard.fields[fieldName]?.value;
    if (Array.isArray(fieldValues)) {
        console.log(`- ${fieldName}:`);
        for (const item of fieldValues) {
            console.log(`  - ${item.value ?? "<no value>"} (${item.confidence} confidence)`);
        }
    } else if (fieldValues === undefined) {
        console.log(`No ${fieldName} were found in the document.`);
    } else {
        console.error(
            `Error: expected field "${fieldName}" to be an Array, but it was a(n) ${businessCard.fields[fieldName].valueType}`
        );
    }
}

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

Tip

Anda juga dapat menganalisis gambar kartu nama lokal dengan metode FormRecognizerClient, seperti beginRecognizeReceipts.

Menganalisis faktur

Bagian ini menunjukkan cara menganalisis dan mengekstrak bidang umum dari faktur penjualan, menggunakan model yang sudah dilatih sebelumnya. Untuk mengetahui informasi selengkapnya tentang analisis faktur, lihat Panduan konseptual faktur.

Untuk menganalisis faktur dari URL, gunakan metode beginRecognizeInvoicesFromUrl.

async function recognizeInvoices() {
    invoiceUrl = "https://github.com/Azure-Samples/cognitive-services-REST-api-samples/curl/form-recognizer/invoice_sample.jpg";

    const poller = await client.beginRecognizeInvoicesFromUrl(invoiceUrl, {
        onProgress: (state) => {
            console.log(`status: ${state.status}`);
        }
    });

    const [invoice] = await poller.pollUntilDone();
    if (invoice === undefined) {
        throw new Error("Failed to extract data from at least one invoice.");
    }

    // Helper function to print fields.
    function fieldToString(field) {
        const {
            name,
            valueType,
            value,
            confidence
        } = field;
        return `${name} (${valueType}): '${value}' with confidence ${confidence}'`;
    }

    console.log("Invoice fields:");

    for (const [name, field] of Object.entries(invoice.fields)) {
        if (field.valueType !== "array" && field.valueType !== "object") {
            console.log(`- ${name} ${fieldToString(field)}`);
        }
    }

    let idx = 0;

    console.log("- Items:");

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

        const subFields = [
            "Description",
            "Quantity",
            "Unit",
            "UnitPrice",
            "ProductCode",
            "Date",
            "Tax",
            "Amount"
        ]
            .map((fieldName) => value[fieldName])
            .filter((field) => field !== undefined);

        console.log(
            [
                `  - Item #${idx}`,
                // Now we will convert those fields into strings to display
                ...subFields.map((field) => `    - ${fieldToString(field)}`)
            ].join("\n")
        );
    }
}

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

Tip

Anda juga dapat menganalisis gambar tanda terima lokal dengan metode FormRecognizerClient, seperti beginRecognizeInvoices.

Menganalisis dokumen ID

Bagian ini menunjukkan cara menganalisis dan mengekstrak informasi kunci dari dokumen identifikasi yang dikeluarkan pemerintah—paspor di seluruh dunia dan SIM AS—menggunakan model ID bawaan Form Recognizer. Untuk mengetahui informasi selengkapnya tentang analisis dokumen identitas, lihat panduan konseptual model identifikasi bawaan kami.

Untuk menganalisis dokumen ID dari URL, gunakan metode beginRecognizeIdDocumentsFromUrl.

async function recognizeIdDocuments() {
    idUrl = "https://github.com/Azure-Samples/cognitive-services-REST-api-samples/curl/form-recognizer/id-license.jpg";
    const poller = await client.beginRecognizeIdDocumentsFromUrl(idUrl, {
        onProgress: (state) => {
            console.log(`status: ${state.status}`);
        }
    });

    const [idDocument] = await poller.pollUntilDone();

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

    console.log("Document Type:", idDocument.formType);

    console.log("Identity Document Fields:");

    function printField(fieldName) {
        // Fields are extracted from the `fields` property of the document result
        const field = idDocument.fields[fieldName];
        console.log(
            `- ${fieldName} (${field?.valueType}): '${field?.value ?? "<missing>"}', with confidence ${field?.confidence
            }`
        );
    }

    printField("FirstName");
    printField("LastName");
    printField("DocumentNumber");
    printField("DateOfBirth");
    printField("DateOfExpiration");
    printField("Sex");
    printField("Address");
    printField("Country");
    printField("Region");
}

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

Melatih model kustom

Bagian ini menunjukkan cara melatih model dengan data Anda sendiri. Model terlatih dapat menampilkan data terstruktur yang menyertakan hubungan kunci/nilai dalam dokumen formulir asli. Setelah melatih model, Anda dapat menguji, melatih kembali, dan akhirnya menggunakannya untuk mengekstrak data secara andal dari lebih banyak formulir sesuai kebutuhan Anda.

Catatan

Anda juga dapat melatih model dengan antarmuka pengguna grafis (GUI) seperti alat Pelabelan Sampel Form Recognizer.

Melatih model tanpa label

Latih model kustom untuk menganalisis semua bidang dan nilai yang ditemukan dalam formulir kustom Anda tanpa memberi label dokumen pelatihan secara manual.

Fungsi berikut melatih model pada set dokumen tertentu dan mencetak status model ke konsol.

async function trainModel() {

    const containerSasUrl = "<SAS-URL-of-your-form-folder-in-blob-storage>";

    const poller = await trainingClient.beginTraining(containerSasUrl, false, {
        onProgress: (state) => { console.log(`training status: ${state.status}`); }
    });
    const model = await poller.pollUntilDone();

    if (!model) {
        throw new Error("Expecting valid training result!");
    }

    console.log(`Model ID: ${model.modelId}`);
    console.log(`Status: ${model.status}`);
    console.log(`Training started on: ${model.trainingStartedOn}`);
    console.log(`Training completed on: ${model.trainingCompletedOn}`);

    if (model.submodels) {
        for (const submodel of model.submodels) {
            // since the training data is unlabeled, we are unable to return the accuracy of this model
            console.log("We have recognized the following fields");
            for (const key in submodel.fields) {
                const field = submodel.fields[key];
                console.log(`The model found field '${field.name}'`);
            }
        }
    }
    // Training document information
    if (model.trainingDocuments) {
        for (const doc of model.trainingDocuments) {
            console.log(`Document name: ${doc.name}`);
            console.log(`Document status: ${doc.status}`);
            console.log(`Document page count: ${doc.pageCount}`);
            console.log(`Document errors: ${doc.errors}`);
        }
    }
}

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

Output

Berikut ini adalah output untuk model yang dilatih dengan data pelatihan yang tersedia dari JavaScript SDK. Contoh output ini telah dipotong agar mudah dibaca.

training status: creating
training status: ready
Model ID: 9d893595-1690-4cf2-a4b1-fbac0fb11909
Status: ready
Training started on: Thu Aug 20 2020 20:27:26 GMT-0700 (Pacific Daylight Time)
Training completed on: Thu Aug 20 2020 20:27:37 GMT-0700 (Pacific Daylight Time)
We have recognized the following fields
The model found field 'field-0'
The model found field 'field-1'
The model found field 'field-2'
The model found field 'field-3'
The model found field 'field-4'
The model found field 'field-5'
The model found field 'field-6'
The model found field 'field-7'
...
Document name: Form_1.jpg
Document status: succeeded
Document page count: 1
Document errors:
Document name: Form_2.jpg
Document status: succeeded
Document page count: 1
Document errors:
Document name: Form_3.jpg
Document status: succeeded
Document page count: 1
Document errors:
...

Melatih model dengan label

Anda juga dapat melatih model kustom dengan memberi label secara manual pada dokumen pelatihan. Pelatihan dengan label berdampak pada performa yang lebih baik dalam beberapa skenario. Untuk berlatih dengan label, Anda harus memiliki file informasi label khusus (\<filename\>.pdf.labels.json) di kontainer penyimpanan blob Anda bersama dengan dokumen pelatihan. Alat Pelabelan Sampel Form Recognizer menyediakan UI untuk membantu Anda membuat file label ini. Setelah mendapatkannya, Anda dapat memanggil metode beginTraining dengan parameter uselabels diatur ke true.

async function trainModelLabels() {

    const containerSasUrl = "<SAS-URL-of-your-form-folder-in-blob-storage>";

    const poller = await trainingClient.beginTraining(containerSasUrl, true, {
        onProgress: (state) => { console.log(`training status: ${state.status}`); }
    });
    const model = await poller.pollUntilDone();

    if (!model) {
        throw new Error("Expecting valid training result!");
    }

    console.log(`Model ID: ${model.modelId}`);
    console.log(`Status: ${model.status}`);
    console.log(`Training started on: ${model.trainingStartedOn}`);
    console.log(`Training completed on: ${model.trainingCompletedOn}`);

    if (model.submodels) {
        for (const submodel of model.submodels) {
            // since the training data is unlabeled, we are unable to return the accuracy of this model
            console.log("We have recognized the following fields");
            for (const key in submodel.fields) {
                const field = submodel.fields[key];
                console.log(`The model found field '${field.name}'`);
            }
        }
    }
    // Training document information
    if (model.trainingDocuments) {
        for (const doc of model.trainingDocuments) {
            console.log(`Document name: ${doc.name}`);
            console.log(`Document status: ${doc.status}`);
            console.log(`Document page count: ${doc.pageCount}`);
            console.log(`Document errors: ${doc.errors}`);
        }
    }
}

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

Output

Berikut ini adalah output untuk model yang dilatih dengan data pelatihan yang tersedia dari JavaScript SDK. Contoh output ini telah dipotong agar mudah dibaca.

training status: creating
training status: ready
Model ID: 789b1b37-4cc3-4e36-8665-9dde68618072
Status: ready
Training started on: Thu Aug 20 2020 20:30:37 GMT-0700 (Pacific Daylight Time)
Training completed on: Thu Aug 20 2020 20:30:43 GMT-0700 (Pacific Daylight Time)
We have recognized the following fields
The model found field 'CompanyAddress'
The model found field 'CompanyName'
The model found field 'CompanyPhoneNumber'
The model found field 'DatedAs'
...
Document name: Form_1.jpg
Document status: succeeded
Document page count: 1
Document errors: undefined
Document name: Form_2.jpg
Document status: succeeded
Document page count: 1
Document errors: undefined
Document name: Form_3.jpg
Document status: succeeded
Document page count: 1
Document errors: undefined
...

Menganalisis formulir dengan model kustom

Bagian ini menunjukkan cara mengekstrak informasi kunci/nilai dan konten lainnya dari jenis templat kustom Anda, menggunakan model yang Anda latih dengan formulir Anda sendiri.

Penting

Untuk menerapkan skenario ini, Anda harus sudah melatih model sehingga dapat meneruskan ID model ke metode di bawah ini. Lihat bagianMelatih model.

Anda akan menggunakan metode beginRecognizeCustomFormsFromUrl. Nilai yang ditampilkan adalah kumpulan objek RecognizedForm: satu objek untuk setiap halaman dalam dokumen yang dikirimkan.

async function recognizeCustom() {
    // Model ID from when you trained your model.
    const modelId = "<modelId>";
    const formUrl = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/simple-invoice.png";

    const poller = await client.beginRecognizeCustomForms(modelId, formUrl, {
        onProgress: (state) => { console.log(`status: ${state.status}`); }
    });
    const forms = await poller.pollUntilDone();

    console.log("Forms:");
    for (const form of forms || []) {
        console.log(`${form.formType}, page range: ${form.pageRange}`);
        console.log("Pages:");
        for (const page of form.pages || []) {
            console.log(`Page number: ${page.pageNumber}`);
            console.log("Tables");
            for (const table of page.tables || []) {
                for (const cell of table.cells) {
                    console.log(`cell (${cell.rowIndex},${cell.columnIndex}) ${cell.text}`);
                }
            }
        }

        console.log("Fields:");
        for (const fieldName in form.fields) {
            // each field is of type FormField
            const field = form.fields[fieldName];
            console.log(
                `Field ${fieldName} has value '${field.value}' with a confidence score of ${field.confidence}`
            );
        }
    }
}

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

Tip

Anda juga dapat menganalisis file lokal dengan metode FormRecognizerClient, seperti beginRecognizeCustomForms.

Output

status: notStarted
status: succeeded
Forms:
custom:form, page range: [object Object]
Pages:
Page number: 1
Tables
cell (0,0) Invoice Number
cell (0,1) Invoice Date
cell (0,2) Invoice Due Date
cell (0,3) Charges
cell (0,5) VAT ID
cell (1,0) 34278587
cell (1,1) 6/18/2017
cell (1,2) 6/24/2017
cell (1,3) $56,651.49
cell (1,5) PT
Fields:
Field Merchant has value 'Invoice For:' with a confidence score of 0.116
Field CompanyPhoneNumber has value '$56,651.49' with a confidence score of 0.249
Field VendorName has value 'Charges' with a confidence score of 0.145
Field CompanyAddress has value '1 Redmond way Suite 6000 Redmond, WA' with a confidence score of 0.258
Field CompanyName has value 'PT' with a confidence score of 0.245
Field Website has value '99243' with a confidence score of 0.114
Field DatedAs has value 'undefined' with a confidence score of undefined
Field Email has value 'undefined' with a confidence score of undefined
Field PhoneNumber has value 'undefined' with a confidence score of undefined
Field PurchaseOrderNumber has value 'undefined' with a confidence score of undefined
Field Quantity has value 'undefined' with a confidence score of undefined
Field Signature has value 'undefined' with a confidence score of undefined
Field Subtotal has value 'undefined' with a confidence score of undefined
Field Tax has value 'undefined' with a confidence score of undefined
Field Total has value 'undefined' with a confidence score of undefined

Mengelola model kustom

Bagian ini menunjukkan cara mengelola model kustom yang disimpan di akun Anda. Kode berikut melakukan semua tugas pengelolaan model dalam satu fungsi, sebagai contoh.

Mendapatkan jumlah model

Blok kode berikut mendapatkan jumlah model yang saat ini ada di akun Anda.

async function countModels() {
    // First, we see how many custom models we have, and what our limit is
    const accountProperties = await trainingClient.getAccountProperties();
    console.log(
        `Our account has ${accountProperties.customModelCount} custom models, and we can have at most ${accountProperties.customModelLimit} custom models`
    );
}
countModels().catch((err) => {
    console.error("The sample encountered an error:", err);
});

Mendapatkan daftar model pada akun

Blok kode berikut ini menyediakan daftar lengkap dari model yang tersedia di akun Anda termasuk informasi tentang kapan model tersebut dibuat dan statusnya saat ini.

async function listModels() {

    // returns an async iteratable iterator that supports paging
    const result = trainingClient.listCustomModels();
    let i = 0;
    for await (const modelInfo of result) {
        console.log(`model ${i++}:`);
        console.log(modelInfo);
    }
}

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

Output

model 0:
{
  modelId: '453cc2e6-e3eb-4e9f-aab6-e1ac7b87e09e',
  status: 'invalid',
  trainingStartedOn: 2020-08-20T22:28:52.000Z,
  trainingCompletedOn: 2020-08-20T22:28:53.000Z
}
model 1:
{
  modelId: '628739de-779c-473d-8214-d35c72d3d4f7',
  status: 'ready',
  trainingStartedOn: 2020-08-20T23:16:51.000Z,
  trainingCompletedOn: 2020-08-20T23:16:59.000Z
}
model 2:
{
  modelId: '789b1b37-4cc3-4e36-8665-9dde68618072',
  status: 'ready',
  trainingStartedOn: 2020-08-21T03:30:37.000Z,
  trainingCompletedOn: 2020-08-21T03:30:43.000Z
}
model 3:
{
  modelId: '9d893595-1690-4cf2-a4b1-fbac0fb11909',
  status: 'ready',
  trainingStartedOn: 2020-08-21T03:27:26.000Z,
  trainingCompletedOn: 2020-08-21T03:27:37.000Z
}

Mendapatkan daftar ID model menurut halaman

Blok kode ini menyediakan daftar model dan model ID yang di-paginasi.

async function listModelsByPage() {
    // using `byPage()`
    i = 1;
    for await (const response of trainingClient.listCustomModels().byPage()) {
        for (const modelInfo of response.modelList) {
            console.log(`model ${i++}: ${modelInfo.modelId}`);
        }
    }
}
listModelsByPage().catch((err) => {
    console.error("The sample encountered an error:", err);
});

Output

model 1: 453cc2e6-e3eb-4e9f-aab6-e1ac7b87e09e
model 2: 628739de-779c-473d-8214-d35c72d3d4f7
model 3: 789b1b37-4cc3-4e36-8665-9dde68618072

Mendapatkan model menurut ID

Fungsi berikut mengambil ID model dan mendapatkan objek model yang cocok. Fungsi ini tidak dipanggil secara default.

async function getModel(modelId) {
    // Now we'll get the first custom model in the paged list
    const model = await client.getCustomModel(modelId);
    console.log("--- First Custom Model ---");
    console.log(`Model Id: ${model.modelId}`);
    console.log(`Status: ${model.status}`);
    console.log("Documents used in training:");
    for (const doc of model.trainingDocuments || []) {
        console.log(`- ${doc.name}`);
    }
}

Menghapus model dari akun sumber daya

Anda juga dapat menghapus model dari akun dengan melihat ID-nya. Fungsi ini menghapus model dengan ID yang diberikan. Fungsi ini tidak dipanggil secara default.

async function deleteModel(modelId) {
    await client.deleteModel(modelId);
    try {
        const deleted = await client.getCustomModel(modelId);
        console.log(deleted);
    } catch (err) {
        // Expected
        console.log(`Model with id ${modelId} has been deleted`);
    }
}

Output

Model with id 789b1b37-4cc3-4e36-8665-9dde68618072 has been deleted

Menjalankan aplikasi

Jalankan aplikasi dengan perintah node dalam file proyek Anda.

node index.js

Membersihkan sumber daya

Jika ingin membersihkan dan menghapus langganan Cognitive Services, Anda dapat menghapus sumber daya atau grup sumber daya. Menghapus grup sumber daya juga menghapus sumber daya apa pun yang terkait dengannya.

Pemecahan Masalah

Aktifkan log

Anda dapat mengatur variabel lingkungan berikut untuk melihat log debug saat menggunakan pustaka ini.

export DEBUG=azure*

Untuk petunjuk lebih detail mengenai cara mengaktifkan log, lihat dokumen paket @azure/logger.

Langkah berikutnya

Untuk proyek ini, Anda menggunakan pustaka klien JavaScript Form Recognizer untuk melatih model dan menganalisis formulir dengan cara yang berbeda. Selanjutnya, pelajari tips untuk membuat himpunan data pelatihan yang lebih baik dan membuat model yang lebih akurat.

Lihat juga

Penting

  • Proyek ini menargetkan Form Recognizer REST API versi 2.1.

Dokumentasi referensi | Kode sumber pustaka | Paket (PyPi) | Sampel

Prasyarat

  • Langganan Azure - Membuat langganan gratis
  • Python 3.x
    • Penginstalan Python Anda harus menyertakan pip. Anda dapat memeriksa apakah Anda telah memasang pip dengan menjalankan pip --version pada baris perintah. Dapatkan pip dengan memasang versi terbaru Python.
  • Blob Azure Storage yang berisi set data pelatihan. Lihat Membangun himpunan data pelatihan untuk model kustom untuk tips dan opsi dalam menyusun himpunan data pelatihan Anda. Anda dapat menggunakan file dalam folder Latihan dari himpunan data sampel (unduh dan ekstrak sample_data.zip).
  • Setelah Anda berlangganan Azure, buat sumber daya Form Recognizer di portal Microsoft Azure untuk mendapatkan kunci dan titik akhir Anda. Setelah menyebar, pilih Buka sumber daya.
    • Anda akan memerlukan kunci dan titik akhir sumber daya yang Anda buat untuk menghubungkan aplikasi ke API Form Recognizer. Tempelkan kunci dan titik akhir ke dalam kode di bawah ini.
    • Anda dapat menggunakan tingkat harga gratis (F0) untuk mencoba layanan, lalu meningkatkannya ke tingkat berbayar untuk produksi.

Tip

Buat sumber daya Cognitive Services jika Anda berencana untuk mengakses beberapa layanan kognitif di bawah satu titik akhir/kunci. Hanya untuk akses Form Recognizer, buat sumber daya Form Recognizer. Harap perhatikan bahwa Anda memerlukan sumber daya layanan tunggal jika ingin menggunakan Autentikasi Azure Active Directory.

Persiapan

Memasang pustaka klien

Setelah memasang Python, Anda dapat memasang versi terbaru dari pustaka klien Azure Form Recognizer dengan:

pip install azure-ai-formrecognizer 

Membuat aplikasi Python baru

Buat aplikasi Python baru bernama form-recognizer.py di editor atau IDE pilihan Anda. Kemudian impor pustaka berikut.

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

Buat variabel untuk titik akhir dan kunci Azure dari sumber daya Anda.

endpoint = "PASTE_YOUR_FORM_RECOGNIZER_ENDPOINT_HERE"
key = "PASTE_YOUR_FORM_RECOGNIZER_SUBSCRIPTION_KEY_HERE"

Model objek

Dengan Azure Form Recognizer, Anda dapat membuat dua jenis klien yang berbeda. Yang pertama, form_recognizer_client digunakan untuk mengkueri layanan guna mengenali bidang isian borang dan konten. Yang kedua, form_training_client digunakan untuk membuat dan mengelola model kustom agar lebih dikenali.

FormRecognizerClient

form_recognizer_client menyediakan operasi berikut:

  • Mengenali bidang formulir dan konten menggunakan model kustom yang dilatih untuk menganalisis formulir kustom Anda.
  • Mengenali isi formulir, termasuk tabel, garis, dan kata, tanpa perlu melatih model.
  • Mengenali bidang umum dari tanda terima, menggunakan model tanda terima yang telah dilatih sebelumnya pada layanan Form Recognizer.

FormTrainingClient

form_training_client menyediakan operasi untuk:

Catatan

Model juga dapat dilatih menggunakan antarmuka pengguna grafis seperti Alat Pelabelan Azure Form Recognizer.

Autentikasi klien

Di sini, Anda akan mengautentikasi dua objek klien menggunakan variabel langganan yang ditentukan di atas. Anda akan menggunakan objek AzureKeyCredential, sehingga jika diperlukan, Anda dapat memperbarui kunci tanpa membuat objek klien baru.

form_recognizer_client = FormRecognizerClient(endpoint, AzureKeyCredential(key))
form_training_client = FormTrainingClient(endpoint, AzureKeyCredential(key))

Menddapatkan aset untuk pengujian

Anda harus menambahkan referensi ke URL untuk data pelatihan dan pengujian.

  • Untuk mengambil URL SAS untuk data pelatihan model kustom Anda, buka sumber daya penyimpanan di portal Microsoft Azure dan pilih tab Penjelajah Penyimpanan. Buka kontainer Anda, klik kanan, lalu pilih Dapatkan tanda tangan akses bersama. Sangat penting untuk mendapatkan SAS untuk kontainer Anda, bukan untuk akun penyimpanan itu sendiri. Pastikan izin Baca, Tulis, Hapus, dan Cantumkan dicentang, lalu klik Buat. Kemudian salin nilai di bagian URL ke lokasi sementara. Ini harus memiliki format: https://<storage account>.blob.core.windows.net/<container name>?<SAS value>.

    Pengambilan URL SAS

  • Gunakan formulir sampel dan gambar tanda terima yang disertakan dalam sampel di bawah ini (juga tersedia di GitHub atau Anda dapat menggunakan langkah-langkah di atas untuk mendapatkan URL SAS masing-masing dokumen dalam penyimpanan blob.

Catatan

Cuplikan kode dalam proyek ini menggunakan formulir jarak jauh yang diakses oleh URL. Jika Anda ingin memproses dokumen formulir lokal, lihat metode terkait di dokumentasi referensi dan sampel.

Menganalisis tata letak

Anda dapat menggunakan Form Recognizer untuk menganalisis tabel, garis, dan kata-kata dalam dokumen, tanpa perlu melatih model. Untuk informasi selengkapnya tentang ekstraksi tata letak, lihat Panduan konseptual tata letak.

Untuk menganalisis konten file pada URL yang diberikan, gunakan metode begin_recognize_content_from_url. Nilai yang ditampilkan adalah kumpulan objek FormPage: satu untuk setiap halaman dalam dokumen yang dikirimkan. Kode berikut mengulangi melalui objek-objek ini dan mencetak pasangan kunci/nilai yang diekstrak dan data tabel.

formUrl = "https://raw.githubusercontent.com/Azure/azure-sdk-for-python/master/sdk/formrecognizer/azure-ai-formrecognizer/tests/sample_forms/forms/Form_1.jpg"

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

table = page[0].tables[0] # page 1, table 1
print("Table found on page {}:".format(table.page_number))
for cell in table.cells:
    print("Cell text: {}".format(cell.text))
    print("Location: {}".format(cell.bounding_box))
    print("Confidence score: {}\n".format(cell.confidence))

Tip

Anda juga bisa mendapatkan konten dari gambar lokal dengan metode FormRecognizerClient, seperti begin_recognize_content.

Output

Table found on page 1:
Cell text: Invoice Number
Location: [Point(x=0.5075, y=2.8088), Point(x=1.9061, y=2.8088), Point(x=1.9061, y=3.3219), Point(x=0.5075, y=3.3219)]
Confidence score: 1.0

Cell text: Invoice Date
Location: [Point(x=1.9061, y=2.8088), Point(x=3.3074, y=2.8088), Point(x=3.3074, y=3.3219), Point(x=1.9061, y=3.3219)]
Confidence score: 1.0

Cell text: Invoice Due Date
Location: [Point(x=3.3074, y=2.8088), Point(x=4.7074, y=2.8088), Point(x=4.7074, y=3.3219), Point(x=3.3074, y=3.3219)]
Confidence score: 1.0

Cell text: Charges
Location: [Point(x=4.7074, y=2.8088), Point(x=5.386, y=2.8088), Point(x=5.386, y=3.3219), Point(x=4.7074, y=3.3219)]
Confidence score: 1.0
...

Menganalisis tanda terima

Bagian ini menunjukkan cara menganalisis dan mengekstrak bidang umum dari tanda terima US, menggunakan model tanda terima yang telah dilatih sebelumnya. Untuk informasi selengkapnya tentang analisis tanda terima, lihat Panduan konseptual tanda terima. Untuk menganalisis tanda terima dari URL, gunakan metode begin_recognize_receipts_from_url.

receiptUrl = "https://raw.githubusercontent.com/Azure/azure-sdk-for-python/master/sdk/formrecognizer/azure-ai-formrecognizer/tests/sample_forms/receipt/contoso-receipt.png"

poller = form_recognizer_client.begin_recognize_receipts_from_url(receiptUrl)
result = poller.result()

for receipt in result:
    for name, field in receipt.fields.items():
        if name == "Items":
            print("Receipt Items:")
            for idx, items in enumerate(field.value):
                print("...Item #{}".format(idx + 1))
                for item_name, item in items.value.items():
                    print("......{}: {} has confidence {}".format(item_name, item.value, item.confidence))
        else:
            print("{}: {} has confidence {}".format(name, field.value, field.confidence))

Tip

Anda juga dapat menganalisis gambar tanda terima lokal dengan metode FormRecognizerClient, seperti begin_recognize_receipts.

Output

ReceiptType: Itemized has confidence 0.659
MerchantName: Contoso Contoso has confidence 0.516
MerchantAddress: 123 Main Street Redmond, WA 98052 has confidence 0.986
MerchantPhoneNumber: None has confidence 0.99
TransactionDate: 2019-06-10 has confidence 0.985
TransactionTime: 13:59:00 has confidence 0.968
Receipt Items:
...Item #1
......Name: 8GB RAM (Black) has confidence 0.916
......TotalPrice: 999.0 has confidence 0.559
...Item #2
......Quantity: None has confidence 0.858
......Name: SurfacePen has confidence 0.858
......TotalPrice: 99.99 has confidence 0.386
Subtotal: 1098.99 has confidence 0.964
Tax: 104.4 has confidence 0.713
Total: 1203.39 has confidence 0.774

Menganalisis kartu bisnis

Bagian ini menunjukkan cara menganalisis dan mengekstrak bidang umum dari kartu bisnis berbahasa Inggris menggunakan model yang dilatih sebelumnya. Untuk mengetahui informasi selengkapnya tentang analisis kartu bisnis, lihat Panduan konseptual kartu bisnis.

Untuk menganalisis kartu bisnis dari URL, gunakan metode begin_recognize_business_cards_from_url.

bcUrl = "https://raw.githubusercontent.com/Azure/azure-sdk-for-python/master/sdk/formrecognizer/azure-ai-formrecognizer/samples/sample_forms/business_cards/business-card-english.jpg"

poller = form_recognizer_client.begin_recognize_business_cards_from_url(bcUrl)
business_cards = poller.result()

for idx, business_card in enumerate(business_cards):
    print("--------Recognizing business card #{}--------".format(idx+1))
    contact_names = business_card.fields.get("ContactNames")
    if contact_names:
        for contact_name in contact_names.value:
            print("Contact First Name: {} has confidence: {}".format(
                contact_name.value["FirstName"].value, contact_name.value["FirstName"].confidence
            ))
            print("Contact Last Name: {} has confidence: {}".format(
                contact_name.value["LastName"].value, contact_name.value["LastName"].confidence
            ))
    company_names = business_card.fields.get("CompanyNames")
    if company_names:
        for company_name in company_names.value:
            print("Company Name: {} has confidence: {}".format(company_name.value, company_name.confidence))
    departments = business_card.fields.get("Departments")
    if departments:
        for department in departments.value:
            print("Department: {} has confidence: {}".format(department.value, department.confidence))
    job_titles = business_card.fields.get("JobTitles")
    if job_titles:
        for job_title in job_titles.value:
            print("Job Title: {} has confidence: {}".format(job_title.value, job_title.confidence))
    emails = business_card.fields.get("Emails")
    if emails:
        for email in emails.value:
            print("Email: {} has confidence: {}".format(email.value, email.confidence))
    websites = business_card.fields.get("Websites")
    if websites:
        for website in websites.value:
            print("Website: {} has confidence: {}".format(website.value, website.confidence))
    addresses = business_card.fields.get("Addresses")
    if addresses:
        for address in addresses.value:
            print("Address: {} has confidence: {}".format(address.value, address.confidence))
    mobile_phones = business_card.fields.get("MobilePhones")
    if mobile_phones:
        for phone in mobile_phones.value:
            print("Mobile phone number: {} has confidence: {}".format(phone.value, phone.confidence))
    faxes = business_card.fields.get("Faxes")
    if faxes:
        for fax in faxes.value:
            print("Fax number: {} has confidence: {}".format(fax.value, fax.confidence))
    work_phones = business_card.fields.get("WorkPhones")
    if work_phones:
        for work_phone in work_phones.value:
            print("Work phone number: {} has confidence: {}".format(work_phone.value, work_phone.confidence))
    other_phones = business_card.fields.get("OtherPhones")
    if other_phones:
        for other_phone in other_phones.value:
            print("Other phone number: {} has confidence: {}".format(other_phone.value, other_phone.confidence))

Tip

Anda juga dapat menganalisis gambar kartu nama lokal dengan metode FormRecognizerClient, seperti begin_recognize_business_cards.

Menganalisis faktur

Bagian ini menunjukkan cara menganalisis dan mengekstrak bidang umum dari faktur penjualan, menggunakan model yang sudah dilatih sebelumnya. Untuk mengetahui informasi selengkapnya tentang analisis faktur, lihat Panduan konseptual faktur.

Untuk menganalisis faktur dari URL, gunakan metode begin_recognize_invoices_from_url.

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

poller = form_recognizer_client.begin_recognize_invoices_from_url(invoiceUrl)
invoices = poller.result()

for idx, invoice in enumerate(invoices):
    print("--------Recognizing invoice #{}--------".format(idx+1))
    vendor_name = invoice.fields.get("VendorName")
    if vendor_name:
        print("Vendor Name: {} has confidence: {}".format(vendor_name.value, vendor_name.confidence))
    vendor_address = invoice.fields.get("VendorAddress")
    if vendor_address:
        print("Vendor Address: {} has confidence: {}".format(vendor_address.value, vendor_address.confidence))
    customer_name = invoice.fields.get("CustomerName")
    if customer_name:
        print("Customer Name: {} has confidence: {}".format(customer_name.value, customer_name.confidence))
    customer_address = invoice.fields.get("CustomerAddress")
    if customer_address:
        print("Customer Address: {} has confidence: {}".format(customer_address.value, customer_address.confidence))
    customer_address_recipient = invoice.fields.get("CustomerAddressRecipient")
    if customer_address_recipient:
        print("Customer Address Recipient: {} has confidence: {}".format(customer_address_recipient.value, customer_address_recipient.confidence))
    invoice_id = invoice.fields.get("InvoiceId")
    if invoice_id:
        print("Invoice Id: {} has confidence: {}".format(invoice_id.value, invoice_id.confidence))
    invoice_date = invoice.fields.get("InvoiceDate")
    if invoice_date:
        print("Invoice Date: {} has confidence: {}".format(invoice_date.value, invoice_date.confidence))
    invoice_total = invoice.fields.get("InvoiceTotal")
    if invoice_total:
        print("Invoice Total: {} has confidence: {}".format(invoice_total.value, invoice_total.confidence))
    due_date = invoice.fields.get("DueDate")
    if due_date:
        print("Due Date: {} has confidence: {}".format(due_date.value, due_date.confidence))

Tip

Anda juga dapat menganalisis gambar tagihan lokal dengan metode FormRecognizerClient, seperti begin_recognize_invoices.

Menganalisis dokumen ID

Bagian ini menunjukkan cara menganalisis dan mengekstrak informasi kunci dari dokumen identifikasi yang dikeluarkan pemerintah—paspor di seluruh dunia dan SIM AS—menggunakan model ID bawaan Form Recognizer. Untuk mengetahui informasi selengkapnya tentang analisis dokumen identitas, lihat panduan konseptual model identifikasi bawaan kami.

Untuk menganalisis dokumen ID dari URL, gunakan metode begin_recognize_id_documents_from_url.

idURL = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-REST-api-samples/master/curl/form-recognizer/id-license.jpg"

for idx, id_document in enumerate(id_documents):
    print("--------Recognizing ID document #{}--------".format(idx+1))
    first_name = id_document.fields.get("FirstName")
    if first_name:
        print("First Name: {} has confidence: {}".format(first_name.value, first_name.confidence))
    last_name = id_document.fields.get("LastName")
    if last_name:
        print("Last Name: {} has confidence: {}".format(last_name.value, last_name.confidence))
    document_number = id_document.fields.get("DocumentNumber")
    if document_number:
        print("Document Number: {} has confidence: {}".format(document_number.value, document_number.confidence))
    dob = id_document.fields.get("DateOfBirth")
    if dob:
        print("Date of Birth: {} has confidence: {}".format(dob.value, dob.confidence))
    doe = id_document.fields.get("DateOfExpiration")
    if doe:
        print("Date of Expiration: {} has confidence: {}".format(doe.value, doe.confidence))
    sex = id_document.fields.get("Sex")
    if sex:
        print("Sex: {} has confidence: {}".format(sex.value, sex.confidence))
    address = id_document.fields.get("Address")
    if address:
        print("Address: {} has confidence: {}".format(address.value, address.confidence))
    country_region = id_document.fields.get("CountryRegion")
    if country_region:
        print("Country/Region: {} has confidence: {}".format(country_region.value, country_region.confidence))
    region = id_document.fields.get("Region")
    if region:
        print("Region: {} has confidence: {}".format(region.value, region.confidence))

Tip

Anda juga dapat menganalisis gambar dokumen ID dengan metode FormRecognizerClient, seperti begin_recognize_identity_documents .

Melatih model kustom

Bagian ini menunjukkan cara melatih model dengan data Anda sendiri. Model terlatih dapat menampilkan data terstruktur yang menyertakan hubungan kunci/nilai dalam dokumen formulir asli. Setelah melatih model, Anda dapat menguji, melatih kembali, dan akhirnya menggunakannya untuk mengekstrak data secara andal dari lebih banyak formulir sesuai kebutuhan Anda.

Catatan

Anda juga dapat melatih model dengan antarmuka pengguna grafis seperti alat Pelabelan Sampel Form Recognizer.

Melatih model tanpa label

Latih model kustom untuk menganalisis semua bidang dan nilai yang ditemukan di formulir kustom Anda tanpa memberi label secara manual pada dokumen pelatihan.

Kode berikut menggunakan klien pelatihan dengan fungsi begin_training untuk melatih model pada set dokumen yang diberikan. Objek CustomFormModel yang dikembalikan berisi informasi tentang jenis formulir yang dapat dianalisis model dan bidang yang dapat diekstrak dari setiap jenis formulir. Blok kode berikut mencetak informasi ini ke konsol.

# To train a model you need an Azure Storage account.
# Use the SAS URL to access your training files.
trainingDataUrl = "PASTE_YOUR_SAS_URL_OF_YOUR_FORM_FOLDER_IN_BLOB_STORAGE_HERE"

poller = form_training_client.begin_training(trainingDataUrl, use_training_labels=False)
model = poller.result()

print("Model ID: {}".format(model.model_id))
print("Status: {}".format(model.status))
print("Training started on: {}".format(model.training_started_on))
print("Training completed on: {}".format(model.training_completed_on))

print("\nRecognized fields:")
for submodel in model.submodels:
    print(
        "The submodel with form type '{}' has recognized the following fields: {}".format(
            submodel.form_type,
            ", ".join(
                [
                    field.label if field.label else name
                    for name, field in submodel.fields.items()
                ]
            ),
        )
    )

# Training result information
for doc in model.training_documents:
    print("Document name: {}".format(doc.name))
    print("Document status: {}".format(doc.status))
    print("Document page count: {}".format(doc.page_count))
    print("Document errors: {}".format(doc.errors))

Output

Berikut adalah output untuk model yang dilatih dengan data pelatihan yang tersedia dari Python SDK.

Model ID: 628739de-779c-473d-8214-d35c72d3d4f7
Status: ready
Training started on: 2020-08-20 23:16:51+00:00
Training completed on: 2020-08-20 23:16:59+00:00

Recognized fields:
The submodel with form type 'form-0' has recognized the following fields: Additional Notes:, Address:, Company Name:, Company Phone:, Dated As:, Details, Email:, Hero Limited, Name:, Phone:, Purchase Order, Purchase Order #:, Quantity, SUBTOTAL, Seattle, WA 93849 Phone:, Shipped From, Shipped To, TAX, TOTAL, Total, Unit Price, Vendor Name:, Website:
Document name: Form_1.jpg
Document status: succeeded
Document page count: 1
Document errors: []
Document name: Form_2.jpg
Document status: succeeded
Document page count: 1
Document errors: []
Document name: Form_3.jpg
Document status: succeeded
Document page count: 1
Document errors: []
Document name: Form_4.jpg
Document status: succeeded
Document page count: 1
Document errors: []
Document name: Form_5.jpg
Document status: succeeded
Document page count: 1
Document errors: []

Melatih model dengan label

Anda juga dapat melatih model kustom dengan memberi label secara manual pada dokumen pelatihan. Pelatihan dengan label menghasilkan performa yang lebih baik dalam beberapa skenario. CustomFormModel yang ditampilkan menunjukkan bidang yang dapat diekstrak model, bersama dengan perkiraan akurasinya di setiap bidang. Blok kode berikut mencetak informasi ini ke konsol.

Penting

Untuk melatih dengan label, Anda harus memiliki file informasi label khusus (\<filename\>.pdf.labels.json) di kontainer penyimpanan blob bersamaan dengan dokumen pelatihan. Alat Pelabelan Sampel Form Recognizer menyediakan UI untuk membantu Anda membuat file label ini. Setelah memiliki alat, Anda dapat memanggil fungsi begin_training dengan parameter use_training_labels yang diatur ke true.

# To train a model you need an Azure Storage account.
# Use the SAS URL to access your training files.
trainingDataUrl = "PASTE_YOUR_SAS_URL_OF_YOUR_FORM_FOLDER_IN_BLOB_STORAGE_HERE"

poller = form_training_client.begin_training(trainingDataUrl, use_training_labels=True)
model = poller.result()
trained_model_id = model.model_id

print("Model ID: {}".format(trained_model_id))
print("Status: {}".format(model.status))
print("Training started on: {}".format(model.training_started_on))
print("Training completed on: {}".format(model.training_completed_on))

print("\nRecognized fields:")
for submodel in model.submodels:
    print(
        "The submodel with form type '{}' has recognized the following fields: {}".format(
            submodel.form_type,
            ", ".join(
                [
                    field.label if field.label else name
                    for name, field in submodel.fields.items()
                ]
            ),
        )
    )

# Training result information
for doc in model.training_documents:
    print("Document name: {}".format(doc.name))
    print("Document status: {}".format(doc.status))
    print("Document page count: {}".format(doc.page_count))
    print("Document errors: {}".format(doc.errors))

Output

Berikut adalah output untuk model yang dilatih dengan data pelatihan yang tersedia dari Python SDK.

Model ID: ae636292-0b14-4e26-81a7-a0bfcbaf7c91

Status: ready
Training started on: 2020-08-20 23:20:56+00:00
Training completed on: 2020-08-20 23:20:57+00:00

Recognized fields:
The submodel with form type 'form-ae636292-0b14-4e26-81a7-a0bfcbaf7c91' has recognized the following fields: CompanyAddress, CompanyName, CompanyPhoneNumber, DatedAs, Email, Merchant, PhoneNumber, PurchaseOrderNumber, Quantity, Signature, Subtotal, Tax, Total, VendorName, Website
Document name: Form_1.jpg
Document status: succeeded
Document page count: 1
Document errors: []
Document name: Form_2.jpg
Document status: succeeded
Document page count: 1
Document errors: []
Document name: Form_3.jpg
Document status: succeeded
Document page count: 1
Document errors: []
Document name: Form_4.jpg
Document status: succeeded
Document page count: 1
Document errors: []
Document name: Form_5.jpg
Document status: succeeded
Document page count: 1
Document errors: []

Menganalisis formulir dengan model kustom

Bagian ini menunjukkan cara mengekstrak informasi kunci/nilai dan konten lainnya dari jenis templat kustom Anda, menggunakan model yang Anda latih dengan formulir Anda sendiri.

Penting

Untuk menerapkan skenario ini, Anda harus sudah melatih model sehingga dapat meneruskan ID model ke metode di bawah ini. Lihat bagianMelatih model.

Anda akan menggunakan metode begin_recognize_custom_forms_from_url. Nilai yang ditampilkan adalah kumpulan objek RecognizedForm: satu untuk setiap halaman dalam dokumen yang dikirimkan. Kode berikut mencetak hasil analisis ke konsol. Kode mencetak setiap bidang yang dikenali dan nilai yang sesuai, bersama dengan skor keyakinan.


poller = form_recognizer_client.begin_recognize_custom_forms_from_url(
    model_id=trained_model_id, form_url=formUrl)
result = poller.result()

for recognized_form in result:
    print("Form type: {}".format(recognized_form.form_type))
    for name, field in recognized_form.fields.items():
        print("Field '{}' has label '{}' with value '{}' and a confidence score of {}".format(
            name,
            field.label_data.text if field.label_data else name,
            field.value,
            field.confidence
        ))

Tip

Anda juga dapat menganalisis gambar lokal. Lihat metode FormRecognizerClient, seperti begin_recognize_custom_forms. Atau, lihat kode sampel di GitHub untuk skenario yang melibatkan gambar lokal.

Output

Model dari contoh sebelumnya, membuat output berikut:

Form type: form-ae636292-0b14-4e26-81a7-a0bfcbaf7c91
Field 'Merchant' has label 'Merchant' with value 'Invoice For:' and a confidence score of 0.116
Field 'CompanyAddress' has label 'CompanyAddress' with value '1 Redmond way Suite 6000 Redmond, WA' and a confidence score of 0.258
Field 'Website' has label 'Website' with value '99243' and a confidence score of 0.114
Field 'VendorName' has label 'VendorName' with value 'Charges' and a confidence score of 0.145
Field 'CompanyPhoneNumber' has label 'CompanyPhoneNumber' with value '$56,651.49' and a confidence score of 0.249
Field 'CompanyName' has label 'CompanyName' with value 'PT' and a confidence score of 0.245
Field 'DatedAs' has label 'DatedAs' with value 'None' and a confidence score of None
Field 'Email' has label 'Email' with value 'None' and a confidence score of None
Field 'PhoneNumber' has label 'PhoneNumber' with value 'None' and a confidence score of None
Field 'PurchaseOrderNumber' has label 'PurchaseOrderNumber' with value 'None' and a confidence score of None
Field 'Quantity' has label 'Quantity' with value 'None' and a confidence score of None
Field 'Signature' has label 'Signature' with value 'None' and a confidence score of None
Field 'Subtotal' has label 'Subtotal' with value 'None' and a confidence score of None
Field 'Tax' has label 'Tax' with value 'None' and a confidence score of None
Field 'Total' has label 'Total' with value 'None' and a confidence score of None

Mengelola model kustom

Bagian ini menunjukkan cara mengelola model kustom yang disimpan di akun Anda.

Memeriksa jumlah model di akun sumber daya FormRecognizer

Blok kode berikut memeriksa banyaknya model yang Anda simpan di akun Form Recognizer dan membandingkannya dengan batas akun.

account_properties = form_training_client.get_account_properties()
print("Our account has {} custom models, and we can have at most {} custom models".format(
    account_properties.custom_model_count, account_properties.custom_model_limit
))

Output

Our account has 5 custom models, and we can have at most 5000 custom models

Mencantumkan model yang saat ini disimpan di akun sumber daya

Kode berikut memblokir model saat ini di akun Anda dan mencetak detailnya ke konsol. Blok kode juga menyimpan referensi ke model pertama.

# Next, we get a paged list of all of our custom models
custom_models = form_training_client.list_custom_models()

print("We have models with the following ids:")

# Let's pull out the first model
first_model = next(custom_models)
print(first_model.model_id)
for model in custom_models:
    print(model.model_id)

Output

Berikut adalah contoh output untuk akun pengujian.

We have models with the following ids:
453cc2e6-e3eb-4e9f-aab6-e1ac7b87e09e
628739de-779c-473d-8214-d35c72d3d4f7
ae636292-0b14-4e26-81a7-a0bfcbaf7c91
b4b5df77-8538-4ffb-a996-f67158ecd305
c6309148-6b64-4fef-aea0-d39521452699

Mendapatkan model tertentu menggunakan ID model

Blok kode berikut menggunakan ID model yang disimpan dari bagian sebelumnya dan menggunakannya untuk mengambil detail tentang model.

custom_model = form_training_client.get_custom_model(model_id=trained_model_id)
print("Model ID: {}".format(custom_model.model_id))
print("Status: {}".format(custom_model.status))
print("Training started on: {}".format(custom_model.training_started_on))
print("Training completed on: {}".format(custom_model.training_completed_on))

Output

Berikut adalah contoh output untuk model kustom yang dibuat pada contoh sebelumnya.

Model ID: ae636292-0b14-4e26-81a7-a0bfcbaf7c91
Status: ready
Training started on: 2020-08-20 23:20:56+00:00
Training completed on: 2020-08-20 23:20:57+00:00

Menghapus model dari akun sumber daya

Anda juga dapat menghapus model dari akun dengan merujuk ID model. Kode ini menghapus model yang digunakan di bagian sebelumnya.

form_training_client.delete_model(model_id=custom_model.model_id)

try:
    form_training_client.get_custom_model(model_id=custom_model.model_id)
except ResourceNotFoundError:
    print("Successfully deleted model with id {}".format(custom_model.model_id))

Menjalankan aplikasi

Jalankan aplikasi dengan python perintah di bawah:

python form-recognizer.py

Membersihkan sumber daya

Jika ingin membersihkan dan menghapus langganan Cognitive Services, Anda dapat menghapus sumber daya atau grup sumber daya. Menghapus grup sumber daya juga menghapus sumber daya apa pun yang terkait dengannya.

Pemecahan Masalah

Umum

Pustaka klien Azure Form Recognizer akan memunculkan pengecualian yang ditentukan di Azure Core.

Pengelogan

Pustaka ini menggunakan pustaka pengelogan standar untuk pengelogan. Informasi dasar tentang sesi HTTP (URL, header, dan sebagainya) dicatat di tingkat INFO.

Pengelogan tingkat DEBUG mendetail, termasuk isi permintaan/respons dan header yang tidak diedit, dapat diaktifkan pada klien dengan argumen kata kunci logging_enable:

import sys
import logging
from azure.ai.formrecognizer import FormRecognizerClient
from azure.core.credentials import AzureKeyCredential

# Create a logger for the 'azure' SDK
logger = logging.getLogger('azure')
logger.setLevel(logging.DEBUG)

# Configure a console output
handler = logging.StreamHandler(stream=sys.stdout)
logger.addHandler(handler)

endpoint = "PASTE_YOUR_FORM_RECOGNIZER_ENDPOINT_HERE"
credential = AzureKeyCredential("PASTE_YOUR_FORM_RECOGNIZER_SUBSCRIPTION_KEY_HERE")

# This client will log detailed information about its HTTP sessions, at DEBUG level
form_recognizer_client = FormRecognizerClient(endpoint, credential, logging_enable=True)

Demikian pula, logging_enable dapat mengaktifkan pengelogan terperinci untuk satu operasi, bahkan ketika tidak diaktifkan untuk klien:

receiptUrl = "https://raw.githubusercontent.com/Azure/azure-sdk-for-python/master/sdk/formrecognizer/azure-ai-formrecognizer/tests/sample_forms/receipt/contoso-receipt.png"
poller = form_recognizer_client.begin_recognize_receipts_from_url(receiptUrl, logging_enable=True)

Sampel REST di GitHub

Langkah berikutnya

Untuk proyek ini, Anda menggunakan pustaka klien Python Form Recognizer untuk melatih model dan menganalisis formulir dengan cara yang berbeda. Selanjutnya, pelajari tips untuk membuat himpunan data pelatihan yang lebih baik dan membuat model yang lebih akurat.

Catatan

  • Proyek ini menargetkan Azure Form Recognizer API versi 2.1 menggunakan cURL untuk menjalankan panggilan REST API.

| Form Recognizer REST API | Referensi Azure REST API |

Prasyarat

  • cURL terpasang.
  • PowerShell versi 6.0+, atau aplikasi baris perintah serupa.
  • Langganan Azure - Membuat langganan secara gratis
  • Blob Azure Storage yang berisi satu set data pelatihan. Lihat Membangun himpunan data pelatihan untuk model kustom untuk tips dan opsi dalam menyusun himpunan data pelatihan Anda. Anda dapat menggunakan file dalam folder Latihan dari himpunan data sampel (unduh dan ekstrak sample_data.zip).
  • Setelah Anda berlangganan Azure, buat sumber daya Form Recognizer di portal Microsoft Azure untuk mendapatkan kunci dan titik akhir Anda. Setelah menyebar, pilih Buka sumber daya.
    • Anda akan memerlukan kunci dan titik akhir sumber daya yang Anda buat untuk menghubungkan aplikasi ke API Form Recognizer. Anda akan menempelkan kunci dan titik akhir Anda ke dalam kode di bawah ini nanti di proyek
    • Anda dapat menggunakan tingkat harga gratis (F0) untuk mencoba layanan, lalu meningkatkannya ke tingkat berbayar untuk produksi.
  • URL untuk gambar tanda terima. Anda dapat menggunakan gambar sampel untuk mulai cepat ini.
  • URL untuk gambar kartu nama. Anda dapat menggunakan gambar sampel untuk mulai cepat ini.
  • URL untuk gambar faktur. Anda dapat menggunakan dokumen sampel untuk mulai cepat ini.
  • URL untuk gambar dokumen ID. Anda dapat menggunakan gambar sampel

Tip

Buat sumber daya Cognitive Services jika Anda berencana untuk mengakses beberapa layanan kognitif di bawah satu titik akhir/kunci. Hanya untuk akses Form Recognizer, buat sumber daya Form Recognizer. Harap perhatikan bahwa Anda memerlukan sumber daya layanan tunggal jika ingin menggunakan Autentikasi Azure Active Directory.

Menganalisis tata letak

Anda dapat menggunakan Form Recognizer untuk menganalisis dan mengekstrak tabel, tanda pilihan, teks, dan struktur dalam dokumen, tanpa perlu melatih model. Untuk informasi selengkapnya tentang ekstraksi tata letak, lihat Panduan konseptual tata letak. Sebelum Anda menjalankan perintah, buat perubahan ini:

  1. Ganti {endpoint} dengan titik akhir yang Anda peroleh dengan langganan Form Recognizer.
  2. Ganti {key} dengan kunci yang Anda salin dari langkah sebelumnya.
  3. Ganti \"{your-document-url} dengan salah satu contoh URL.

Minta

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

Operasi-Lokasi

Anda akan menerima 202 (Success) tanggapan yang menyertakan header Lokasi-Operasi. Nilai header ini berisi ID hasil yang dapat Anda gunakan untuk menanyakan status operasi asinkron dan mendapatkan hasilnya:

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

Dalam contoh berikut, sebagai bagian dari URL, untai setelah analyzeResults/ adalah ID hasil.

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

Mendapatkan hasil tata letak

Setelah Anda memanggil Analyze Layout API, Anda memanggil Get Analyze Layout Result API untuk mendapatkan status operasi dan data yang diekstraksi. Sebelum Anda menjalankan perintah, buat perubahan ini:

  1. Ganti {endpoint} dengan titik akhir yang Anda peroleh dengan langganan Form Recognizer.
  2. Ganti {key} dengan kunci yang Anda salin dari langkah sebelumnya.
  3. Ganti {resultId} dengan ID hasil dari langkah sebelumnya.

Minta

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

Periksa hasilnya

Anda akan menerima respons 200 (success) dengan konten JSON.

Lihat gambar faktur berikut dan output JSON yang sesuai.

  • Simpul "readResults" berisi setiap baris teks dengan penempatan kotak pembatasnya masing-masing pada halaman.
  • Simpul selectionMarks menunjukkan setiap tanda pilihan (kotak centang, tanda radio) dan apakah statusnya "dipilih" atau "tidak dipilih".
  • Bagian "pageResults" ini mencakup tabel yang diekstrak. Untuk setiap tabel, teks, baris, dan indeks kolom, rentang baris dan kolom, kotak pembatas, dan lainnya diekstraksi.

Dokumen pernyataan proyek Contoso dengan tabel.

Isi Respons

Output ini telah dipersingkat agar sederhana. Lihat output sampel lengkap di GitHub.

{
    "status": "succeeded",
    "createdDateTime": "2020-08-20T20:40:50Z",
    "lastUpdatedDateTime": "2020-08-20T20:40:55Z",
    "analyzeResult": {
        "version": "2.1.0",
        "readResults": [
            {
                "page": 1,
                "angle": 0,
                "width": 8.5,
                "height": 11,
                "unit": "inch",
                "lines": [
                    {
                        "boundingBox": [
                            0.5826,
                            0.4411,
                            2.3387,
                            0.4411,
                            2.3387,
                            0.7969,
                            0.5826,
                            0.7969
                        ],
                        "text": "Contoso, Ltd.",
                        "words": [
                            {
                                "boundingBox": [
                                    0.5826,
                                    0.4411,
                                    1.744,
                                    0.4411,
                                    1.744,
                                    0.7969,
                                    0.5826,
                                    0.7969
                                ],
                                "text": "Contoso,",
                                "confidence": 1
                            },
                            {
                                "boundingBox": [
                                    1.8448,
                                    0.4446,
                                    2.3387,
                                    0.4446,
                                    2.3387,
                                    0.7631,
                                    1.8448,
                                    0.7631
                                ],
                                "text": "Ltd.",
                                "confidence": 1
                            }
                        ]
                    },
                    ...
                        ]
                    }
                ],
                "selectionMarks": [
                    {
                        "boundingBox": [
                            3.9737,
                            3.7475,
                            4.1693,
                            3.7475,
                            4.1693,
                            3.9428,
                            3.9737,
                            3.9428
                        ],
                        "confidence": 0.989,
                        "state": "selected"
                    },
                    ...
                ]
            }
        ],
        "pageResults": [
            {
                "page": 1,
                "tables": [
                    {
                        "rows": 5,
                        "columns": 5,
                        "cells": [
                            {
                                "rowIndex": 0,
                                "columnIndex": 0,
                                "text": "Training Date",
                                "boundingBox": [
                                    0.5133,
                                    4.2167,
                                    1.7567,
                                    4.2167,
                                    1.7567,
                                    4.4492,
                                    0.5133,
                                    4.4492
                                ],
                                "elements": [
                                    "#/readResults/0/lines/12/words/0",
                                    "#/readResults/0/lines/12/words/1"
                                ]
                            },
                            ...
                        ]
                    },
                    ...
                ]
            }
        ]
    }
}

Menganalisis tanda terima

Bagian ini menunjukkan cara menganalisis dan mengekstrak bidang umum dari tanda terima US, menggunakan model tanda terima yang telah dilatih sebelumnya. Untuk mengetahui informasi selengkapnya tentang analisis tanda terima, lihat Panduan konseptual tanda terima. Untuk mulai menganalisis tanda terima, panggil Analyze Receipt API menggunakan perintah cURL di bawah. Sebelum Anda menjalankan perintah, buat perubahan ini:

  1. Ganti {endpoint} dengan titik akhir yang Anda peroleh dengan langganan Form Recognizer.
  2. Ganti {your receipt URL} dengan alamat URL gambar tanda terima.
  3. Ganti {key> dengan kunci yang Anda salin dari langkah sebelumnya.

Minta

curl -i -X POST "https://{endpoint}/formrecognizer/v2.1/prebuilt/receipt/analyze" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: {key}" --data-ascii "{ 'source': '{your receipt URL}'}"

Operasi-Lokasi

Anda akan menerima 202 (Success) tanggapan yang menyertakan header Lokasi-Operasi. Nilai header ini berisi ID hasil yang dapat Anda gunakan untuk menanyakan status operasi asinkron dan mendapatkan hasilnya:

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

Dalam contoh berikut, untai setelah operations/ adalah ID hasil:

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

Mendapatkan hasil tanda terima

Setelah Anda memanggil Analyze Receipt API, Anda memanggil Get Analyze Receipt Result API untuk mendapatkan status operasi dan data yang diekstraksi. Sebelum Anda menjalankan perintah, buat perubahan ini:

  1. Ganti {endpoint} dengan titik akhir yang Anda peroleh dengan kunci Form Recognizer Anda. Anda dapat menemukannya di tab Ringkasan sumber daya Form Recognizer.
  2. Ganti {resultId} dengan ID hasil dari langkah sebelumnya.
  3. Ganti {key} dengan kunci Anda.

Minta

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

Periksa responsnya

Anda akan menerima respons 200 (Success) dengan output JSON. Bidang pertama, "status", menunjukkan status operasi. Jika operasi tidak selesai, nilai "status" akan menjadi "running" atau "notStarted", dan Anda harus memanggil API lagi, baik secara manual atau melalui skrip. Kami merekomendasikan interval satu detik atau lebih di antara panggilan.

Simpul "readResults" berisi semua teks yang dikenali (jika Anda mengatur parameter opsional includeTextDetails ke true). Teks diatur menurut halaman, lalu menurut baris, lalu menurut kata-kata individual. Node "documentResults" berisi nilai khusus tanda terima yang ditemukan model. Node "documentResults" adalah tempat Anda akan menemukan pasangan kunci/nilai yang berguna seperti pajak, total, alamat pedagang, dan sebagainya.

Lihat gambar tanda terima berikut dan output JSON yang sesuai.

Tanda terima dari toko Contoso

Isi Respons

Output ini telah dipersingkat agar mudah dibaca. Lihat output sampel lengkap di GitHub.

{
  "status":"succeeded",
  "createdDateTime":"2019-12-17T04:11:24Z",
  "lastUpdatedDateTime":"2019-12-17T04:11:32Z",
  "analyzeResult":{
    "version":"2.1.0",
    "readResults":[
      {
        "page":1,
        "angle":0.6893,
        "width":1688,
        "height":3000,
        "unit":"pixel",
        "language":"en",
        "lines":[
          {
            "text":"Contoso",
            "boundingBox":[
              635,
              510,
              1086,
              461,
              1098,
              558,
              643,
              604
            ],
            "words":[
              {
                "text":"Contoso",
                "boundingBox":[
                  639,
                  510,
                  1087,
                  461,
                  1098,
                  551,
                  646,
                  604
                ],
                "confidence":0.955
              }
            ]
          },
          ...
        ]
      }
    ],
    "documentResults":[
      {
        "docType":"prebuilt:receipt",
        "pageRange":[
          1,
          1
        ],
        "fields":{
          "ReceiptType":{
            "type":"string",
            "valueString":"Itemized",
            "confidence":0.692
          },
          "MerchantName":{
            "type":"string",
            "valueString":"Contoso Contoso",
            "text":"Contoso Contoso",
            "boundingBox":[
              378.2,
              292.4,
              1117.7,
              468.3,
              1035.7,
              812.7,
              296.3,
              636.8
            ],
            "page":1,
            "confidence":0.613,
            "elements":[
              "#/readResults/0/lines/0/words/0",
              "#/readResults/0/lines/1/words/0"
            ]
          },
          "MerchantAddress":{
            "type":"string",
            "valueString":"123 Main Street Redmond, WA 98052",
            "text":"123 Main Street Redmond, WA 98052",
            "boundingBox":[
              302,
              675.8,
              848.1,
              793.7,
              809.9,
              970.4,
              263.9,
              852.5
            ],
            "page":1,
            "confidence":0.99,
            "elements":[
              "#/readResults/0/lines/2/words/0",
              "#/readResults/0/lines/2/words/1",
              "#/readResults/0/lines/2/words/2",
              "#/readResults/0/lines/3/words/0",
              "#/readResults/0/lines/3/words/1",
              "#/readResults/0/lines/3/words/2"
            ]
          },
          "MerchantPhoneNumber":{
            "type":"phoneNumber",
            "valuePhoneNumber":"+19876543210",
            "text":"987-654-3210",
            "boundingBox":[
              278,
              1004,
              656.3,
              1054.7,
              646.8,
              1125.3,
              268.5,
              1074.7
            ],
            "page":1,
            "confidence":0.99,
            "elements":[
              "#/readResults/0/lines/4/words/0"
            ]
          },
          "TransactionDate":{
            "type":"date",
            "valueDate":"2019-06-10",
            "text":"6/10/2019",
            "boundingBox":[
              265.1,
              1228.4,
              525,
              1247,
              518.9,
              1332.1,
              259,
              1313.5
            ],
            "page":1,
            "confidence":0.99,
            "elements":[
              "#/readResults/0/lines/5/words/0"
            ]
          },
          "TransactionTime":{
            "type":"time",
            "valueTime":"13:59:00",
            "text":"13:59",
            "boundingBox":[
              541,
              1248,
              677.3,
              1261.5,
              668.9,
              1346.5,
              532.6,
              1333
            ],
            "page":1,
            "confidence":0.977,
            "elements":[
              "#/readResults/0/lines/5/words/1"
            ]
          },
          "Items":{
            "type":"array",
            "valueArray":[
              {
                "type":"object",
                "valueObject":{
                  "Quantity":{
                    "type":"number",
                    "text":"1",
                    "boundingBox":[
                      245.1,
                      1581.5,
                      300.9,
                      1585.1,
                      295,
                      1676,
                      239.2,
                      1672.4
                    ],
                    "page":1,
                    "confidence":0.92,
                    "elements":[
                      "#/readResults/0/lines/7/words/0"
                    ]
                  },
                  "Name":{
                    "type":"string",
                    "valueString":"Cappuccino",
                    "text":"Cappuccino",
                    "boundingBox":[
                      322,
                      1586,
                      654.2,
                      1601.1,
                      650,
                      1693,
                      317.8,
                      1678
                    ],
                    "page":1,
                    "confidence":0.923,
                    "elements":[
                      "#/readResults/0/lines/7/words/1"
                    ]
                  },
                  "TotalPrice":{
                    "type":"number",
                    "valueNumber":2.2,
                    "text":"$2.20",
                    "boundingBox":[
                      1107.7,
                      1584,
                      1263,
                      1574,
                      1268.3,
                      1656,
                      1113,
                      1666
                    ],
                    "page":1,
                    "confidence":0.918,
                    "elements":[
                      "#/readResults/0/lines/8/words/0"
                    ]
                  }
                }
              },
              ...
            ]
          },
          "Subtotal":{
            "type":"number",
            "valueNumber":11.7,
            "text":"11.70",
            "boundingBox":[
              1146,
              2221,
              1297.3,
              2223,
              1296,
              2319,
              1144.7,
              2317
            ],
            "page":1,
            "confidence":0.955,
            "elements":[
              "#/readResults/0/lines/13/words/1"
            ]
          },
          "Tax":{
            "type":"number",
            "valueNumber":1.17,
            "text":"1.17",
            "boundingBox":[
              1190,
              2359,
              1304,
              2359,
              1304,
              2456,
              1190,
              2456
            ],
            "page":1,
            "confidence":0.979,
            "elements":[
              "#/readResults/0/lines/15/words/1"
            ]
          },
          "Tip":{
            "type":"number",
            "valueNumber":1.63,
            "text":"1.63",
            "boundingBox":[
              1094,
              2479,
              1267.7,
              2485,
              1264,
              2591,
              1090.3,
              2585
            ],
            "page":1,
            "confidence":0.941,
            "elements":[
              "#/readResults/0/lines/17/words/1"
            ]
          },
          "Total":{
            "type":"number",
            "valueNumber":14.5,
            "text":"$14.50",
            "boundingBox":[
              1034.2,
              2617,
              1387.5,
              2638.2,
              1380,
              2763,
              1026.7,
              2741.8
            ],
            "page":1,
            "confidence":0.985,
            "elements":[
              "#/readResults/0/lines/19/words/0"
            ]
          }
        }
      }
    ]
  }
}

Menganalisis kartu bisnis

Bagian ini menunjukkan cara menganalisis dan mengekstrak bidang umum dari kartu bisnis berbahasa Inggris menggunakan model yang dilatih sebelumnya. Untuk mengetahui informasi selengkapnya tentang analisis kartu bisnis, lihat Panduan konseptual kartu bisnis. Untuk mulai menganalisis kartu nama, Anda memanggil Analyze Business Card API menggunakan perintah cURL di bawah. Sebelum Anda menjalankan perintah, buat perubahan ini:

  1. Ganti {endpoint} dengan titik akhir yang Anda peroleh dengan langganan Form Recognizer.
  2. Ganti {your business card URL} dengan alamat URL gambar tanda terima.
  3. Ganti {key} dengan kunci yang Anda salin dari langkah sebelumnya.

Minta

curl -i -X POST "https://{endpoint}/formrecognizer/v2.1/prebuilt/businessCard/analyze" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: {key}" --data-ascii "{ 'source': '{your receipt URL}'}"

Operasi-Lokasi

Anda akan menerima 202 (Success) tanggapan yang menyertakan header Lokasi-Operasi. Nilai header ini berisi ID hasil yang dapat Anda gunakan untuk menanyakan status operasi asinkron dan mendapatkan hasilnya:

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

Dalam contoh berikut, sebagai bagian dari URL, untai setelah analyzeResults/ adalah ID hasil.

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

Mendapatkan hasil kartu nama

Setelah Anda memanggil Analyze Business Card API, Anda memanggil Get Analyze Business Card API untuk mendapatkan status operasi dan data yang diekstraksi. Sebelum Anda menjalankan perintah, buat perubahan ini:

  1. Ganti {endpoint} dengan titik akhir yang Anda peroleh dengan kunci Form Recognizer Anda. Anda dapat menemukannya di tab Ringkasan sumber daya Form Recognizer.
  2. Ganti {resultId} dengan ID hasil dari langkah sebelumnya.
  3. Ganti {key} dengan kunci Anda.
curl -v -X GET https://{endpoint}/formrecognizer/v2.1/prebuilt/businessCard/analyzeResults/{resultId}"
-H "Ocp-Apim-Subscription-Key: {key}"

Periksa responsnya

Anda akan menerima respons 200 (Success) dengan output JSON.

Simpul "readResults" berisi semua teks yang dikenali. Teks diatur menurut halaman, lalu menurut baris, lalu menurut kata-kata individual. Node "documentResults" berisi nilai khusus kartu nama yang ditemukan model. Node "documentResults" adalah tempat Anda akan menemukan informasi kontak yang berguna seperti nama perusahaan, nama depan, nama belakang, nomor telepon, dan sebagainya.

Kartu nama dari perusahaan Contoso

Contoh output JSON ini telah dipersingkat agar mudah dibaca. Lihat output sampel lengkap di GitHub.

{
    "status": "succeeded",
    "createdDateTime":"2021-02-09T18:14:05Z",
    "lastUpdatedDateTime":"2021-02-09T18:14:10Z",
    "analyzeResult": {
        "version": "2.1.0",
        "readResults": [
            {
             "page":1,
             "angle":-16.6836,
             "width":4032,
             "height":3024,
             "unit":"pixel"
          }
        ],
        "documentResults": [
            {
                "docType": "prebuilt:businesscard",
                "pageRange": [
                    1,
                    1
                ],
                "fields": {
                    "ContactNames": {
                        "type": "array",
                        "valueArray": [
                            {
                                "type": "object",
                                "valueObject": {
                                    "FirstName": {
                                        "type": "string",
                                        "valueString": "Avery",
                                        "text": "Avery",
                                        "boundingBox": [
                                            703,
                                            1096,
                                            1134,
                                            989,
                                            1165,
                                            1109,
                                            733,
                                            1206
                                        ],
                                        "page": 1
                                },
                                "text": "Dr. Avery Smith",
                                "boundingBox": [
                                    419.3,
                                    1154.6,
                                    1589.6,
                                    877.9,
                                    1618.9,
                                    1001.7,
                                    448.6,
                                    1278.4
                                ],
                                "confidence": 0.993
                            }
                        ]
                    },
                    "Emails": {
                        "type": "array",
                        "valueArray": [
                            {
                                "type": "string",
                                "valueString": "avery.smith@contoso.com",
                                "text": "avery.smith@contoso.com",
                                "boundingBox": [
                                    2107,
                                    934,
                                    2917,
                                    696,
                                    2935,
                                    764,
                                    2126,
                                    995
                                ],
                                "page": 1,
                                "confidence": 0.99
                            }
                        ]
                    },
                    "Websites": {
                        "type": "array",
                        "valueArray": [
                            {
                                "type": "string",
                                "valueString": "https://www.contoso.com/",
                                "text": "https://www.contoso.com/",
                                "boundingBox": [
                                    2121,
                                    1002,
                                    2992,
                                    755,
                                    3014,
                                    826,
                                    2143,
                                    1077
                                ],
                                "page": 1,
                                "confidence": 0.995
                            }
                        ]
                    }
                }
            }
        ]
    }
}

Skrip akan mencetak tanggapan ke konsol hingga operasi Analyze Business Card selesai.

Menganalisis faktur

Anda bisa menggunakan Form Recognizer untuk mengekstrak teks bidang dan nilai semantik dari dokumen faktur tertentu. Untuk mulai menganalisis faktur, gunakan perintah cURL di bawah ini. Untuk mengetahui informasi selengkapnya tentang analisis faktur, lihat Panduan konseptual faktur. Untuk mulai menganalisis faktur, panggil Analyze Faktur API menggunakan perintah cURL di bawah ini. Sebelum Anda menjalankan perintah, buat perubahan ini:

  1. Ganti {endpoint} dengan titik akhir yang Anda peroleh dengan langganan Form Recognizer.
  2. Ganti {your invoice URL} dengan alamat URL dokumen faktur.
  3. Ganti {key} dengan kunci Anda.

Minta

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

Operasi-Lokasi

Anda akan menerima 202 (Success) tanggapan yang menyertakan header Lokasi-Operasi. Nilai header ini berisi ID hasil yang dapat Anda gunakan untuk menanyakan status operasi asinkron dan mendapatkan hasilnya:

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

Dalam contoh berikut, sebagai bagian dari URL, untai setelah analyzeResults/ adalah ID hasil:

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

Mendapatkan hasil faktur

Setelah Anda memanggil API Analyze Invoice, Anda memanggil API Get Analyze Invoice Result untuk mendapatkan status operasi dan data yang diekstrak. Sebelum Anda menjalankan perintah, buat perubahan ini:

  1. Ganti {endpoint} dengan titik akhir yang Anda peroleh dengan kunci Form Recognizer Anda. Anda dapat menemukannya di tab Ringkasan sumber daya Form Recognizer.
  2. Ganti {resultId} dengan ID hasil dari langkah sebelumnya.
  3. Ganti {key} dengan kunci Anda.

Minta

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

Periksa responsnya

Anda akan menerima respons 200 (Success) dengan output JSON.

  • Bidang "readResults" berisi setiap baris teks yang diambil dari faktur.
  • "pageResults" menyertakan tabel dan tanda pilihan yang diambil dari faktur.
  • Bidang "documentResults" berisi informasi kunci/nilai untuk bagian faktur yang paling relevan.

Lihat dokumen faktur berikut dan output JSON yang sesuai.

Isi Respons

Konten JSON ini telah dipersingkat agar mudah dibaca. Lihat output sampel lengkap di GitHub.

{
    "status": "succeeded",
    "createdDateTime": "2020-11-06T23:32:11Z",
    "lastUpdatedDateTime": "2020-11-06T23:32:20Z",
    "analyzeResult": {
        "version": "2.1.0",
        "readResults": [{
            "page": 1,
            "angle": 0,
            "width": 8.5,
            "height": 11,
            "unit": "inch"
        }],
        "pageResults": [{
            "page": 1,
            "tables": [{
                "rows": 3,
                "columns": 4,
                "cells": [{
                    "rowIndex": 0,
                    "columnIndex": 0,
                    "text": "QUANTITY",
                    "boundingBox": [0.4953,
                    5.7306,
                    1.8097,
                    5.7306,
                    1.7942,
                    6.0122,
                    0.4953,
                    6.0122]
                },
                {
                    "rowIndex": 0,
                    "columnIndex": 1,
                    "text": "DESCRIPTION",
                    "boundingBox": [1.8097,
                    5.7306,
                    5.7529,
                    5.7306,
                    5.7452,
                    6.0122,
                    1.7942,
                    6.0122]
                },
                ...
                ],
                "boundingBox": [0.4794,
                5.7132,
                8.0158,
                5.714,
                8.0118,
                6.5627,
                0.4757,
                6.5619]
            },
            {
                "rows": 2,
                "columns": 6,
                "cells": [{
                    "rowIndex": 0,
                    "columnIndex": 0,
                    "text": "SALESPERSON",
                    "boundingBox": [0.4979,
                    4.963,
                    1.8051,
                    4.963,
                    1.7975,
                    5.2398,
                    0.5056,
                    5.2398]
                },
                {
                    "rowIndex": 0,
                    "columnIndex": 1,
                    "text": "P.O. NUMBER",
                    "boundingBox": [1.8051,
                    4.963,
                    3.3047,
                    4.963,
                    3.3124,
                    5.2398,
                    1.7975,
                    5.2398]
                },
                ...
                ],
                "boundingBox": [0.4976,
                4.961,
                7.9959,
                4.9606,
                7.9959,
                5.5204,
                0.4972,
                5.5209]
            }]
        }],
        "documentResults": [{
            "docType": "prebuilt:invoice",
            "pageRange": [1,
            1],
            "fields": {
                "AmountDue": {
                    "type": "number",
                    "valueNumber": 610,
                    "text": "$610.00",
                    "boundingBox": [7.3809,
                    7.8153,
                    7.9167,
                    7.8153,
                    7.9167,
                    7.9591,
                    7.3809,
                    7.9591],
                    "page": 1,
                    "confidence": 0.875
                },
                "BillingAddress": {
                    "type": "string",
                    "valueString": "123 Bill St, Redmond WA, 98052",
                    "text": "123 Bill St, Redmond WA, 98052",
                    "boundingBox": [0.594,
                    4.3724,
                    2.0125,
                    4.3724,
                    2.0125,
                    4.7125,
                    0.594,
                    4.7125],
                    "page": 1,
                    "confidence": 0.997
                },
                "BillingAddressRecipient": {
                    "type": "string",
                    "valueString": "Microsoft Finance",
                    "text": "Microsoft Finance",
                    "boundingBox": [0.594,
                    4.1684,
                    1.7907,
                    4.1684,
                    1.7907,
                    4.2837,
                    0.594,
                    4.2837],
                    "page": 1,
                    "confidence": 0.998
                },
                ...
            }
        }]
    }
}

Menganalisis dokumen identitas (ID)

Untuk mulai menganalisis dokumen identifikasi, gunakan perintah cURL di bawah ini. Untuk informasi selengkapnya tentang analisis dokumen ID, lihat panduan konseptual dokumen ID. Untuk mulai menganalisis dokumen ID, Anda memanggil Analyze Document ID API menggunakan perintah cURL di bawah ini. Sebelum Anda menjalankan perintah, buat perubahan ini:

  1. Ganti {endpoint} dengan titik akhir yang Anda peroleh dengan langganan Form Recognizer.
  2. Ganti {your ID document URL} dengan alamat URL gambar tanda terima.
  3. Ganti {key} dengan kunci yang Anda salin dari langkah sebelumnya.

Minta

curl -i -X POST "https://{endpoint}/formrecognizer/v2.1/prebuilt/idDocument/analyze" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: {key}" --data-ascii "{ 'source': '{your ID document URL}'}"

Operasi-Lokasi

Anda akan menerima 202 (Success) tanggapan yang menyertakan header Lokasi-Operasi. Nilai header ini berisi ID hasil yang dapat Anda gunakan untuk menanyakan status operasi asinkron dan mendapatkan hasilnya:

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

Dalam contoh berikut, untai setelah analyzeResults/ adalah ID hasil:

https://westus.api.cognitive.microsoft.com/formrecognizer/v2.1/prebuilt/idDocument/analyzeResults/83d0137b-28e1-4051-98ce-42bd21f77ae0

Mendapatkan hasil Analyze ID Document

Setelah Anda memanggil Analyze ID Document API, panggil Get Analyze ID Document Result API untuk mendapatkan status operasi dan data yang diekstraksi. Sebelum Anda menjalankan perintah, buat perubahan ini:

  1. Ganti {endpoint} dengan titik akhir yang Anda peroleh dengan kunci Form Recognizer Anda. Anda dapat menemukannya di tab Ringkasan sumber daya Form Recognizer.
  2. Ganti {resultId} dengan ID hasil dari langkah sebelumnya.
  3. Ganti {key} dengan kunci Anda.

Minta

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

Periksa responsnya

Anda akan menerima respons 200 (Success) dengan output JSON. Bidang pertama, "status", menunjukkan status operasi. Jika operasi tidak selesai, nilai "status" akan menjadi "running" atau "notStarted", dan Anda harus memanggil API lagi, baik secara manual atau melalui skrip hingga Anda menerima nilai succeeded. Kami merekomendasikan interval satu detik atau lebih di antara panggilan.

  • Bidang "readResults" berisi setiap baris teks yang diambil dari dokumen ID.
  • Bidang "documentResults" berisi array objek, masing-masing mewakili dokumen ID yang terdeteksi dalam dokumen masukan.

Di bawah ini adalah sampel dokumen ID dan output JSON yang sesuai

  • sampel driver lisensi

Isi Respons

{
    "status": "succeeded",
    "createdDateTime": "2021-04-13T17:24:52Z",
    "lastUpdatedDateTime": "2021-04-13T17:24:55Z",
    "analyzeResult": {
      "version": "2.1.0",
      "readResults": [
        {
          "page": 1,
          "angle": -0.2823,
          "width": 450,
          "height": 294,
          "unit": "pixel"
        }
      ],
      "documentResults": [
        {
          "docType": "prebuilt:idDocument:driverLicense",
          "docTypeConfidence": 0.995,
          "pageRange": [
            1,
            1
          ],
          "fields": {
            "Address": {
              "type": "string",
              "valueString": "123 STREET ADDRESS YOUR CITY WA 99999-1234",
              "text": "123 STREET ADDRESS YOUR CITY WA 99999-1234",
              "boundingBox": [
                158,
                151,
                326,
                151,
                326,
                177,
                158,
                177
              ],
              "page": 1,
              "confidence": 0.965
            },
            "CountryRegion": {
              "type": "countryRegion",
              "valueCountryRegion": "USA",
              "confidence": 0.99
            },
            "DateOfBirth": {
              "type": "date",
              "valueDate": "1958-01-06",
              "text": "01/06/1958",
              "boundingBox": [
                187,
                133,
                272,
                132,
                272,
                148,
                187,
                149
              ],
              "page": 1,
              "confidence": 0.99
            },
            "DateOfExpiration": {
              "type": "date",
              "valueDate": "2020-08-12",
              "text": "08/12/2020",
              "boundingBox": [
                332,
                230,
                414,
                228,
                414,
                244,
                332,
                245
              ],
              "page": 1,
              "confidence": 0.99
            },
            "DocumentNumber": {
              "type": "string",
              "valueString": "LICWDLACD5DG",
              "text": "LIC#WDLABCD456DG",
              "boundingBox": [
                162,
                70,
                307,
                68,
                307,
                84,
                163,
                85
              ],
              "page": 1,
              "confidence": 0.99
            },
            "FirstName": {
              "type": "string",
              "valueString": "LIAM R.",
              "text": "LIAM R.",
              "boundingBox": [
                158,
                102,
                216,
                102,
                216,
                116,
                158,
                116
              ],
              "page": 1,
              "confidence": 0.985
            },
            "LastName": {
              "type": "string",
              "valueString": "TALBOT",
              "text": "TALBOT",
              "boundingBox": [
                160,
                86,
                213,
                85,
                213,
                99,
                160,
                100
              ],
              "page": 1,
              "confidence": 0.987
            },
            "Region": {
              "type": "string",
              "valueString": "Washington",
              "confidence": 0.99
            },
            "Sex": {
              "type": "string",
              "valueString": "M",
              "text": "M",
              "boundingBox": [
                226,
                190,
                232,
                190,
                233,
                201,
                226,
                201
              ],
              "page": 1,
              "confidence": 0.99
            }
          }
        }
      ]
    }
  }

Melatih model kustom

Untuk melatih model kustom, Anda memerlukan kumpulan data pelatihan dalam blob Azure Storage. Anda memerlukan minimal lima formulir yang telah diisi (dokumen PDF dan/atau gambar) dengan jenis/struktur yang sama. Lihat Membuat himpunan data pelatihan untuk model kustom untuk kiat dan opsi dalam menyusun data pelatihan Anda.

Pelatihan tanpa data berlabel adalah operasi default dan lebih sederhana. Atau, Anda dapat memberi label secara manual pada beberapa atau semua data latihan Anda sebelumnya. Pelabelan manual adalah proses yang lebih kompleks tetapi menghasilkan model yang lebih terlatih.

Catatan

Anda juga dapat melatih model dengan antarmuka pengguna grafis seperti alat Pelabelan Sampel Form Recognizer.

Melatih model tanpa label

Untuk melatih model Pengenal Formulir dengan dokumen di kontainer blob Azure Anda, panggil Latih Model Kustom API dengan menjalankan perintah cURL berikut. Sebelum Anda menjalankan perintah, buat perubahan ini:

  1. Ganti {endpoint} dengan titik akhir yang Anda peroleh dengan langganan Form Recognizer.

  2. Ganti {key} dengan kunci yang Anda salin dari langkah sebelumnya.

  3. Ganti {SAS URL} dengan URL tanda tangan akses bersama (SAS) kontainer penyimpanan Azure Blob. Untuk mengambil URL SAS untuk data pelatihan model kustom Anda, buka sumber daya penyimpanan di portal Microsoft Azure dan pilih tab Penjelajah Penyimpanan. Buka kontainer Anda, klik kanan, lalu pilih Dapatkan tanda tangan akses bersama. Sangat penting untuk mendapatkan SAS untuk kontainer Anda, bukan untuk akun penyimpanan itu sendiri. Pastikan izin Baca, Tulis, Hapus, dan Cantumkan dicentang, lalu klik Buat. Kemudian salin nilai di bagian URL ke lokasi sementara. Ini harus memiliki format: https://<storage account>.blob.core.windows.net/<container name>?<SAS value>.

    Pengambilan URL SAS

Minta

curl -i -X POST "https://{endpoint}/formrecognizer/v2.1/custom/models" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: {key}" --data-ascii "{ 'source': '{SAS URL}'}"

Lokasi

Anda akan menerima respons 201 (Success) dengan header Lokasi. Nilai header ini berisi ID model untuk model yang baru dilatih yang dapat Anda gunakan untuk mengkueri status operasi dan mendapatkan hasilnya:

https://{endpoint}/formrecognizer/v2.1/custom/models/ {modelId}

Dalam contoh berikut, sebagai bagian dari URL, untai setelah models/ adalah ID model.

https://westus.api.cognitive.microsoft.com/formrecognizer/v2.1/custom/models/77d8ecad-b8c1-427e-ac20-a3fe4af503e9

Melatih model dengan label

Untuk berlatih dengan label, Anda harus memiliki file informasi label khusus (\<filename\>.pdf.labels.json) di kontainer penyimpanan blob Anda bersama dengan dokumen pelatihan. Alat Pelabelan Sampel Form Recognizer menyediakan UI untuk membantu Anda membuat file label ini. Setelah memilikinya, Anda dapat memanggil API Latih Model Kustom, dengan parameter "useLabelFile" diatur ke true di badan JSON.

Sebelum Anda menjalankan perintah, buat perubahan ini:

  1. Ganti {endpoint} dengan titik akhir yang Anda peroleh dengan langganan Form Recognizer.

  2. Ganti {key} dengan kunci yang Anda salin dari langkah sebelumnya.

  3. Ganti {SAS URL} dengan URL tanda tangan akses bersama (SAS) kontainer penyimpanan Azure Blob. Untuk mengambil URL SAS untuk data pelatihan model kustom Anda, buka sumber daya penyimpanan di portal Microsoft Azure dan pilih tab Penjelajah Penyimpanan. Buka kontainer Anda, klik kanan, lalu pilih Dapatkan tanda tangan akses bersama. Sangat penting untuk mendapatkan SAS untuk kontainer Anda, bukan untuk akun penyimpanan itu sendiri. Pastikan izin Baca, Tulis, Hapus, dan Cantumkan dicentang, lalu klik Buat. Kemudian salin nilai di bagian URL ke lokasi sementara. Ini harus memiliki format: https://<storage account>.blob.core.windows.net/<container name>?<SAS value>.

    Pengambilan URL SAS

Minta

curl -i -X POST "https://{endpoint}/formrecognizer/v2.1/custom/models" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: {key}" --data-ascii "{ 'source': '{SAS URL}', 'useLabelFile':true}"

Lokasi

Anda akan menerima respons 201 (Success) dengan header Lokasi. Nilai header ini berisi ID model untuk model yang baru dilatih yang dapat Anda gunakan untuk mengkueri status operasi dan mendapatkan hasilnya:

https://{endpoint}/formrecognizer/v2.1/custom/models/ {modelId}

Dalam contoh berikut, sebagai bagian dari URL, untai setelah models/ adalah ID model.

https://westus.api.cognitive.microsoft.com/formrecognizer/v2.1/custom/models/4da0bf8e-5325-467c-93bb-9ff13d5f72a2

Mendapatkan hasil pelatihan

Setelah Anda memulai pengoperasian latihan, gunakan Get Custom Model untuk memeriksa status pelatihan. Teruskan ID model ke dalam permintaan API untuk memeriksa status pelatihan:

  1. Ganti {endpoint} dengan titik akhir yang Anda peroleh dengan kunci Form Recognizer Anda.
  2. Ganti {key} dengan kunci Anda
  3. Ganti {model ID} dengan ID model Anda terima di langkah sebelumnya

Minta

curl -X GET "https://{endpoint}/formrecognizer/v2.1/custom/models/{modelId}" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: {key}"

Menganalisis formulir dengan model kustom

Selanjutnya, Anda akan menggunakan model yang baru dilatih untuk menganalisis dokumen dan mengekstrak bidang dan tabel darinya. Panggil Analyze Form API dengan menjalankan perintah cURL berikut. Sebelum Anda menjalankan perintah, buat perubahan ini:

  1. Ganti {endpoint} dengan titik akhir yang Anda peroleh dari kunci Form Recognizer. Anda dapat menemukannya di tab Ringkasan sumber daya Form Recognizer.
  2. Ganti {model ID} dengan ID model yang Anda terima di bagian sebelumnya.
  3. Ganti {SAS URL} dengan URL SAS ke file Anda di penyimpanan Azure. Ikuti langkah-langkah di bagian Pelatihan, tetapi alih-alih mendapatkan URL SAS untuk seluruh kontainer blob, dapatkan satu untuk file tertentu yang ingin Anda analisis.
  4. Ganti {key} dengan kunci Anda.

Minta

curl -v "https://{endpoint}/formrecognizer/v2.1/custom/models/{modelId}/analyze?includeTextDetails=true" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: {key}" -d "{ 'source': '{SAS URL}' } "

Anda akan menerima 202 (Success) respons dengan header Lokasi-Operasi. Nilai header ini menyertakan ID hasil yang akan Anda gunakan untuk melacak hasil operasi Analisis:

https://cognitiveservice/formrecognizer/v2.1/custom/models/{modelId}/analyzeResults/ {resultId}

Dalam contoh berikut, sebagai bagian dari URL, untai setelah analyzeResults/ adalah ID hasil.

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

Simpan ID hasil ini untuk langkah selanjutnya.

Mendapatkan hasil Analisis

Panggil Get Analyze Form Result API untuk mengkueri hasil operasi Analisis.

  1. Ganti {endpoint} dengan titik akhir yang Anda peroleh dari kunci Form Recognizer. Anda dapat menemukannya di tab Ringkasan sumber daya Form Recognizer.
  2. Ganti {result ID} dengan ID yang Anda terima di bagian sebelumnya.
  3. Ganti {key} dengan kunci Anda.

Minta

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

Anda akan menerima respons 200 (Success) dengan isi JSON dalam format berikut. Output ini telah dipersingkat agar sederhana. Perhatikan bidang "status" di dekat bagian bawah. Bidang ini akan memiliki nilai "succeeded" saat operasi Analisis selesai. Jika operasi Analisis belum selesai, Anda harus menanyakan layanan lagi dengan menjalankan kembali perintah. Kami merekomendasikan interval satu detik atau lebih di antara panggilan.

Dalam model kustom yang dilatih tanpa label, asosiasi dan tabel pasangan kunci/nilai berada di simpul "pageResults" dari keluaran JSON. Dalam model kustom yang dilatih dengan label, asosiasi pasangan kunci/nilai berada pada node "documentResults". Jika Anda juga menentukan ekstraksi teks biasa melalui parameter URL includeTextDetails, maka simpul "readResults" akan menampilkan konten dan posisi semua teks dalam dokumen.

Contoh keluaran JSON ini telah dipersingkat agar sederhana. Lihat output sampel lengkap di GitHub.

Isi Respons

{
  "status": "succeeded",
  "createdDateTime": "2020-08-21T01:13:28Z",
  "lastUpdatedDateTime": "2020-08-21T01:13:42Z",
  "analyzeResult": {
    "version": "2.1.0",
    "readResults": [
      {
        "page": 1,
        "angle": 0,
        "width": 8.5,
        "height": 11,
        "unit": "inch",
        "lines": [
          {
            "text": "Project Statement",
            "boundingBox": [
              5.0444,
              0.3613,
              8.0917,
              0.3613,
              8.0917,
              0.6718,
              5.0444,
              0.6718
            ],
            "words": [
              {
                "text": "Project",
                "boundingBox": [
                  5.0444,
                  0.3587,
                  6.2264,
                  0.3587,
                  6.2264,
                  0.708,
                  5.0444,
                  0.708
                ]
              },
              {
                "text": "Statement",
                "boundingBox": [
                  6.3361,
                  0.3635,
                  8.0917,
                  0.3635,
                  8.0917,
                  0.6396,
                  6.3361,
                  0.6396
                ]
              }
            ]
          },
          ...
        ]
      }
    ],
    "pageResults": [
      {
        "page": 1,
        "keyValuePairs": [
          {
            "key": {
              "text": "Date:",
              "boundingBox": [
                6.9833,
                1.0615,
                7.3333,
                1.0615,
                7.3333,
                1.1649,
                6.9833,
                1.1649
              ],
              "elements": [
                "#/readResults/0/lines/2/words/0"
              ]
            },
            "value": {
              "text": "9/10/2020",
              "boundingBox": [
                7.3833,
                1.0802,
                7.925,
                1.0802,
                7.925,
                1.174,
                7.3833,
                1.174
              ],
              "elements": [
                "#/readResults/0/lines/3/words/0"
              ]
            },
            "confidence": 1
          },
          ...
        ],
        "tables": [
          {
            "rows": 5,
            "columns": 5,
            "cells": [
              {
                "text": "Training Date",
                "rowIndex": 0,
                "columnIndex": 0,
                "boundingBox": [
                  0.6944,
                  4.2779,
                  1.5625,
                  4.2779,
                  1.5625,
                  4.4005,
                  0.6944,
                  4.4005
                ],
                "confidence": 1,
                "rowSpan": 1,
                "columnSpan": 1,
                "elements": [
                  "#/readResults/0/lines/15/words/0",
                  "#/readResults/0/lines/15/words/1"
                ],
                "isHeader": true,
                "isFooter": false
              },
              ...
            ]
          }
        ],
        "clusterId": 0
      }
    ],
    "documentResults": [],
    "errors": []
  }
}

Meningkatkan hasil

Periksa "confidence" nilai untuk setiap hasil kunci/nilai di bawah "pageResults" simpul. Anda juga harus melihat skor kepercayaan diri dalam "readResults" simpul, yang sesuai dengan operasi baca teks. Kepercayaan diri hasil baca tidak mempengaruhi kepercayaan diri dari hasil ekstraksi kunci/nilai, jadi Anda harus memeriksa keduanya.

  • Jika skor kepercayaan diri untuk operasi baca rendah, cobalah untuk meningkatkan kualitas dokumen input Anda (lihat Persyaratan input).
  • Jika skor kepercayaan untuk operasi ekstraksi kunci/nilai rendah, pastikan bahwa dokumen yang dianalisis memiliki jenis yang sama dengan dokumen yang digunakan dalam kumpulan pelatihan. Jika dokumen dalam kumpulan pelatihan memiliki variasi penampilan, pertimbangkan untuk membaginya menjadi folder yang berbeda dan melatih satu model untuk setiap variasi.

Skor kepercayaan diri yang Anda targetkan akan tergantung pada kasus penggunaan Anda, tetapi umumnya itu adalah praktik yang baik untuk menargetkan skor 80% atau lebih. Untuk kasus yang lebih sensitif, seperti membaca catatan medis atau laporan penagihan, skor 100% direkomendasikan.

Mengelola model kustom

Mendapatkan daftar model kustom

Gunakan List Custom Models API dalam perintah berikut untuk menampilkan daftar semua model kustom milik langganan Anda.

  1. Ganti {endpoint} dengan titik akhir yang Anda peroleh dengan langganan Form Recognizer.
  2. Ganti {key} dengan kunci yang Anda salin dari langkah sebelumnya.

Minta

curl -v -X GET "https://{endpoint}/formrecognizer/v2.1/custom/models?op=full"
-H "Ocp-Apim-Subscription-Key: {key}"

Isi Respons

Anda akan menerima 200 respons sukses, dengan data JSON seperti berikut. Elemen "modelList" berisi semua model yang Anda buat dan informasinya.

{
  "summary": {
    "count": 0,
    "limit": 0,
    "lastUpdatedDateTime": "string"
  },
  "modelList": [
    {
      "modelId": "string",
      "status": "creating",
      "createdDateTime": "string",
      "lastUpdatedDateTime": "string"
    }
  ],
  "nextLink": "string"
}

Mendapatkan model tertentu

Untuk mengambil informasi terperinci tentang model kustom tertentu, gunakan Get Custom Model API dalam perintah berikut.

  1. Ganti {endpoint} dengan titik akhir yang Anda peroleh dengan langganan Form Recognizer.
  2. Ganti {key} dengan kunci yang Anda salin dari langkah sebelumnya.
  3. Ganti {modelId} dengan ID model kustom yang ingin Anda cari.

Minta

curl -v -X GET "https://{endpoint}/formrecognizer/v2.1/custom/models/{modelId}" -H "Ocp-Apim-Subscription-Key: {key}"

Isi permintaan

Anda akan menerima 200 respons sukses, dengan data JSON seperti berikut.

{
  "modelInfo": {
    "modelId": "string",
    "status": "creating",
    "createdDateTime": "string",
    "lastUpdatedDateTime": "string"
  },
  "keys": {
    "clusters": {}
  },
  "trainResult": {
    "trainingDocuments": [
      {
        "documentName": "string",
        "pages": 0,
        "errors": [
          "string"
        ],
        "status": "succeeded"
      }
    ],
    "fields": [
      {
        "fieldName": "string",
        "accuracy": 0.0
      }
    ],
    "averageModelAccuracy": 0.0,
    "errors": [
      {
        "message": "string"
      }
    ]
  }
}

Menghapus model dari akun sumber daya

Anda juga dapat menghapus model dari akun dengan mereferensikan ID-nya. Perintah ini memanggil Delete Custom Model API untuk menghapus model yang digunakan di bagian sebelumnya.

  1. Ganti {endpoint} dengan titik akhir yang Anda peroleh dengan langganan Form Recognizer.
  2. Ganti {key} dengan kunci yang Anda salin dari langkah sebelumnya.
  3. Ganti {modelId} dengan ID model kustom yang ingin Anda cari.

Minta

curl -v -X DELETE "https://{endpoint}/formrecognizer/v2.1/custom/models/{modelId}" -H "Ocp-Apim-Subscription-Key: {key}"

Anda akan menerima 204 respons sukses, yang menunjukkan bahwa model Anda ditandai untuk dihapus. Model artefak akan dihapus secara permanen dalam waktu 48 jam.

Langkah berikutnya

Untuk proyek ini, Anda menggunakan REST API Azure Form Recognizer untuk menganalisis formulir dengan berbagai cara. Selanjutnya, jelajahi dokumentasi referensi untuk mempelajari tentang Form Recognizer API secara lebih mendalam.