图像转文本:使用 Azure Computer Vision





5.00/5 (2投票s)
一个简单的教程,包含一些关于如何使用 Azure Computer Vision 从图像中读取文本的代码。
引言
收据丢失是任何电脑应用都无法解决的问题。但前者,也就是有收据的,是我们能够自动化的。一些技术可以将图像转换为文本。这通过 OCR(光学字符识别)完成。它可以从手写信件、图像、路牌、收据(!)、产品标签以及更多内容中提取文本。
Microsoft Azure 拥有计算机视觉,这是一项专门针对我们需求的资源和技术:读取收据上的文本。计算机视觉可以识别多种语言。但目前我将只使用英语。
我还尝试了另一个非常流行的 OCR:Aspose.OCR
。尽管网上有更多的关于这个包的教程,但它并没有达到我的预期。并非所有文本都能被找到,有些还被替换成了奇怪的字符。“为了获得更好的性能,您应该购买它。”有些人这么说。我拥有 Azure 积分,而且在使用免费服务时,它的效果要好得多。
摘要:让我们创建一个小型控制台应用程序,它可以读取收据图片并获取总金额。我们将使用 C#、Visual Studio 和 Azure 计算机视觉。
创建计算机视觉资源
在使用计算机视觉的 OCR 功能之前,我们需要在 Azure 云中对其进行设置。它就像其他资源一样是一种服务。通过门户,创建新的计算机视觉服务非常容易。登录后,您可以搜索计算机视觉并选择它。
点击左上角的创建按钮来创建一个新的计算机视觉服务。
基础
第一页看起来与其他许多 Azure 服务一样,选项也相似。第一部分是关于您的订阅(应该已填写),资源组、区域、名称和定价层。
除了定价层之外,其他一切都应该很容易理解。所以,让我们稍微深入了解一下定价层。
第一个选项是免费 F0。但有一个限制。您每月只能向此计算机视觉发送 5000 次免费调用,每分钟 20 次。这似乎不多,但很快就会达到上限,尤其是在测试时。这个免费层也仅用于开发和测试,不能用于生产。您只能免费使用一次。
第二个选项是标准 S1。尽管它每秒有 10 次调用,但此层有更多的“规则”。您需要为多个事务付费。例如,0 到 100 万次事务的费用为每 1000 次事务 1 美元,依此类推。
目前,我们还是坚持使用免费的。可惜,我已经在另一个项目中用完了免费额度,所以无法再次使用。因此,如果您在我的截图上看到标准 S1,请不要感到惊讶。
网络
网络选项卡提供了新服务如何被访问的选项。有三个选项:
- 所有网络,包括互联网,都可以访问此资源。
这基本上意味着任何使用互联网的人(人类和计算机)都可以访问。如果您要处理重要数据,这并不是一个安全的选项。
对于简单的收据读取器,此选项将是最佳选择。 - 选定的网络,并为您的认知服务资源配置网络安全。
对于此选项,您需要创建和配置自己的 Azure 网络,这是一个完全不同的领域。我目前不打算覆盖它。
如果您确实拥有自己的网络,此选项将允许您选择可以访问此资源的网络。处理重要数据的一种好方法。 - 已禁用,没有网络可以访问此资源。您可以配置私有终结点连接,这将是访问此资源的唯一方式。
使用此选项,您可以创建自己的终结点,就像 API 一样。缺点是:配置比 API 要复杂得多。
我选择了第一个选项。
身份
通过此选项卡,我们可以允许此新资源授予对其他资源的访问权限。我必须承认,这是 Azure 微软提供的一个有点奇怪且不合逻辑的选项卡,我从未用过它。我只是保持关闭状态,然后继续。
如果您确实想使用此身份,请将其设置为“开启”并添加您的身份。请确保在分配它们之前创建它们……您可以分配一个不存在的东西,对吧?
审阅和创建
如果一切顺利,请点击创建。这可能需要一些时间。您还没有完成!在资源创建并运行后,我们需要从中提取一些信息。这些信息允许 C# 应用程序连接到该资源。
如果一切顺利,请点击创建。这可能需要一些时间。您还没有完成!在资源创建并运行后,我们需要从中提取一些信息。这些信息允许 C# 应用程序连接到该资源。
终结点和密钥
为了让我们的 C# 应用程序与计算机视觉资源通信,我们需要告诉它资源的终结点是什么,并使用密钥进行身份验证。您可以通过刚刚创建的计算机视觉资源的概览找到这些信息。
找到终结点并不难,它就在那里。右侧中间。复制并保存以备后用。
密钥(或多个密钥)也不难找到。就在终结点下方是“管理密钥:”和一个链接。点击此链接,您将看到一个新屏幕,其中也显示了终结点……再次。
只需点击“显示密钥”按钮,即可显示密钥。您只需要一个密钥,所以复制一个并将其与终结点一起保存。稍后您将需要它。
终结点是资源在互联网上的位置。密钥是身份验证。这样,并非所有人都可以调用终结点并使用您的资源。
就是这样!计算机视觉资源现已创建并运行。我们已收集到所需信息。让我们开始编写 C# 代码。
控制台应用程序
为了让控制台应用程序读取收据,我们需要一张收据。您可以使用自己的。只需拍一张您拥有的收据照片并保存在您的驱动器上。如果您没有收据,您可以使用我的。
正如您所见,这张收据并不是特别干净。有点模糊,有一些折痕和晕墨。正是我喜欢的!因为这可能是一个挑战。请记住:没有完美的收据或其他纸张图片。我还拍了照片时留了一些边距,所以您也看到了阴影。
让我们创建项目。我创建了一个简单的 .NET 6 控制台应用程序,没有什么花哨的。图像文件应该在命令行参数中,而不是硬编码。这样我就可以测试多个图像。我使用 C# 和 .NET 6 创建了一个新的控制台应用程序。我将项目命名为ReceiptReaderDemo
。
我做的第一件事是删除program.cs 文件中的脚手架代码。稍后我会回到这个文件。接下来,我创建了一个新类并将其命名为ReceiptReader.cs。这将是我将负责加载硬盘上的图像、将其发送到 Azure 并从 Azure 返回文本的类。
用于读取的类
首先,我在类的顶部声明了两个新的static
变量。这两个变量将保存我创建计算机视觉资源时从 Azure 获得的订阅密钥和终结点。
readonly string subscriptionKey = "e43cc17b60774baebc42fec1baac22d7";
readonly string endpoint = "https://receiptreadercv.cognitiveservices.azure.com/";
就我个人而言,我会将这类信息放在配置文件中,例如 appsettings。但我这里没有,而且这也不在本文的讨论范围之内。
在我能够使用 Azure 计算机视觉做任何事情之前,我需要安装一个包。这个包包含了我需要的一切。让我们安装这个包。
Install-Package Microsoft.Azure.CognitiveServices.Vision.ComputerVision
安装完成后,我们可以使用密钥和终结点进行身份验证,然后让 Azure 将图像转换为文本。我在ReceiptReader
类中创建了一个新的方法:Authenticate。此方法会将订阅密钥发送到 Azure 以进行应用程序身份验证。如果成功,您将获得一个客户端,可以将其发送图像到 Azure 计算机视觉进行处理。该方法如下所示:
private ComputerVisionClient Authenticate()
{
ComputerVisionClient client =
new(new ApiKeyServiceClientCredentials(subscriptionKey))
{
Endpoint = endpoint
};
return client;
}
首先,我初始化了一个新的ComputerVisionClient
,它是我的计算机视觉资源和我的应用程序之间的通信接口。构造函数需要某种形式的身份验证,所以我给它一个新初始化的ApiKeyServiceCredentials
,它会验证我的订阅密钥。我还将终结点设置为ComputerVisionClient
,以便它知道我的计算机视觉 API 在哪里。
现在我们可以进行身份验证,并且可以处理文件了。我创建了另一个async private
方法,并将其命名为ProcessFile
。这是一个相当大的方法,所以我会先向您展示。
private async Task<string> ProcessFile(ComputerVisionClient client, string pathToFile)
{
FileStream stream = File.OpenRead(pathToFile);
ReadInStreamHeaders textHeaders = await client.ReadInStreamAsync(stream);
Thread.Sleep(2000);
string operationLocation = textHeaders.OperationLocation;
string operationId = operationLocation[^36..];
ReadOperationResult results;
do
{
results = await client.GetReadResultAsync(Guid.Parse(operationId));
}
while ((results.Status == OperationStatusCodes.Running ||
results.Status == OperationStatusCodes.NotStarted));
IList<ReadResult> textUrlFileResults = results.AnalyzeResult.ReadResults;
StringBuilder sb = new();
foreach (ReadResult page in textUrlFileResults)
{
foreach (Line line in page.Lines)
{
sb.AppendLine(line.Text);
}
}
return string.Join(Environment.NewLine, sb);
}
看起来代码量很大,对吧?我会一步步为您讲解。准备好了吗?我们开始吧!
第 3 行将图像打开为一个FileStream
。第 4 行将该流发送到我的计算机视觉资源(还记得终结点吗?)。这可能需要一些时间。
第 6 行让应用程序等待 2 秒,因为我的资源需要一些时间来处理图像。
我只发送了图像进行处理,但我并没有收到任何返回……好吧,我收到一个OperationLocation
。这基本上是一个指向我的 API 的 URI。该 URI 包含一个 GUID,它是我的已处理图像的标识符。我需要获取该 GUID 并使用它来获取结果。第 8 行和第 9 行检索此 GUID,它有 36 个字符长。
在第 11 行,我声明了一个ReadOprationResult
变量。它将保存我的计算机视觉资源的结果;即实际文本。
因为 Azure 可能仍在处理我的图像,所以我创建了一个do
-while
循环。只要我的ReadOperationResult
的状态是“运行中”或者尚未开始,它就应该重复循环。第 13 行启动 do。第 15 行通过客户端使用操作标识符(来自第 9 行)从 Azure 获取我的处理结果。
如果一切顺利,在我的机器上是这样的,results.AnalyzeResult
将包含ReadResults
。这些是计算机视觉资源找到的文本页面。在第 19 行,我将这些页面放入一个ReadResult
列表中。
我想遍历页面并获取行。以下操作可以用更少的代码完成,但那样会降低可读性。
第 21 行的StringBuilder
将保存所有文本行。第 22 行启动foreach
循环,该循环将遍历页面。第 24 行启动一个遍历页面行的循环。我在第 26 行将文本行添加到StringBuilder
。
一切完成后,我用换行符连接StringBuilder
中的行并返回它。
好了,我们现在需要做的就是创建一个可以从控制台应用程序调用的public
方法。我创建了一个新的异步public
方法,名为Read
。它将接收pathToFile
参数,这是我们要读取的图像的路径。此方法返回一个string
。它将从Authenticate
方法获取客户端,然后从ProcessFile
方法检索文本。
public async Task<string> Read(string pathToFile)
{
ComputerVisionClient client = Authenticate();
return await ProcessFile(client, pathToFile);
}
ReceiptReader
类现在已经完成,可以开始工作了。让我们回到program.cs。
填充 program.cs
这部分代码不多。只是一个文件存在性检查,初始化ReceiptReader
类,从该类检索文本,并在屏幕上显示。
using ReceiptReaderDemo;
string path = Environment.GetCommandLineArgs()[1];
if (!File.Exists(path))
throw new FileNotFoundException($"File not found at {path}");
Console.WriteLine("Reading receipt...");
ReceiptReader receiptReader = new();
string content = await receiptReader.Read(path);
Console.WriteLine("\tSucceeded");
Console.WriteLine(content);
我觉得这不需要太多解释,对吧?
哦,还有一件事!如果您在 Visual Studio 中运行此应用程序,您将无法输入文件路径……或者可以吗?
命令行参数
在 Visual Studio 中为控制台应用程序添加命令行参数有一种方法。如果您转到控制台应用程序的属性(右键单击项目 -> 属性),展开调试,然后单击常规。接下来,单击“打开调试启动配置文件 UI”。这将弹出一个新窗口。
“命令行参数”下的文本框是您可以添加要读取的图像路径的地方。确保用引号将其括起来。
这仅在您在 Visual Studio 中运行应用程序时有效。当您发布控制台应用程序或从命令提示符运行它时,您需要自己输入路径。
结果
我们现在结合了 Azure 计算机视觉和一些 C# 代码。所有这些代码和解释听起来都很棒,但它真的有效吗?当然!如果不行,请确保一切都正确(我知道您复制了代码并将其粘贴到您自己的项目中,如果您遵循了本文)。如果您发现问题,请在评论中告诉我,我会修复它。
但如果一切顺利,结果应该看起来像这样:
结论
有很多方法可以将图像转换为文本。我恰好懂 C# 和 Azure。将这两者结合起来,您就可以得到一个很棒的工具,可以从图像中获取文本。我相信其他语言也可以同样有效地工作,甚至可能更好。
仍然使用 C#。我也尝试过其他技术,但大多数都无法与 Azure 云的计算机视觉资源相媲美。我不是 Azure 云的粉丝,但这个效果非常好。
您只需要一个订阅、一个计算机视觉资源和一些代码。
在引言中,我说我想创建一个应用程序,可以减少在预算应用程序中添加成本时的一些手动“劳动”。本文并没有完全展示,因为还有很多工作要做。但这只是第一步。下一步是确定需要保存的区域。考虑金额、日期和描述。本文将很快跟进。
历史
- 2022 年 11 月 13 日:初始版本