paddlepaddle(二) 文字识别 PaddleOCR C++部署

本文章记录,如何将PaddleOCR应用到window下的C++项目中,实现利用摄像头实时显示输出,上述即为实际的检测效果。看得出来,对不同大小语言文字检测性能都还不错。

主要过程包括:①PaddleOCR的编译,②VS2019的属性配置,③cpp文件修改用来显示图像

一、PaddleOCR编译

官方给出在VS中cmake,https://gitee.com/paddlepaddle/PaddleOCR/blob/release/2.0/deploy/cpp_infer/docs/windows_vs2019_build.md

本文采用cmake-gui中进行编译。

1.1 这里需要准备好3种资源

①PaddleOCR源码:https://github.com/PaddlePaddle/PaddleOCR

PaddlePaddle C++ 预测库 fluid_inference:https://www.paddlepaddle.org.cn/documentation/docs/en/guides/05_inference_deployment/inference/windows_cpp_inference_en.html

③OpenCV,用于读图、画图等操作

1.2 cmake

配置好cmake选项,congfigure,generate。

1.3 编译生成

二、新建PaddleOCR项目进行预测

2.1 新建项目

新建VS2019项目,将PaddleOCR源文件和头文件(见下图)全部添加到项目中。并配置项目属性。

2.2 PaddleOCR项目的配置文件

2.2.1 加载OCR预测模型

下载链接https://github.com/PaddlePaddle/PaddleOCR,此处用的是mobile形式的。

config.txt将作为项目main.cpp的输入参数,务必将文件中的模型文件路径填写正确。

2 main.cpp修改

修改部分见代码,主要包括输入参数、摄像头取帧、识别文字标记边界。

int main()
{
	OCRConfig config("D:/E/z_pp/config.txt");

	config.PrintConfigInfo();

	DBDetector det(config.det_model_dir, config.use_gpu, config.gpu_id,
		config.gpu_mem, config.cpu_math_library_num_threads,
		config.use_mkldnn, config.max_side_len, config.det_db_thresh,
		config.det_db_box_thresh, config.det_db_unclip_ratio,
		config.visualize, config.use_tensorrt, config.use_fp16);

	Classifier* cls = nullptr;
	if (config.use_angle_cls == true) {
		cls = new Classifier(config.cls_model_dir, config.use_gpu, config.gpu_id,
			config.gpu_mem, config.cpu_math_library_num_threads,
			config.use_mkldnn, config.cls_thresh,
			config.use_tensorrt, config.use_fp16);
	}

	CRNNRecognizer rec(config.rec_model_dir, config.use_gpu, config.gpu_id,
		config.gpu_mem, config.cpu_math_library_num_threads,
		config.use_mkldnn, config.char_list_file,
		config.use_tensorrt, config.use_fp16);

	cv::Mat srcimg;
	VideoCapture capture;
	capture.open(0, CAP_DSHOW);
	while (capture.read(srcimg))
	{
		//auto start = std::chrono::system_clock::now();
		std::vector<std::vector<std::vector<int>>> boxes;	//vector: [][0](x1,y1),  [][1](x2,y1),  [][2](x2,y2),[][3](x1,y2), 顺时针四个角
		det.Run(srcimg, boxes);

		rec.Run(boxes, srcimg, cls);
		//auto end = std::chrono::system_clock::now();
		//auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
		//std::cout << "Cost  "
		//	<< double(duration.count()) *
		//	std::chrono::microseconds::period::num /
		//	std::chrono::microseconds::period::den
		//	<< "s" << std::endl;

		for (int i = 0; i < boxes.size(); i++)
		{
			printf("%d %d %d %d\n", boxes[i][0][0], boxes[i][0][1], boxes[i][2][0], boxes[i][2][1]);

			line(srcimg, Point(boxes[i][0][0], boxes[i][0][1]), Point(boxes[i][1][0], boxes[i][1][1]), Scalar(0, 255, 0), 3);
			line(srcimg, Point(boxes[i][1][0], boxes[i][1][1]), Point(boxes[i][2][0], boxes[i][2][1]), Scalar(0, 255, 0), 3);
			line(srcimg, Point(boxes[i][2][0], boxes[i][2][1]), Point(boxes[i][3][0], boxes[i][3][1]), Scalar(0, 255, 0), 3);
			line(srcimg, Point(boxes[i][3][0], boxes[i][3][1]), Point(boxes[i][0][0], boxes[i][0][1]), Scalar(0, 255, 0), 3);
		}

		cv::imshow("PaddleOCR", srcimg);
		char ch = waitKey(1);	if (ch == 27)break;
	}

	return 0;
}

系列之(一)

paddlepaddle(一)文字识别 - PaddleOCR简单使用

  • 4
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然可以!以下是一个简单的PaddleOCR C++部署代码示例: ```cpp #include <iostream> #include <vector> #include <chrono> #include <opencv2/opencv.hpp> #include <paddle_api.h> using namespace std::chrono; int main() { // 加载模型 paddle::lite_api::MobileConfig config; config.set_model_from_file("path/to/model"); config.set_threads(1); config.set_power_mode(paddle::lite_api::PowerMode::LITE_POWER_HIGH); paddle::lite_api::MobilePredictor predictor(config); // 读取图像 cv::Mat img = cv::imread("path/to/image"); if (img.empty()) { std::cerr << "Failed to read image!" << std::endl; return -1; } // 图像预处理 cv::Mat input; cv::cvtColor(img, input, cv::COLOR_BGR2RGB); cv::resize(input, input, cv::Size(640, 640), 0, 0, cv::INTER_LINEAR); input.convertTo(input, CV_32FC3, 1.f / 255.f); paddle::lite_api::Tensor input_tensor; input_tensor.Resize({1, 3, input.rows, input.cols}); auto* input_data = input_tensor.mutable_data<float>(); memcpy(input_data, input.ptr<float>(), input.total() * sizeof(float)); // 执行推理 paddle::lite_api::Tensor output_tensor; predictor.Run({input_tensor}, {&output_tensor}); // 解析结果 auto* output_data = output_tensor.data<float>(); std::vector<std::vector<int>> boxes; std::vector<std::vector<std::string>> texts; int output_size = output_tensor.numel(); for (int i = 0; i < output_size / 6; ++i) { float* data = output_data + i * 6; std::vector<int> box = {static_cast<int>(data[0] * img.cols), static_cast<int>(data[1] * img.rows), static_cast<int>(data[2] * img.cols), static_cast<int>(data[3] * img.rows)}; std::vector<std::string> text; for (int j = 0; j < 5; ++j) { text.push_back(std::to_string(data[j + 5])); } boxes.push_back(box); texts.push_back(text); } // 打印结果 for (size_t i = 0; i < boxes.size(); ++i) { std::cout << "Box: "; for (const auto& point : boxes[i]) { std::cout << point << " "; } std::cout << "Text: "; for (const auto& t : texts[i]) { std::cout << t << " "; } std::cout << std::endl; } return 0; } ``` 请注意,上述代码仅为示例,你需要根据你的具体环境和模型进行适当的修改和配置。此外,你还需要安装相关的依赖项和头文件,并将模型文件和图像路径替换为正确的路径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值