Tesseract5+OpenCV4(VS2017+win10)实现OCR识别
Posted GreenOpen专注CV
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Tesseract5+OpenCV4(VS2017+win10)实现OCR识别相关的知识,希望对你有一定的参考价值。
一、环境配置
较之前采用cppan进行编译的方式,vcpkg的方式已经发生了许多变化,带来的最大不同就是便捷。
对于在NuGet中能够找到的Vcpkg的export,真的实现了开箱即用
这样的话对于普通用户来说就购了;而复杂的问题就交给专家来解决。
二、代码编写和结果展示
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <leptonica/allheaders.h>
#include <tesseract/baseapi.h>
#include <tesseract/publictypes.h>
using namespace cv;
using namespace cv::dnn;
using namespace std;
//对east的结果进行解码
void decode(const Mat& scores, const Mat& geometry, float scoreThresh,
std::vector<RotatedRect>& detections, std::vector<float>& confidences)
detections.clear();
CV_Assert(scores.dims == 4); CV_Assert(geometry.dims == 4); CV_Assert(scores.size[0] == 1);
CV_Assert(geometry.size[0] == 1); CV_Assert(scores.size[1] == 1); CV_Assert(geometry.size[1] == 5);
CV_Assert(scores.size[2] == geometry.size[2]); CV_Assert(scores.size[3] == geometry.size[3]);
const int height = scores.size[2];
const int width = scores.size[3];
for (int y = 0; y < height; ++y)
const float* scoresData = scores.ptr<float>(0, 0, y);
const float* x0_data = geometry.ptr<float>(0, 0, y);
const float* x1_data = geometry.ptr<float>(0, 1, y);
const float* x2_data = geometry.ptr<float>(0, 2, y);
const float* x3_data = geometry.ptr<float>(0, 3, y);
const float* anglesData = geometry.ptr<float>(0, 4, y);
for (int x = 0; x < width; ++x)
float score = scoresData[x];
if (score < scoreThresh)
continue;
// Decode a prediction.
// Multiple by 4 because feature maps are 4 time less than input image.
float offsetX = x * 4.0f, offsetY = y * 4.0f;
float angle = anglesData[x];
float cosA = std::cos(angle);
float sinA = std::sin(angle);
float h = x0_data[x] + x2_data[x];
float w = x1_data[x] + x3_data[x];
Point2f offset(offsetX + cosA * x1_data[x] + sinA * x2_data[x],
offsetY - sinA * x1_data[x] + cosA * x2_data[x]);
Point2f p1 = Point2f(-sinA * h, -cosA * h) + offset;
Point2f p3 = Point2f(-cosA * w, sinA * w) + offset;
RotatedRect r(0.5f * (p1 + p3), Size2f(w, h), -angle * 180.0f / (float)CV_PI);
detections.push_back(r);
confidences.push_back(score);
int main()
//参数和常量准备
String model = "F:/未来项目/GOCVHelper455/GOCVHelper455/GOCVHelper455/model/frozen_east_text_detection.pb";
std::vector<Mat> outs;
std::vector<String> outNames(2);
outNames[0] = "feature_fusion/Conv_7/Sigmoid";
outNames[1] = "feature_fusion/concat_3";
Mat blob;
std::vector<RotatedRect> boxes;
std::vector<float> confidences;
std::vector<int> indices;
char cbuf[255];
// 引入EAST model
Net net = readNet(model);
//对tesseract进行初始化操作
tesseract::TessBaseAPI tess;
if (tess.Init("C:/Program Files/Tesseract-OCR/tessdata", "eng"))
std::cout << "OCRTesseract: Could not initialize tesseract." << std::endl;
return 1;
tess.SetVariable("tessedit_char_whitelist", "0123456789");
Mat src = imread("F:/未来项目/OCR2023/2.jpg");
Mat board = src.clone();//用于显示图片
blobFromImage(src, blob, 1.0, Size(1280, 1280), Scalar(), true, false);//Scalar采用默认是设置
net.setInput(blob);
net.forward(outs, outNames);
Mat scores = outs[0];
Mat geometry = outs[1];
decode(scores, geometry, 0.5, boxes, confidences);//注意0.5是超参数
NMSBoxes(boxes, confidences, 0.5, 0.4, indices);
Point2f ratio((float)src.cols / 1280, (float)src.rows / 1280);//缩放比例
//获得最终框选结果
for (size_t i = 0; i < indices.size(); ++i)
RotatedRect& box = boxes[indices[i]];
Point2f vertices[4];
box.points(vertices);
for (int j = 0; j < 4; ++j)
vertices[j].x *= ratio.x;
vertices[j].y *= ratio.y;
Point2f* lastItemPointer = (vertices + sizeof vertices / sizeof vertices[0]);
vector<Point2f> contour(vertices, lastItemPointer);
Rect boundRect = boundingRect(Mat(contour));
//对rect适当进行扩充
boundRect = cv::Rect(boundRect.tl().x - 5, boundRect.tl().y, boundRect.width + 10, boundRect.height);
if (boundRect.y < src.rows)
Mat roi = src(boundRect);
//绘制外接边线
for (int j = 0; j < 4; ++j)
line(board, vertices[j], vertices[(j + 1) % 4], Scalar(0, 255, 0), 1);
rectangle(board, boundRect, Scalar(0, 0, 255));//绘制外接最小矩形
//打印数据
sprintf_s(cbuf, "F:/未来项目/OCR2023//roi/%d.jpg", i);//打印出来
imwrite(cbuf, roi);
////将切割出来的图片输入tesseract中
auto pixs = pixRead(cbuf);
if (!pixs)
std::cout << "Cannot open input file: " << std::endl;
return 1;
// recognize
tess.SetImage(pixs);
tess.Recognize(0);
// get result and delete[] returned char* string
std::cout << std::unique_ptr<char[]>(tess.GetUTF8Text()).get() << std::endl;
string strOut = tess.GetUTF8Text();
putText(board, std::unique_ptr<char[]>(tess.GetUTF8Text()).get(), boundRect.tl(), 1, 1.0f, Scalar(0, 255, 0));
// cleanup
tess.Clear();
pixDestroy(&pixs);
imshow("board", board);
imwrite("F:/未来项目/OCR2023/roi/result.jpg", board);
cv::waitKey();
getchar();
return 0;
三、代码编写和结果展示
这种环境配置方法以数量级的方式降低了环境配置的难度,而且“正好”有这样的一个可以使用的环境。其中:。
1、VCPKG是什么
VCPKG是微软 C++ 团队开发的适用于 C 和 C++ 库的跨平台开源软件包管理器,它大大简化了 Windows、Linux 和 macOS 上第三方库相关的下载和配置操作,目前已有超过1600个第三方库可以通过vcpkg来安装。
自动下载开源库源代码。一键安装第三方库。源码包的缓存管理和版本管理,可以依需求安装指定的版本。
自动检查库的依赖关系并安装其依赖项。
无缝集成Visual Studio,不用手动设置任何的库相关的路径。
Visual Studio全平台支持,不仅支持Debug/Release、x86/x64编译,还支持UWP、ARM平台的编译。
2、nuget
Nuget是一个.NET平台下的开源的项目,它是Visual Studio的扩展。在使用Visual Studio 或.NET CLI开发基于.NET 或.NET Framework的应用时,Nuget能把在项目中添加、移除和更新引用的工作变得更加快捷方便。
3、vcpkg导出NuGet
vcpkg export --nuget [options] <package>...
在 <output-dir>/<nuget-id>.<nuget-version>.nupkg创建 NuGet 包。
包含 标准集成文件 以及其他 MSBuild 集成,以支持通过 NuGet 包管理器 (.vcxproj) 包含在 MSBuild C++ 项目中。 请注意,不能将生成的 export 多个 NuGet 包混合在一起 -- 仅使用其中一个包。 若要添加其他库,必须创建包含完整依赖项集的新导出。
以上是关于Tesseract5+OpenCV4(VS2017+win10)实现OCR识别的主要内容,如果未能解决你的问题,请参考以下文章
OpenCV4机器学习:OpenCV4+VS2017环境搭建与配置