PP-OCRv5 C++封装DLL C#调用源码分享

360影视 动漫周边 2025-06-02 11:40 2

摘要:头文件#include #include #include #include using namespace std;using namespace cv;//o

说明

C++封装DLL,C#调用源码分享

效果

C#调用效果

项目

C#

C++

头文件#include
#include
#include
#include

using namespace std;
using namespace cv;

//ocr 初始化
extern "C" _declspec(dllexport) int __cdecl init(void** engine
, int cpu_threads
, bool enable_mkldnn

, char* det_model_dir
, int limit_side_len
, double det_db_thresh
, double det_db_box_thresh
, double det_db_unclip_ratio
, bool use_dilation

, bool cls
, bool use_angle_cls
, char* cls_model_dir
, double cls_thresh
, double cls_batch_num

, char* rec_model_dir
, char* rec_char_dict_path
, int rec_batch_num
, int rec_img_h
, int rec_img_w

, char* msg);

//识别
extern "C" _declspec(dllexport) int __cdecl ocr(void* engine, Mat * image, char* msg, char** ocr_result, int* ocr_result_len);

//释放
extern "C" _declspec(dllexport) int __cdecl destroy(void* engine, char* msg);

//structure 初始化
extern "C" _declspec(dllexport) int __cdecl structure_init(void** engine

, int cpu_threads
, bool enable_mkldnn

, int limit_side_len

, bool use_dilation

, bool cls
, bool use_angle_cls

, double cls_thresh

, int rec_batch_num
, int rec_img_h
, int rec_img_w

, int table_max_len
, int table_batch_num
, char* table_model_dir
, char* table_char_dict_path

, char* msg);

//structure
extern "C" _declspec(dllexport) int __cdecl structure(void* engine, Mat * image, char* msg, char** ocr_result, int* ocr_result_len);

//释放
extern "C" _declspec(dllexport) int __cdecl structure_destroy(void* engine, char* msg);

源文件#define _CRT_SECURE_NO_WARNINGS

#include "pch.h"
#include


#include "src/json.cpp"
#include
#include
#include

using json = nlohmann::json;
using namespace PaddleOCR;

#include
#include
#include



//初始化
int __cdecl init(void** engine

, int cpu_threads
, bool enable_mkldnn

, char* det_model_dir
, int limit_side_len
, double det_db_thresh
, double det_db_box_thresh
, double det_db_unclip_ratio
, bool use_dilation

, bool cls
, bool use_angle_cls
, char* cls_model_dir
, double cls_thresh
, double cls_batch_num

, char* rec_model_dir
, char* rec_char_dict_path
, int rec_batch_num
, int rec_img_h
, int rec_img_w

, char* msg) {

try {

FLAGS_cpu_threads = cpu_threads;
FLAGS_enable_mkldnn = enable_mkldnn;
FLAGS_visualize =false;

//det
FLAGS_det_model_dir = det_model_dir;
FLAGS_limit_side_len = limit_side_len;
FLAGS_det_db_thresh = det_db_thresh;
FLAGS_det_db_box_thresh = det_db_box_thresh;
FLAGS_det_db_unclip_ratio = det_db_unclip_ratio;
FLAGS_use_dilation = use_dilation;

//cls
FLAGS_cls = cls;
FLAGS_use_angle_cls = use_angle_cls;
FLAGS_cls_model_dir = cls_model_dir;
FLAGS_cls_thresh = cls_thresh;
FLAGS_cls_batch_num = cls_batch_num;

//rec
FLAGS_rec_model_dir = rec_model_dir;
FLAGS_rec_char_dict_path = rec_char_dict_path;
FLAGS_rec_batch_num = rec_batch_num;
FLAGS_rec_img_h = rec_img_h;
FLAGS_rec_img_w = rec_img_w;

PPOCR* _engine = new PPOCR;

*engine = _engine;

strcpy_s(msg, 128, "init success");

return0;
}
catch (...) {
std::cout << "init error" << std::endl;
strcpy_s(msg, 128, "init error");
return-1;
}

}

//识别
int __cdecl ocr(void* engine, Mat* image, char* msg, char** ocr_result, int* ocr_result_len) {
if(engine == ptr)
{
strcpy_s(msg, 128, "engine is ptr");
return-1;
}

PPOCR* _engine = (PPOCR*)engine;

//auto start = std::chrono::steady_clock::now;
std::vector OCRPredictResult = _engine->ocr(*image,truetrue, FLAGS_cls);
//auto end = std::chrono::steady_clock::now;
//std::chrono::duration duration = end - start;
//std::cout << "ocr识别耗时 : " << duration.count << " ms" << std::endl;

//返回json格式
json array = json::array;
for(int i = 0; i < OCRPredictResult.size; i++) {
json texts = {};

texts["text"] = OCRPredictResult[i].text;
texts["score"] = OCRPredictResult[i].score;

texts["x1"] = OCRPredictResult[i].box[0][0];
texts["y1"] = OCRPredictResult[i].box[0][1];

texts["x2"] = OCRPredictResult[i].box[1][0];
texts["y2"] = OCRPredictResult[i].box[1][1];

texts["x3"] = OCRPredictResult[i].box[2][0];
texts["y3"] = OCRPredictResult[i].box[2][1];

texts["x4"] = OCRPredictResult[i].box[3][0];
texts["y4"] = OCRPredictResult[i].box[3][1];

array.push_back(texts);
}

std::string json_str = array.dump;
*ocr_result_len = (int)json_str.size;
*ocr_result = (char*)CoTaskMemAlloc(*ocr_result_len + 1);
strcpy_s(*ocr_result, *ocr_result_len + 1, json_str.c_str);

strcpy_s(msg, 128, "ocr success");
return0;
}

//释放
int __cdecl destroy(void* engine, char* msg) {
if(engine != ptr)
{

delete _engine;
_engine = ptr;
strcpy_s(msg, 128, "destroy success");
return0;
}
else
{

return-1;
}
}

//structure
int __cdecl structure_init(void** engine

, int cpu_threads
, bool enable_mkldnn

, int limit_side_len

, bool use_dilation

, bool cls
, bool use_angle_cls

, double cls_thresh

, int rec_batch_num
, int rec_img_h
, int rec_img_w

, int table_max_len
, int table_batch_num
, char* table_model_dir
, char* table_char_dict_path

, char* msg) {

try {

FLAGS_visualize =false;

//det

//cls
FLAGS_cls = cls;

//rec

FLAGS_table =true;
FLAGS_table_model_dir = table_model_dir;
FLAGS_table_char_dict_path = table_char_dict_path;
FLAGS_table_max_len = table_max_len;
FLAGS_table_batch_num = table_batch_num;

PaddleStructure* _engine = new PaddleStructure;

*engine = _engine;

strcpy_s(msg, 128, "structure_init success");

return0;
}
catch (...) {
std::cout << "structure_init error" << std::endl;
strcpy_s(msg, 128, "structure_init error");
return-1;
}
}

//structure
int __cdecl structure(void* engine, Mat* image, char* msg, char** ocr_result, int* ocr_result_len) {

if(engine == ptr)
{
strcpy_s(msg, 128, "structure engine is ptr");
return-1;
}

PaddleStructure* _engine = (PaddleStructure*)engine;

std::vector structure_results = _engine->structure(
*image, FLAGS_layout, FLAGS_table, FLAGS_det && FLAGS_rec);

for(size_t j = 0; j < structure_results.size; ++j) {

json structure = {};

structure["type"] = structure_results[j].type;
structure["x1"] = structure_results[j].box[0];
structure["y1"] = structure_results[j].box[1];
structure["x2"] = structure_results[j].box[2];
structure["y2"] = structure_results[j].box[3];
structure["confidence"] = structure_results[j].confidence;
structure["res"] = structure_results[j].html;

array.push_back(structure);
}

strcpy_s(msg, 128, "structure success");
return0;

}

//释放
int __cdecl structure_destroy(void* engine, char* msg) {
if(engine != ptr)
{

delete _engine;
_engine = ptr;
strcpy_s(msg, 128, "structure destroy success");
return0;
}
else
{

return-1;
}
}

using Newtonsoft.Json;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

namespace OCRV5Test
{
public partial class Form1 : Form
{
publicForm1
{
InitializeComponent;
}

const string DllName = "lw.PPOCRSharp.dll";

//初始化
[DllImport(DllName, EntryPoint = "init", CallingConvention = CallingConvention.Cdecl)]
public extern static int init(ref IntPtr engine
, int cpu_threads
, bool enable_mkldnn

, string det_model_dir
, int limit_side_len
, double det_db_thresh
, double det_db_box_thresh
, double det_db_unclip_ratio
, bool use_dilation

, bool cls
, bool use_angle_cls
, string cls_model_dir
, double cls_thresh
, double cls_batch_num

, string rec_model_dir
, string rec_char_dict_path
, int rec_batch_num
, int rec_img_h
, int rec_img_w

, StringBuilder msg);

//识别
[DllImport(DllName, EntryPoint = "ocr", CallingConvention = CallingConvention.Cdecl)]
public extern static int ocr(IntPtr engine, IntPtr image, StringBuilder msg, out IntPtr ocr_result, out int ocr_result_len);

//释放
[DllImport(DllName, EntryPoint = "destroy", CallingConvention = CallingConvention.Cdecl)]
public extern static int destroy(IntPtr engine, StringBuilder msg);

static IntPtr OCREngine;

private Bitmap bmp;

private String imgPath = ;

private List ltOCRResult;

private string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tif;*.png";

private StringBuilder OCRResultInfo = new StringBuilder;
private StringBuilder OCRResultAllInfo = new StringBuilder;

Pen pen = new Pen(Brushes.Red, 2f);

private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog;
ofd.Filter = fileFilter;
if(ofd.ShowDialog == DialogResult.OK)
{
imgPath = ofd.FileName;
bmp = new Bitmap(imgPath);
pictureBox1.Image = bmp;
richTextBox1.Clear;

button2_Click;
}
}

private void button2_Click(object sender, EventArgs e)
{
if(imgPath == )
{
return;
}
button1.Enabled =false;
button2.Enabled =false;
richTextBox1.Clear;
OCRResultInfo.Clear;
OCRResultAllInfo.Clear;

Application.DoEvents;
Mat img = new Mat(imgPath);
StringBuilder msgTemp = new StringBuilder(128);
StringBuilder ocrResultStr = new StringBuilder(1024 * 100);

Stopwatch stopwatch = new Stopwatch;
stopwatch.Start;

IntPtr strPtr;
int ocr_result_len = 0;

int res = ocr(OCREngine, img.CvPtr, msgTemp, out strPtr, out ocr_result_len);
byte buffer = new byte[ocr_result_len];
Marshal.Copy(strPtr, buffer, 0, ocr_result_len);
string ocr_result = Encoding.UTF8.GetString(buffer);
Marshal.FreeCoTaskMem(strPtr);
stopwatch.Stop;
double totalTime = stopwatch.Elapsed.TotalSeconds;

OCRResultAllInfo.AppendLine($"耗时: {totalTime:F2}s");
OCRResultAllInfo.AppendLine("");

OCRResultInfo.AppendLine($"耗时: {totalTime:F2}s");
OCRResultInfo.AppendLine("");

if(res == 0)
{

ltOCRResult = Newtonsoft.Json.JsonConvert.DeserializeObject>(ocr_result);
OCRResultAllInfo.Append(JsonConvert.SerializeObject(ltOCRResult, Newtonsoft.Json.Formatting.Indented));
Graphics graphics = Graphics.FromImage(bmp);

foreach (OCRResult iteminltOCRResult)
{
OCRResultInfo.AppendLine(item.text);
System.Drawing.Point pt = new System.Drawing.Point {
new System.Drawing.Point(item.x1, item.y1)
, new System.Drawing.Point(item.x2, item.y2)
, new System.Drawing.Point(item.x3, item.y3)
, new System.Drawing.Point(item.x4, item.y4)
};
graphics.DrawPolygon(pen, pt);
}
graphics.Dispose;

if(checkBox1.Checked)
{
richTextBox1.Text = OCRResultAllInfo.ToString;
}
else
{
richTextBox1.Text = OCRResultInfo.ToString;
}

pictureBox1.Image = ;

}
else
{
MessageBox.Show("识别失败," + msgTemp.ToString);
}

img.Release;
button1.Enabled =true;
button2.Enabled =true;
}

///
/// 初始化
///
///


///


private void Form1_Load(object sender, EventArgs e)
{
radioButton1.Checked =true;
}

voidLoadModel
{

string root_dir = Application.StartupPath + @"\inference";

int cpu_threads = 2 ;
bool enable_mkldnn =true;

string det_model_dir = "";
int limit_side_len = 960;
double det_db_thresh = 0.3;
double det_db_box_thresh = 0.6;
double det_db_unclip_ratio = 1.2;
bool use_dilation =false;

bool cls =false;
bool use_angle_cls =true;
string cls_model_dir = root_dir + @"\ch_ppocr_mobile_v2.0_cls_infer\";
double cls_thresh = 0.9;
int cls_batch_num = 1;

string rec_model_dir = "";
string rec_char_dict_path = root_dir + @"\ppocrv5_dict.txt";
int rec_batch_num = 1;
int rec_img_h = 48;
int rec_img_w = 320;

if (radioButton1.Checked)
{
det_model_dir = root_dir + @"\PP-OCRv5_mobile_det_infer\";
rec_model_dir = root_dir + @"\PP-OCRv5_mobile_rec_infer\";
}
else
{
det_model_dir = root_dir + @"\PP-OCRv5_server_det_infer\";
rec_model_dir = root_dir + @"\PP-OCRv5_server_rec_infer\";
}
int res = init(ref OCREngine
, cpu_threads
, enable_mkldnn

, det_model_dir
, limit_side_len
, det_db_thresh
, det_db_box_thresh
, det_db_unclip_ratio
, use_dilation

, cls
, use_angle_cls
, cls_model_dir
, cls_thresh
, cls_batch_num

, rec_model_dir
, rec_char_dict_path
, rec_batch_num
, rec_img_h
, rec_img_w

, msgTemp);

if (res == 0)
{
MessageBox.Show("模型加载成功!");
}
else
{
string msg = msgTemp.ToString;
MessageBox.Show("模型加载失败," + msg);
}
}

private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
richTextBox1.Clear;
if (checkBox1.Checked)
{

}
else
{

}
}

private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
RadioButton rb = sender as RadioButton;
if (rb != && rb.Checked)
{
//MessageBox.Show("选中的是:" + rb.Text);
LoadModel;
}
}

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{

destroy(OCREngine, msgTemp);
}
}

}
PP-OCRv5 Test C#调用完整项目源码.rar
pwd=n79z 提取码: n79z

来源:opendotnet

相关推荐