目录
注释掉main.cpp内全部内容,将下面内容替换进去。ppocr.h需要再环境配置中包含进去头文件
注意这些dll一个也不能少。生成dll后,重新在vs中新建一个C++项目
需要更改输出目录,添加连接器,并将项目里需要的内容一并放入输出目录中
paddeocr用cmake编译生成exe请查阅我的另一篇博客,这里只看如何在exe的基础上生成dll
借鉴博主:
准备版本:release2.5
编译完成后修改内容:
新建ppocr.h头文件
#pragma once
#include <vector>
#include <string>
#ifndef IMAGE_API
#define IMAGE_API
struct TextDetectionResult {
std::vector<std::vector<int>> boxes;
};
struct TextRecognitionResult {
std::string text;
double score;
};
extern "C" {
// 图像推理
__declspec(dllexport) void ImageProcess(const char* image_dir, TextDetectionResult*** detection_results, int* num_detection_results,
TextRecognitionResult*** recognition_results, int* num_recognition_results);
/*__declspec(dllexport) void FreeMemory(TextDetectionResult** detection_results, int num_detection_results,
TextRecognitionResult** recognition_results, int num_recognition_results);*/
}
#endif
注释掉main.cpp内全部内容,将下面内容替换进去。ppocr.h需要再环境配置中包含进去头文件
#include <iostream>
#include <include/paddleocr.h>
#include <include/args.h>
#include "ppocr.h"
using namespace PaddleOCR;
// 处理图片的函数
void ImageProcess(const char* image_dir, TextDetectionResult*** detection_results, int* num_detection_results,
TextRecognitionResult*** recognition_results, int* num_recognition_results)
{
std::cout << "--------" << image_dir << "-------" << std::endl;
std::string dir(image_dir);
std::replace(dir.begin(), dir.end(), '/', '\\');
std::cout << "--------" << dir << "-------" << std::endl;
std::vector<cv::String> cv_all_img_names;
cv::glob(image_dir, cv_all_img_names);
std::cout << "total images num: " << cv_all_img_names.size() << endl;
PPOCR ocr = PPOCR();
std::cout << "begin process" << std::endl;
std::vector<std::vector<OCRPredictResult>> ocr_results = ocr.ocr(cv_all_img_names, FLAGS_det, FLAGS_rec, FLAGS_cls);
std::cout << "finish process" << std::endl;
auto ocr_result = ocr_results[0];
std::vector<TextDetectionResult> detectionResults;
std::vector<TextRecognitionResult> recognitionResults;
for (int i = 0; i < ocr_result.size(); i++) {
if (ocr_result[i].score != -1.0) {
TextDetectionResult detectionResult;
detectionResult.boxes = ocr_result[i].box;
TextRecognitionResult recognitionResult;
recognitionResult.text = ocr_result[i].text;
recognitionResult.score = ocr_result[i].score;
detectionResults.push_back(detectionResult);
recognitionResults.push_back(recognitionResult);
}
}
*num_detection_results = detectionResults.size();
*detection_results = new TextDetectionResult * [*num_detection_results];
for (int i = 0; i < *num_detection_results; i++) {
(*detection_results)[i] = new TextDetectionResult(detectionResults[i]);
}
*num_recognition_results = recognitionResults.size();
*recognition_results = new TextRecognitionResult * [*num_recognition_results];
for (int i = 0; i < *num_recognition_results; i++) {
(*recognition_results)[i] = new TextRecognitionResult(recognitionResults[i]);
}
std::cout << "in the end" << std::endl;
if (*num_recognition_results == 0) {
std::cout << "result is null" << std::endl;
}
///*c*/onst char* img_dir = "E:\paddlepaddle\projects\PaddleOCR-release-2.5\deploy\cpp_infer\qt_project\qt4ocr\imgs\1.jpg";
cv::Mat srcimg = cv::imread(dir, cv::IMREAD_COLOR);
if (!srcimg.data) {
std::cerr << "[ERROR] image read failed! image path: "
<< endl;
exit(1);
}
std::string file_name = Utility::basename(image_dir);
Utility::VisualizeBboxes(srcimg, ocr_results[0],
FLAGS_output + file_name);
std::cout << "***************************" << endl;
}
void FreeMemory(TextDetectionResult** detection_results, int num_detection_results,
TextRecognitionResult** recognition_results, int num_recognition_results)
{
for (int i = 0; i < num_detection_results; i++) {
delete detection_results[i];
}
delete[] detection_results;
for (int i = 0; i < num_recognition_results; i++) {
delete recognition_results[i];
}
delete[] recognition_results;
}
然后更改配置信息,将exe换成dll
随后右击重新编译会在根目录生成dll,lib文件。
注意这些dll一个也不能少。生成dll后,重新在vs中新建一个C++项目
内容如下:
#include <iostream>
#include <vector>
#include <string>
#include <Windows.h>
struct TextDetectionResult {
std::vector<std::vector<int>> boxes;
};
struct TextRecognitionResult {
std::string text;
double score;
};
typedef void (*ImageProcessFunc)(const char* image_dir, TextDetectionResult*** detection_results, int* num_detection_results,
TextRecognitionResult*** recognition_results, int* num_recognition_results);
void FreeMemory(TextDetectionResult** detection_results, int num_detection_results,
TextRecognitionResult** recognition_results, int num_recognition_results)
{
for (int i = 0; i < num_detection_results; i++) {
delete detection_results[i];
}
delete[] detection_results;
for (int i = 0; i < num_recognition_results; i++) {
delete recognition_results[i];
}
delete[] recognition_results;
}
int main()
{
system("chcp 65001");
const char* image_dir = "C:\\Users\\lenovo\\source\\repos\\test_dll\\test_dll//1234.jpg";
const char* dll_path = "C:\\Users\\lenovo\\source\\repos\\test_dll\\test_dll/ppocr.dll";
HMODULE hModule = LoadLibraryA(dll_path);
if (hModule == NULL) {
std::cout << "Failed to load the DLL." << std::endl;
return 1;
}
ImageProcessFunc ImageProcess = (ImageProcessFunc)GetProcAddress(hModule, "ImageProcess");
if (ImageProcess == NULL) {
std::cout << "Failed to get the function address." << std::endl;
FreeLibrary(hModule);
return 1;
}
TextDetectionResult** detection_results = nullptr;
int num_detection_results = 0;
TextRecognitionResult** recognition_results = nullptr;
int num_recognition_results = 0;
ImageProcess(image_dir, &detection_results, &num_detection_results, &recognition_results, &num_recognition_results);
if (num_detection_results > 0) {
std::cout << "get the result" << std::endl;
for (int i = 0; i < num_detection_results; i++) {
std::vector<std::vector<int>> boxes = detection_results[i]->boxes;
std::cout << "det boxes: [";
for (int n = 0; n < boxes.size(); n++) {
std::cout << '[' << boxes[n][0] << ',' << boxes[n][1] << "]";
if (n != boxes.size() - 1) {
std::cout << ',';
}
}
std::string recognitionResult = recognition_results[i]->text;
std::cout << "] " << " " << " recognition text : " << recognitionResult << std::endl;
}
}
std::cout << "begin clear" << std::endl;
// 释放内存
FreeMemory(detection_results, num_detection_results, recognition_results, num_recognition_results);
// 卸载 DLL
FreeLibrary(hModule);
std::cout << "clear over" << std::endl;
return 0;
}
相关的配置如下:
需要更改输出目录,添加连接器,并将项目里需要的内容一并放入输出目录中
结果展示:
结语:
只提供解决方案,非无偿解答问题。
===================2024.4.28日修改==============
新增release2.7版本修改内容
mian.cpp内容 2.7及以后版本 ocr.ocr函数内容传参变为img_list, FLAGS_det, FLAGS_rec, FLAGS_cls。 所以将mian函数修改一下重新定义一个img_list 这个团队的源码里面也有。其他与之前的内容保持一致。
#include <iostream>
#include <include/paddleocr.h>
#include <include/args.h>
#include "ooccrr.h"
using namespace PaddleOCR;
// 处理图片的函数
void ImageProcess(const char* image_dir, TextDetectionResult*** detection_results, int* num_detection_results,
TextRecognitionResult*** recognition_results, int* num_recognition_results)
{
std::cout << "--------" << image_dir << "-------" << std::endl;
std::string dir(image_dir);
std::replace(dir.begin(), dir.end(), '/', '\\');
std::cout << "--------" << dir << "-------" << std::endl;
std::vector<cv::String> cv_all_img_names;
cv::glob(image_dir, cv_all_img_names);
std::cout << "total images num: " << cv_all_img_names.size() << std::endl;
PPOCR ocr = PPOCR();
std::cout << "begin process" << std::endl;
//PPOCR::ocr(std::vector<cv::Mat> img_list, bool det, bool rec, bool cls)
std::vector<cv::Mat> img_list;
std::vector<cv::String> img_names;
for (int i = 0; i < cv_all_img_names.size(); ++i) {
cv::Mat img = cv::imread(cv_all_img_names[i], cv::IMREAD_COLOR);
if (!img.data) {
std::cerr << "[ERROR] image read failed! image path: "
<< cv_all_img_names[i] << std::endl;
continue;
}
img_list.push_back(img);
img_names.push_back(cv_all_img_names[i]);
}
std::vector<std::vector<OCRPredictResult>> ocr_results = ocr.ocr(img_list, FLAGS_det, FLAGS_rec, FLAGS_cls);
std::cout << "finish process" << std::endl;
auto ocr_result = ocr_results[0];
std::vector<TextDetectionResult> detectionResults;
std::vector<TextRecognitionResult> recognitionResults;
for (int i = 0; i < ocr_result.size(); i++) {
if (ocr_result[i].score != -1.0) {
TextDetectionResult detectionResult;
detectionResult.boxes = ocr_result[i].box;
TextRecognitionResult recognitionResult;
recognitionResult.text = ocr_result[i].text;
recognitionResult.score = ocr_result[i].score;
detectionResults.push_back(detectionResult);
recognitionResults.push_back(recognitionResult);
}
}
*num_detection_results = detectionResults.size();
*detection_results = new TextDetectionResult * [*num_detection_results];
for (int i = 0; i < *num_detection_results; i++) {
(*detection_results)[i] = new TextDetectionResult(detectionResults[i]);
}
*num_recognition_results = recognitionResults.size();
*recognition_results = new TextRecognitionResult * [*num_recognition_results];
for (int i = 0; i < *num_recognition_results; i++) {
(*recognition_results)[i] = new TextRecognitionResult(recognitionResults[i]);
}
std::cout << "in the end" << std::endl;
if (*num_recognition_results == 0) {
std::cout << "result is null" << std::endl;
}
///*c*/onst char* img_dir = "E:\paddlepaddle\projects\PaddleOCR-release-2.5\deploy\cpp_infer\qt_project\qt4ocr\imgs\1.jpg";
cv::Mat srcimg = cv::imread(dir, cv::IMREAD_COLOR);
if (!srcimg.data) {
std::cerr << "[ERROR] image read failed! image path: "
<< std::endl;
exit(1);
}
std::string file_name = Utility::basename(image_dir);
Utility::VisualizeBboxes(srcimg, ocr_results[0],
FLAGS_output + file_name);
std::cout << "***************************" << std::endl;
}
void FreeMemory(TextDetectionResult** detection_results, int num_detection_results,
TextRecognitionResult** recognition_results, int num_recognition_results)
{
for (int i = 0; i < num_detection_results; i++) {
delete detection_results[i];
}
delete[] detection_results;
for (int i = 0; i < num_recognition_results; i++) {
delete recognition_results[i];
}
delete[] recognition_results;
}