Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FormRecognizer] Preview 3: moving to new Receipt design #12523

Merged
merged 8 commits into from
Jun 5, 2020
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sdk/formrecognizer/Azure.AI.FormRecognizer/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
- The order of the values for `USReceiptType` have changed so that `Other` has now a value of `1`.
- Parameter `useTrainingLabels` is now required for `FormTrainingClient.StartTraining`.
- Protected constructors have been removed from `Operation` types, such as `TrainingOperation` or `RecognizeContentOperation`.
- `USReceipt`, `USReceiptItem` and `USReceiptType` types removed. Information about a `RecognizedReceipt` must now be extracted from its `RecognizedForm`.

### New Features

Expand Down
83 changes: 64 additions & 19 deletions sdk/formrecognizer/Azure.AI.FormRecognizer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,33 +137,78 @@ Recognize data from US sales receipts using a prebuilt model.
using (FileStream stream = new FileStream(receiptPath, FileMode.Open))
{
RecognizedReceiptCollection receipts = await client.StartRecognizeReceipts(stream).WaitForCompletionAsync();

foreach (var receipt in receipts)
{
USReceipt usReceipt = receipt.AsUSReceipt();
FormField merchantNameField;
kinelski marked this conversation as resolved.
Show resolved Hide resolved
if (receipt.RecognizedForm.Fields.TryGetValue("MerchantName", out merchantNameField))
{
if (merchantNameField.Value.Type == FieldValueType.String)
{
string merchantName = merchantNameField.Value.AsString();

string merchantName = usReceipt.MerchantName?.Value ?? default;
DateTime transactionDate = usReceipt.TransactionDate?.Value ?? default;
IReadOnlyList<USReceiptItem> items = usReceipt.Items ?? default;
float subtotal = usReceipt.Subtotal?.Value ?? default;
float tax = usReceipt.Tax?.Value ?? default;
float tip = usReceipt.Tip?.Value ?? default;
float total = usReceipt.Total?.Value ?? default;
Console.WriteLine($" Merchant Name: '{merchantName}', with confidence {merchantNameField.Confidence}");
}
}

Console.WriteLine($"Recognized USReceipt fields:");
Console.WriteLine($" Merchant Name: '{merchantName}', with confidence {usReceipt.MerchantName.Confidence}");
Console.WriteLine($" Transaction Date: '{transactionDate}', with confidence {usReceipt.TransactionDate.Confidence}");
FormField transactionDateField;
if (receipt.RecognizedForm.Fields.TryGetValue("TransactionDate", out transactionDateField))
{
if (transactionDateField.Value.Type == FieldValueType.Date)
{
DateTime transactionDate = transactionDateField.Value.AsDate();

for (int i = 0; i < items.Count; i++)
Console.WriteLine($" Transaction Date: '{transactionDate}', with confidence {transactionDateField.Confidence}");
}
}

FormField itemsField;
if (receipt.RecognizedForm.Fields.TryGetValue("Items", out itemsField))
{
USReceiptItem item = usReceipt.Items[i];
Console.WriteLine($" Item {i}: Name: '{item.Name.Value}', Quantity: '{item.Quantity?.Value}', Price: '{item.Price?.Value}'");
Console.WriteLine($" TotalPrice: '{item.TotalPrice.Value}'");
if (itemsField.Value.Type == FieldValueType.List)
{
foreach (FormField itemField in itemsField.Value.AsList())
{
if (itemField.Value.Type == FieldValueType.Dictionary)
{
IReadOnlyDictionary<string, FormField> itemFields = itemField.Value.AsDictionary();

FormField itemNameField;
if (itemFields.TryGetValue("MerchantName", out itemNameField))
kinelski marked this conversation as resolved.
Show resolved Hide resolved
{
if (itemNameField.Value.Type == FieldValueType.String)
{
string itemName = itemNameField.Value.AsString();

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

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

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

Console.WriteLine($" Subtotal: '{subtotal}', with confidence '{usReceipt.Subtotal.Confidence}'");
Console.WriteLine($" Tax: '{tax}', with confidence '{usReceipt.Tax.Confidence}'");
Console.WriteLine($" Tip: '{tip}', with confidence '{usReceipt.Tip?.Confidence ?? 0.0f}'");
Console.WriteLine($" Total: '{total}', with confidence '{usReceipt.Total.Confidence}'");
FormField totalField;
if (receipt.RecognizedForm.Fields.TryGetValue("Total", out totalField))
{
if (totalField.Value.Type == FieldValueType.Float)
{
float total = totalField.Value.AsFloat();

Console.WriteLine($" Total: '{total}', with confidence '{totalField.Confidence}'");
}
}
}
}
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,33 +23,78 @@ To recognize receipts from a URI, use the `StartRecognizeReceiptsFromUri` method

```C# Snippet:FormRecognizerSampleRecognizeReceiptFileFromUri
RecognizedReceiptCollection receipts = await client.StartRecognizeReceiptsFromUri(new Uri(receiptUri)).WaitForCompletionAsync();

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

string merchantName = usReceipt.MerchantName?.Value ?? default;
DateTime transactionDate = usReceipt.TransactionDate?.Value ?? default;
IReadOnlyList<USReceiptItem> items = usReceipt.Items ?? default;
float subtotal = usReceipt.Subtotal?.Value ?? default;
float tax = usReceipt.Tax?.Value ?? default;
float tip = usReceipt.Tip?.Value ?? default;
float total = usReceipt.Total?.Value ?? default;
Console.WriteLine($" Merchant Name: '{merchantName}', with confidence {merchantNameField.Confidence}");
}
}

Console.WriteLine($"Recognized USReceipt fields:");
Console.WriteLine($" Merchant Name: '{merchantName}', with confidence {usReceipt.MerchantName.Confidence}");
Console.WriteLine($" Transaction Date: '{transactionDate}', with confidence {usReceipt.TransactionDate.Confidence}");
FormField transactionDateField;
if (receipt.RecognizedForm.Fields.TryGetValue("TransactionDate", out transactionDateField))
{
if (transactionDateField.Value.Type == FieldValueType.Date)
{
DateTime transactionDate = transactionDateField.Value.AsDate();

for (int i = 0; i < items.Count; i++)
Console.WriteLine($" Transaction Date: '{transactionDate}', with confidence {transactionDateField.Confidence}");
}
}

FormField itemsField;
if (receipt.RecognizedForm.Fields.TryGetValue("Items", out itemsField))
{
USReceiptItem item = usReceipt.Items[i];
Console.WriteLine($" Item {i}: Name: '{item.Name.Value}', Quantity: '{item.Quantity?.Value}', Price: '{item.Price?.Value}'");
Console.WriteLine($" TotalPrice: '{item.TotalPrice.Value}'");
if (itemsField.Value.Type == FieldValueType.List)
{
foreach (FormField itemField in itemsField.Value.AsList())
{
if (itemField.Value.Type == FieldValueType.Dictionary)
{
IReadOnlyDictionary<string, FormField> itemFields = itemField.Value.AsDictionary();

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

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

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

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

Console.WriteLine($" Subtotal: '{subtotal}', with confidence '{usReceipt.Subtotal.Confidence}'");
Console.WriteLine($" Tax: '{tax}', with confidence '{usReceipt.Tax.Confidence}'");
Console.WriteLine($" Tip: '{tip}', with confidence '{usReceipt.Tip?.Confidence ?? 0.0f}'");
Console.WriteLine($" Total: '{total}', with confidence '{usReceipt.Total.Confidence}'");
FormField totalField;
if (receipt.RecognizedForm.Fields.TryGetValue("Total", out totalField))
{
if (totalField.Value.Type == FieldValueType.Float)
{
float total = totalField.Value.AsFloat();

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ internal AccountProperties(ModelsSummary_internal summary)
/// <summary>
/// The current count of trained custom models.
/// </summary>
public int CustomModelCount { get; internal set; }
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In parallel to the main changes, removing these internal set properties across the client since we are not using them at all.

public int CustomModelCount { get; }

/// <summary>
/// The maximum number of models that can be trained for this subscription.
/// </summary>
public int CustomModelLimit { get; internal set; }
public int CustomModelLimit { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ internal CustomFormSubmodel(string formType, float? accuracy, IReadOnlyDictionar
/// <summary>
/// The type of form this submodel recognizes.
/// </summary>
public string FormType { get; internal set; }
public string FormType { get; }

/// <summary>
/// The mean of the accuracies of this model's <see cref="CustomFormModelField"/>
/// instances.
/// </summary>
public float? Accuracy { get; internal set; }
public float? Accuracy { get; }

/// <summary>
/// A dictionary of the fields that this submodel will recognize from the
Expand All @@ -35,6 +35,6 @@ internal CustomFormSubmodel(string formType, float? accuracy, IReadOnlyDictionar
/// label of the field. For models trained with forms only, a unique name is
/// generated for each field.
/// </summary>
public IReadOnlyDictionary<string, CustomFormModelField> Fields { get; internal set; }
public IReadOnlyDictionary<string, CustomFormModelField> Fields { get; }
}
}
8 changes: 4 additions & 4 deletions sdk/formrecognizer/Azure.AI.FormRecognizer/src/FormField.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,22 @@ internal FormField(string name, FieldValue_internal fieldValue, IReadOnlyList<Re
/// <summary>
/// Canonical name; uniquely identifies a field within the form.
/// </summary>
public string Name { get; internal set; }
public string Name { get; }

/// <summary>
/// Contains the text, bounding box and content of the label of the field in the form.
/// </summary>
public FieldText LabelText { get; internal set; }
public FieldText LabelText { get; }

/// <summary>
/// Contains the text, bounding box and content of the value of the field in the form.
/// </summary>
public FieldText ValueText { get; internal set; }
public FieldText ValueText { get; }

/// <summary>
/// The strongly-typed value of this <see cref="FormField"/>.
/// </summary>
public FieldValue Value { get; internal set; }
public FieldValue Value { get; }

/// <summary>
/// Measures the degree of certainty of the recognition result. Value is between [0.0, 1.0].
Expand Down
63 changes: 0 additions & 63 deletions sdk/formrecognizer/Azure.AI.FormRecognizer/src/FormField{T}.cs

This file was deleted.

2 changes: 1 addition & 1 deletion sdk/formrecognizer/Azure.AI.FormRecognizer/src/FormLine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ internal FormLine(TextLine_internal textLine, int pageNumber)
/// <summary>
/// A list of the words that make up the line.
/// </summary>
public IReadOnlyList<FormWord> Words { get; internal set; }
public IReadOnlyList<FormWord> Words { get; }

private static IReadOnlyList<FormWord> ConvertWords(IReadOnlyList<TextWord_internal> textWords, int pageNumber)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ public partial class FormRecognizerError
/// The error code.
/// </summary>
[CodeGenMember("Code")]
public string ErrorCode { get; internal set; }
public string ErrorCode { get; }

/// <summary>
/// The error message.
/// </summary>
[CodeGenMember("Message")]
public string Message { get; internal set; }
public string Message { get; }
}
}
12 changes: 0 additions & 12 deletions sdk/formrecognizer/Azure.AI.FormRecognizer/src/GetModelOptions.cs

This file was deleted.

This file was deleted.

Loading