使用 C++ 进行 OCR






4.90/5 (8投票s)
如何使用 C++ 和 libCurl 使用 OCR SDK
引言
在我们的日常开发中,我们需要对扫描图像、屏幕截图和其他形式或文件执行 OCR(光学字符识别)。我们寻找一个允许这样做的 SDK,并研究了 ABBYY Cloud OCR SDK。他们没有任何 C / C++ 代码示例,所以我不得不自己开发...
创建一个 ABBYY Cloud OCR 应用程序
创建并验证试用帐户后,需要执行以下步骤。
- 创建一个新的应用程序。
- 检查您的电子邮件以获取应用程序的密码。您将需要 应用程序 ID 和 应用程序密码 才能开始。
您应该在我们的代码中看到这两行占位符
#define APP_ID "<Your Application ID>"
#define PASSWORD "<Your Application Password"
将这些字符串替换为您分配的 应用程序 ID 和 应用程序密码。
启动 libCurl
首先,我们启动 Curl 对象
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
处理输入文件
我们的输入文件可以是任何图像,甚至可以是 PDF 文件。我们需要将其转换为 mime,为此,我们调用
<a href="https://curl.se/libcurl/c/curl_mime_init.html">curl_mime_init()</a>
接下来,我们在请求中生成上传部分
field = curl_mime_addpart(form);
curl_mime_name(field, "upload");
并使用 curl_mine_filedata() 生成文件数据,该函数用于从我们的输入文件的内容设置我们的 mime 部分的主体数据。
curl_mime_filedata(field, file_to_upload.c_str());
现在,我们通过调用 curl_easy_setopt() 设置选项,顾名思义,该函数用于准备设置我们的请求的选项。
我们需要以下属性
PROCESSING_URL
是 Abbyy SDK 提供的 URL。headerlist
之前已设置。form
是上传部分。APP_ID
是 Abbyy SDK 为我们开发的每个软件提供的特定于应用程序的标识符。PASSWORD
是应用程序的密码,需要生成。CURLOPT_WRITEFUNCTION
是一个回调函数,用于写入请求的结果。数据被写入readBuffer
,它将保存我们从 API 收到的结果。
curl_easy_setopt(curl, CURLOPT_URL, PROCESSING_URL);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
curl_easy_setopt(curl, CURLOPT_MIMEPOST, form);
curl_easy_setopt(curl, CURLOPT_USERNAME, APP_ID);
curl_easy_setopt(curl, CURLOPT_PASSWORD, PASSWORD);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWrite_CallbackFunc_StdString);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
然后,我们准备好执行我们的请求。我们调用 curl_easy_perform()。
res = curl_easy_perform(curl);
之后,我们立即检查结果。
检查结果
接下来,我们获得分配给每个 OCR 任务的 Task_ID
。您可以启动多个任务,然后等待每个任务完成。我们使用获得的 Task_ID
来检查任务的状态并等待它完成。
while (1)
{
res = curl_easy_perform(status_curl);
if (res != CURLE_OK)
{
WriteLogFile(L"Error: %S", curl_easy_strerror(res));
}
else
{
WriteLogFile(L"Read Buffer:\n%S", readBuffer.c_str());
task_status = ObtainStatus(readBuffer);
WriteLogFile(L"task_status: %S", task_status.c_str());
}
if (task_status != "Completed")
{
//wait 5s before next check
Sleep(2000);
}
else
{
setcolor(LOG_COLOR_DARKGREEN, 0);
SetConsoleTitle(L"OCR completed");
setcolor(LOG_COLOR_WHITE, 0);
result_url = ObtainURL(readBuffer);
//replace all & to &
result_url = ReplaceAll(result_url, "&", "&");
//downloading text file of response
WriteLogFile(L"Downloading File from URL: %S", result_url.c_str());
op_curl = curl_easy_init();
if (op_curl)
{
headerlist = curl_slist_append(headerlist, buf);
curl_easy_setopt(op_curl, CURLOPT_URL, result_url.c_str());
curl_easy_setopt(op_curl, CURLOPT_HTTPHEADER, headerlist);
curl_easy_setopt(op_curl, CURLOPT_HTTPGET, 1L);
FILE* wfd = fopen(json_result_file.c_str(), "ab");
fprintf(wfd, "\n");
curl_easy_setopt(op_curl, CURLOPT_WRITEDATA, wfd);
curl_easy_perform(op_curl);
curl_easy_cleanup(op_curl);
fclose(wfd);
WriteLogFile(L"FILE saved");
}
break;
}
readBuffer = "";
} // While
现在,一旦我们有了结果,我们就清理所有东西。
这是一个程序工作原理的视频演示
构建块
该项目的关键构建块之一是 libCurl。我将它用作 static
库。 *.lib* 文件包含在文章的源代码中,但是您可以在 此处 阅读有关将 libCurl
用作 static
库的信息。
注意:WriteLogFile()
是我之前在 这篇文章中描述的旧日志记录函数之一。
Using the Code
您可以使用不同的导出格式。 有关选项,请参阅 此 链接。
您可以定义您期望使用的语言。 有关选项,请阅读 此 链接。
您可以使用多种语言,其中大多数也可以作为手写文本 (ICR)。 您可以在 PROCESSING_URL string
中设置预期语言的列表。
在此示例中,我们期望英语和希伯来语
#define PROCESSING_URL
"https://cloud-westus.ocrsdk.com/processImage?exportFormat=txt&language=English,Hebrew"
历史
- 2021 年 1 月 30 日:初始版本