Skip to content

Commit c9e6d23

Browse files
Merge pull request #104032 from yungshinlintw/v3quickstart
[Cog Svcs] V3.0-Preivew Quickstart update
2 parents 2dc02d1 + e219283 commit c9e6d23

File tree

5 files changed

+1752
-19
lines changed

5 files changed

+1752
-19
lines changed

articles/cognitive-services/Computer-vision/QuickStarts/CSharp-hand-text.md

Lines changed: 322 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: "Quickstart: Extract printed and handwritten text - REST, C#"
2+
title: "Quickstart: Computer Vision 2.0 and 2.1 - Extract printed and handwritten text - REST, C#"
33
titleSuffix: "Azure Cognitive Services"
44
description: In this quickstart, you extract printed and handwritten text from an image using the Computer Vision API with C#.
55
services: cognitive-services
@@ -13,22 +13,41 @@ ms.date: 12/05/2019
1313
ms.author: pafarley
1414
ms.custom: seodec18
1515
---
16-
# Quickstart: Extract printed and handwritten text using the Computer Vision REST API and C#
16+
# Quickstart: Extract printed and handwritten text using the Computer Vision 2.0 and 2.1 REST API and C#
1717

1818
In this quickstart, you will extract printed and/or handwritten text from an image using the Computer Vision REST API. With the [Batch Read](https://westus.dev.cognitive.microsoft.com/docs/services/5adf991815e1060e6355ad44/operations/2afb498089f74080d7ef85eb) and [Read Operation Result](https://westus.dev.cognitive.microsoft.com/docs/services/5adf991815e1060e6355ad44/operations/5be108e7498a4f9ed20bf96d) methods, you can detect text in an image and extract recognized characters into a machine-readable character stream. The API will determine which recognition model to use for each line of text, so it supports images with both printed and handwritten text.
1919

20+
Compared to Computer Vision 2.0 and 2.1, the Computer Vision 3.0 Public Preview provides:
21+
22+
* even better accuracy
23+
* a changed output format
24+
* confidence score for words
25+
* support of both Spanish and English languages with the additional language parameter
26+
27+
#### [Version 2](#tab/version-2)
28+
2029
> [!IMPORTANT]
21-
> The [Batch Read](https://westus.dev.cognitive.microsoft.com/docs/services/5adf991815e1060e6355ad44/operations/2afb498089f74080d7ef85eb) method runs asynchronously. This method does not return any information in the body of a successful response. Instead, the Read method returns a URI in the `Operation-Location` response header field. You can then use this URI, which represents the [Read Operation Result](https://westus.dev.cognitive.microsoft.com/docs/services/5adf991815e1060e6355ad44/operations/5be108e7498a4f9ed20bf96d) method, in order to check the status and return the results of the Batch Read method call.
30+
> The [Batch Read](https://westus.dev.cognitive.microsoft.com/docs/services/5adf991815e1060e6355ad44/operations/2afb498089f74080d7ef85eb) method runs asynchronously. This method does not return any information in the body of a successful response. Instead, the Batch Read method returns a URI in the value of the `Operation-Location` response header field. You can then call this URI, which represents the [Read Operation Result](https://westus.dev.cognitive.microsoft.com/docs/services/5adf991815e1060e6355ad44/operations/5be108e7498a4f9ed20bf96d) API, to both check the status and return the results of the Batch Read method call.
31+
32+
#### [Version 3 (Public preview)](#tab/version-3)
33+
34+
> [!IMPORTANT]
35+
> The [Batch Read](https://westus2.dev.cognitive.microsoft.com/docs/services/5d98695995feb7853f67d6a6/operations/5d986960601faab4bf452005) method runs asynchronously. This method does not return any information in the body of a successful response. Instead, the Batch Read method returns a URI in the value of the `Operation-Location` response header field. You can then call this URI, which represents the [Read Operation Result](https://westus2.dev.cognitive.microsoft.com/docs/services/5d98695995feb7853f67d6a6/operations/5d9869604be85dee480c8750) API, to both check the status and return the results of the Batch Read method call.
36+
37+
---
2238

23-
If you don't have an Azure subscription, create a [free account](https://azure.microsoft.com/free/ai/?ref=microsoft.com&utm_source=microsoft.com&utm_medium=docs&utm_campaign=cognitive-services) before you begin.
2439

2540
## Prerequisites
2641

42+
If you don't have an Azure subscription, create a [free account](https://azure.microsoft.com/free/ai/?ref=microsoft.com&utm_source=microsoft.com&utm_medium=docs&utm_campaign=cognitive-services) before you begin.
43+
2744
- You must have [Visual Studio 2015 or later](https://visualstudio.microsoft.com/downloads/).
2845
- You must have a subscription key for Computer Vision. You can get a free trial key from [Try Cognitive Services](https://azure.microsoft.com/try/cognitive-services/?api=computer-vision). Or, follow the instructions in [Create a Cognitive Services account](https://docs.microsoft.com/azure/cognitive-services/cognitive-services-apis-create-account) to subscribe to Computer Vision and get your key. Then, [create environment variables](https://docs.microsoft.com/azure/cognitive-services/cognitive-services-apis-create-account#configure-an-environment-variable-for-authentication) for the key and service endpoint string, named `COMPUTER_VISION_SUBSCRIPTION_KEY` and `COMPUTER_VISION_ENDPOINT`, respectively.
2946

3047
## Create and run the sample application
3148

49+
#### [Version 2](#tab/version-2)
50+
3251
To create the sample in Visual Studio, do the following steps:
3352

3453
1. Create a new Visual Studio solution in Visual Studio, using the Visual C# Console App template.
@@ -200,10 +219,237 @@ namespace CSHttpClientSample
200219
}
201220
```
202221

222+
#### [Version 3 (Public preview)](#tab/version-3)
223+
224+
To create the sample in Visual Studio, do the following steps:
225+
226+
1. Create a new Visual Studio solution in Visual Studio, using the Visual C# Console App template.
227+
1. Install the Newtonsoft.Json NuGet package.
228+
1. On the menu, click **Tools**, select **NuGet Package Manager**, then **Manage NuGet Packages for Solution**.
229+
1. Click the **Browse** tab, and in the **Search** box type "Newtonsoft.Json".
230+
1. Select **Newtonsoft.Json** when it displays, then click the checkbox next to your project name, and **Install**.
231+
1. Run the program.
232+
1. At the prompt, enter the path to a local image and the language to recognize.
233+
234+
```csharp
235+
using Newtonsoft.Json.Linq;
236+
using System;
237+
using System.IO;
238+
using System.Linq;
239+
using System.Net.Http;
240+
using System.Net.Http.Headers;
241+
using System.Threading.Tasks;
242+
using System.Web;
243+
244+
namespace CSHttpClientSample
245+
{
246+
static class Program
247+
{
248+
// Add your Computer Vision subscription key and endpoint to your environment variables.
249+
static string subscriptionKey = Environment.GetEnvironmentVariable("COMPUTER_VISION_SUBSCRIPTION_KEY");
250+
251+
// An endpoint should have a format like "https://westus.api.cognitive.microsoft.com"
252+
static string endpoint = Environment.GetEnvironmentVariable("COMPUTER_VISION_ENDPOINT");
253+
254+
// the Batch Read method endpoint
255+
static string uriBase = endpoint + "/vision/v3.0-preview/read/analyze";
256+
257+
static void PrintUsage()
258+
{
259+
// Get the path and filename to process from the user.
260+
Console.WriteLine("Cognitive Service Batch Read File Sample");
261+
Console.WriteLine("Usage: ");
262+
Console.WriteLine(" From Azure Cogntivie Service, retrieve your endpoint and subscription key.");
263+
Console.WriteLine(" Set environment variable COMPUTER_VISION_ENDPOINT, such as \"https://westus2.api.cognitive.microsoft.com\"");
264+
Console.WriteLine(" Set environment variable COMPUTER_VISION_SUBSCRIPTION_KEY, such as \"1234567890abcdef1234567890abcdef\"\n");
265+
Console.WriteLine(" Run the program without argument to enter a file name and a language manually.");
266+
Console.WriteLine(" Or run the program with a file name for an image file (bmp/jpg/png/tiff) or a PDF file, plus the language. The language can be \"en\" or \"es\".");
267+
Console.WriteLine(" For example: dotnet Program.dll sample.jpg en");
268+
Console.WriteLine();
269+
}
270+
271+
static void Main(string[] args)
272+
{
273+
PrintUsage();
274+
275+
if (string.IsNullOrEmpty(subscriptionKey) || string.IsNullOrEmpty(endpoint))
276+
{
277+
Console.Error.WriteLine("Please set environment variables COMPUTER_VISION_ENDPOINT and COMPUTER_VISION_SUBSCRIPTION_KEY.");
278+
return;
279+
}
280+
281+
string imageFilePath;
282+
string language;
283+
if (args.Length == 0)
284+
{
285+
Console.Write(
286+
"Enter the path to an image (bmp/jpg/png/tiff) or PDF with text you wish to read: ");
287+
imageFilePath = Console.ReadLine();
288+
}
289+
else
290+
{
291+
imageFilePath = args[0];
292+
}
293+
294+
if (args.Length <= 1)
295+
{
296+
Console.Write(
297+
"Enter the language to read: \"en\" or \"es\": ");
298+
language = Console.ReadLine();
299+
}
300+
else
301+
{
302+
language = args[1];
303+
}
304+
305+
Console.WriteLine($"Endpoint: [{endpoint}]");
306+
Console.WriteLine($"Subscription: [{subscriptionKey}]");
307+
Console.WriteLine($"URL: [{uriBase}]");
308+
309+
if (File.Exists(imageFilePath))
310+
{
311+
// Call the REST API method.
312+
Console.WriteLine("\nWait a moment for the results to appear.\n");
313+
ReadText(imageFilePath, language).Wait();
314+
}
315+
else
316+
{
317+
Console.WriteLine("\nInvalid file path");
318+
}
319+
Console.WriteLine("\nPress Enter to exit...");
320+
Console.ReadLine();
321+
}
322+
323+
/// <summary>
324+
/// Gets the text from the specified image file by using
325+
/// the Computer Vision REST API.
326+
/// </summary>
327+
/// <param name="imageFilePath">The image file with text.</param>
328+
static async Task ReadText(string imageFilePath, string language)
329+
{
330+
try
331+
{
332+
HttpClient client = new HttpClient();
333+
334+
// Request headers.
335+
client.DefaultRequestHeaders.Add(
336+
"Ocp-Apim-Subscription-Key", subscriptionKey);
337+
338+
var builder = new UriBuilder(uriBase);
339+
builder.Port = -1;
340+
var query = HttpUtility.ParseQueryString(builder.Query);
341+
query["language"] = language;
342+
builder.Query = query.ToString();
343+
string url = builder.ToString();
344+
345+
HttpResponseMessage response;
346+
347+
// Two REST API methods are required to extract text.
348+
// One method to submit the image for processing, the other method
349+
// to retrieve the text found in the image.
350+
351+
// operationLocation stores the URI of the second REST API method,
352+
// returned by the first REST API method.
353+
string operationLocation;
354+
355+
// Reads the contents of the specified local image
356+
// into a byte array.
357+
byte[] byteData = GetImageAsByteArray(imageFilePath);
358+
359+
// Adds the byte array as an octet stream to the request body.
360+
using (ByteArrayContent content = new ByteArrayContent(byteData))
361+
{
362+
// This example uses the "application/octet-stream" content type.
363+
// The other content types you can use are "application/json"
364+
// and "multipart/form-data".
365+
content.Headers.ContentType =
366+
new MediaTypeHeaderValue("application/octet-stream");
367+
368+
// The first REST API method, Batch Read, starts
369+
// the async process to analyze the written text in the image.
370+
response = await client.PostAsync(url, content);
371+
}
372+
373+
// The response header for the Batch Read method contains the URI
374+
// of the second method, Read Operation Result, which
375+
// returns the results of the process in the response body.
376+
// The Batch Read operation does not return anything in the response body.
377+
if (response.IsSuccessStatusCode)
378+
operationLocation =
379+
response.Headers.GetValues("Operation-Location").FirstOrDefault();
380+
else
381+
{
382+
// Display the JSON error data.
383+
string errorString = await response.Content.ReadAsStringAsync();
384+
Console.WriteLine("\n\nResponse:\n{0}\n",
385+
JToken.Parse(errorString).ToString());
386+
return;
387+
}
388+
389+
// If the first REST API method completes successfully, the second
390+
// REST API method retrieves the text written in the image.
391+
//
392+
// Note: The response may not be immediately available. Text
393+
// recognition is an asynchronous operation that can take a variable
394+
// amount of time depending on the length of the text.
395+
// You may need to wait or retry this operation.
396+
//
397+
// This example checks once per second for ten seconds.
398+
string contentString;
399+
int i = 0;
400+
do
401+
{
402+
System.Threading.Thread.Sleep(1000);
403+
response = await client.GetAsync(operationLocation);
404+
contentString = await response.Content.ReadAsStringAsync();
405+
++i;
406+
}
407+
while (i < 60 && contentString.IndexOf("\"status\":\"succeeded\"") == -1);
408+
409+
if (i == 60 && contentString.IndexOf("\"status\":\"succeeded\"") == -1)
410+
{
411+
Console.WriteLine("\nTimeout error.\n");
412+
return;
413+
}
414+
415+
// Display the JSON response.
416+
Console.WriteLine("\nResponse:\n\n{0}\n",
417+
JToken.Parse(contentString).ToString());
418+
}
419+
catch (Exception e)
420+
{
421+
Console.WriteLine("\n" + e.Message);
422+
}
423+
}
424+
425+
/// <summary>
426+
/// Returns the contents of the specified file as a byte array.
427+
/// </summary>
428+
/// <param name="imageFilePath">The image file to read.</param>
429+
/// <returns>The byte array of the image data.</returns>
430+
static byte[] GetImageAsByteArray(string imageFilePath)
431+
{
432+
// Open a read-only file stream for the specified file.
433+
using (FileStream fileStream =
434+
new FileStream(imageFilePath, FileMode.Open, FileAccess.Read))
435+
{
436+
// Read the file's contents into a byte array.
437+
BinaryReader binaryReader = new BinaryReader(fileStream);
438+
return binaryReader.ReadBytes((int)fileStream.Length);
439+
}
440+
}
441+
}
442+
}
443+
```
444+
445+
---
446+
203447
## Examine the response
204448

205449
A successful response is returned in JSON. The sample application parses and displays a successful response in the console window, similar to the following example:
206450

451+
#### [Version 2](#tab/version-2)
452+
207453
```json
208454
{
209455
"status": "Succeeded",
@@ -304,6 +550,78 @@ A successful response is returned in JSON. The sample application parses and dis
304550
}
305551
```
306552

553+
#### [Version 3 (Public preview)](#tab/version-3)
554+
555+
556+
```json
557+
{
558+
"status": "succeeded",
559+
"createdDateTime": "2020-02-11T16:44:36Z",
560+
"lastUpdatedDateTime": "2020-02-11T16:44:36Z",
561+
"analyzeResult": {
562+
"version": "3.0.0",
563+
"readResults": [
564+
{
565+
"page": 1,
566+
"language": "es",
567+
"angle": -0.8011,
568+
"width": 401,
569+
"height": 119,
570+
"unit": "pixel",
571+
"lines": [
572+
{
573+
"language": "es",
574+
"boundingBox": [
575+
15,
576+
42,
577+
372,
578+
38,
579+
373,
580+
91,
581+
15,
582+
97
583+
],
584+
"text": "¡Buenos días!",
585+
"words": [
586+
{
587+
"boundingBox": [
588+
15,
589+
43,
590+
243,
591+
40,
592+
244,
593+
93,
594+
17,
595+
98
596+
],
597+
"text": "¡Buenos",
598+
"confidence": 0.56
599+
},
600+
{
601+
"boundingBox": [
602+
254,
603+
40,
604+
370,
605+
38,
606+
371,
607+
91,
608+
255,
609+
93
610+
],
611+
"text": "días!",
612+
"confidence": 0.872
613+
}
614+
]
615+
}
616+
]
617+
}
618+
]
619+
}
620+
}
621+
```
622+
623+
---
624+
307625
## Clean up resources
308626

309627
When no longer needed, delete the Visual Studio solution. To do so, open File Explorer, navigate to the folder in which you created the Visual Studio solution, and delete the folder.

0 commit comments

Comments
 (0)