-
Notifications
You must be signed in to change notification settings - Fork 6
/
AzureOcrEngine.cs
144 lines (118 loc) · 4.63 KB
/
AzureOcrEngine.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
using Microsoft.Azure.CognitiveServices.Vision.ComputerVision;
using Microsoft.Azure.CognitiveServices.Vision.ComputerVision.Models;
using Syncfusion.Drawing;
using Syncfusion.OCRProcessor;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PointF = Syncfusion.Drawing.PointF;
namespace OCRScanner
{
class AzureOcrEngine : IOcrEngine
{
private string subscriptionKey = "provide subscription key here";
private string endpoint = "provide endpoint link here";
public OCRLayoutResult PerformOCR(Stream imgStream)
{
ComputerVisionClient client = Authenticate();
ReadResult azureOcrResult = ReadFileUrl(client, imgStream).Result;
OCRLayoutResult result = ConvertAzureVisionOcrToOcrLayoutResult(azureOcrResult);
return result;
}
public ComputerVisionClient Authenticate()
{
ComputerVisionClient client = new ComputerVisionClient(new ApiKeyServiceClientCredentials(subscriptionKey))
{
Endpoint = endpoint
};
return client;
}
public async Task<ReadResult> ReadFileUrl(ComputerVisionClient client, Stream stream)
{
stream.Position = 0;
var textHeaders = await client.ReadInStreamAsync(stream);
string operationLocation = textHeaders.OperationLocation;
const int numberOfCharsInOperationId = 36;
string operationId = operationLocation.Substring(operationLocation.Length - numberOfCharsInOperationId);
//Extract the text.
ReadOperationResult results;
do
{
results = await client.GetReadResultAsync(Guid.Parse(operationId));
}
while ((results.Status == OperationStatusCodes.Running || results.Status == OperationStatusCodes.NotStarted));
ReadResult azureOcrResult = results.AnalyzeResult.ReadResults[0];
return azureOcrResult;
}
private OCRLayoutResult ConvertAzureVisionOcrToOcrLayoutResult(ReadResult azureVisionOcr)
{
Syncfusion.OCRProcessor.Line ocrLine;
Syncfusion.OCRProcessor.Word ocrWord;
OCRLayoutResult ocrlayoutResult = new OCRLayoutResult();
ocrlayoutResult.ImageWidth = (float)azureVisionOcr.Width;
ocrlayoutResult.ImageHeight = (float)azureVisionOcr.Height;
//Page
Syncfusion.OCRProcessor.Page normalPage = new Syncfusion.OCRProcessor.Page();
//Lines
foreach (var line in azureVisionOcr.Lines)
{
ocrLine = new Syncfusion.OCRProcessor.Line();
//Word
foreach (var word in line.Words)
{
ocrWord = new Syncfusion.OCRProcessor.Word();
Rectangle rect = GetAzureVisionBounds(word.BoundingBox);
ocrWord.Text = word.Text;
ocrWord.Rectangle = rect;
ocrLine.Add(ocrWord);
}
normalPage.Add(ocrLine);
}
ocrlayoutResult.Add(normalPage);
return ocrlayoutResult;
}
private Rectangle GetAzureVisionBounds(IList<double?> bbox)
{
Rectangle rect = Rectangle.Empty;
PointF[] pointCollection = new PointF[bbox.Count / 2];
int count = 0;
for (int i = 0; i < bbox.Count; i = i + 2)
{
pointCollection[count] = new PointF((float)bbox[i], (float)bbox[i + 1]);
count++;
}
float xMin = 0;
float yMin = 0;
float xMax = 0;
float yMax = 0;
bool first = true;
foreach (PointF point in pointCollection)
{
if (first)
{
xMin = point.X;
yMin = point.Y;
first = false;
}
else
{
if (point.X < xMin)
xMin = point.X;
else if (point.X > xMax)
xMax = point.X;
if (point.Y < yMin)
yMin = point.Y;
else if (point.Y > yMax)
yMax = point.Y;
}
}
int x = Convert.ToInt32(xMin);
int y = Convert.ToInt32(yMin);
int w = Convert.ToInt32(xMax);
int h = Convert.ToInt32(yMax);
return new Rectangle(x, y, w, h);
}
}
}