轻松学习C#:百度行驶证C++离线SDK接入详解

DotNet NB

共 22165字,需浏览 45分钟

 · 2024-04-21

效果

先看最终效果

SDK

拿到完整包如图,687M

解压后看看内容

发现有个readme.txt,那就先看看内容

1:用vs2015打开sln工程,最好用vs2015 comunity版本,可微软官网下载。
2:sdk的doc目录有pdf接口文档。
3:工程总入口main.cpp、请参考示例实现您的功能。
4:sdk支持windows x7、10等主流平台的64位模式。
5:工程不支持debug模式,请切换到Release x64。

做个听劝的人,不当犟拐拐,用VS2015打开工程看看

直接运行看看

LICENSE err!!!找销售要个测试的license先试试。

加入license以后,再运行试试。

封装DLL

下面开始动手封装一个DLL给C#调用

新建一个项目,起名DLSharp

附加包含目录

附加库目录

附加依赖项

opencv_world410.lib
ocr_vehiclecard_front.lib
ocr_vehiclecard_back.lib

定义头文件

#pragma once

#include "targetver.h"

#define WIN32_LEAN_AND_MEAN             // 从 Windows 头中排除极少使用的资料
// Windows 头文件: 
#include <windows.h>
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

// 初始化正页SDK授权
extern "C" _declspec(dllexport) int __stdcall dl_front_init_license(char* key, char* licenseFile, bool is_remote);

// 创建正页SDK实例
extern "C" _declspec(dllexport) void* __stdcall dl_front_create();

//正页SDK实例初始化
extern "C" _declspec(dllexport) int __stdcall dl_front_init(void* engine, char* ini_path);

//正页SDK识别
extern "C" _declspec(dllexport) int __stdcall dl_front_ocr(void* engine, char* image_path, char* ocr_result1, char* ocr_result2);

//正页SDK识别2
extern "C" _declspec(dllexport) int __stdcall dl_front_ocr2(void* engine, Mat* image, char* ocr_result1, char* ocr_result2);

//正页SDK释放
extern "C" _declspec(dllexport) void __stdcall dl_front_destroy(void* engine);

代码实现

#define _CRT_SECURE_NO_WARNINGS
#include "stdafx.h"

// TODO: 在 STDAFX.H 中引用任何所需的附加头文件,
//而不是在此文件中引用

#include <memory>

#include "dirent.h"
#include <sys/stat.h>
#include <fstream>
#include <string>
#include <fstream>
#include <io.h>
#include <codecvt>
#include <wchar.h>

#include "front/include/iocrgve_engine.h"
#include "front/include/response.h"
#include "front/include/DLL_API.h"

#include "back/include/iocrgve_engine.h"
#include "back/include/response.h"
#include "back/include/DLL_API.h"

// 初始化正页SDK授权
int __stdcall dl_front_init_license(char* key, char* licenseFile, bool is_remote)
{
 vis_vehiclecard_front::IOcrgveEngine::set_log(vis_vehiclecard_front::OFF_LOG, ""false);
 std::cout << "vis_vehiclecard_front key:" << key << std::endl;
 std::cout << "vis_vehiclecard_front licenseFile:" << licenseFile << std::endl;
 return (int)vis_vehiclecard_front::IOcrgveEngine::init_license(key, licenseFile, is_remote);
}

// 创建正页SDK实例
void* __stdcall dl_front_create() {
 vis_vehiclecard_front::IOcrgveEngine* engine = vis_vehiclecard_front::IOcrgveEngine::create();
 return engine;
}

//实例初始化
int __stdcall dl_front_init(void* engine, char* ini_path) {
 vis_vehiclecard_front::IOcrgveEngine* _engine = (vis_vehiclecard_front::IOcrgveEngine*)engine;
 return (int)_engine->init(ini_path);
}

//识别
int __stdcall dl_front_ocr(void* engine, char* image_path, char* ocr_result1, char* ocr_result2) {
 int res = 0;
 vis_vehiclecard_front::IOcrgveEngine* _engine = (vis_vehiclecard_front::IOcrgveEngine*)engine;
 std::cout << "image_path:" << image_path << std::endl;
 Mat input_mat;

 try {
  input_mat = imread(image_path, IMREAD_COLOR);
 }
 catch (...) {
  std::cout << "imread error" << std::endl;
  return -1;
 }

 return dl_front_ocr2(_engine, &input_mat, ocr_result1, ocr_result2);
}

//识别2
int __stdcall dl_front_ocr2(void* engine, Mat* image, char* ocr_result1, char* ocr_result2)
{
 int res = 0;
 vis_vehiclecard_front::IOcrgveEngine* _engine = (vis_vehiclecard_front::IOcrgveEngine*)engine;

 vis_vehiclecard_front::ImageFrame input_frame;
 input_frame._width = (*image).cols;
 input_frame._height = (*image).rows;
 input_frame._data = (uint8_t*)(*image).data;
 input_frame._fmt = vis_vehiclecard_front::IMAGE_PIX_FMT_BGR;

 std::vector<vis_vehiclecard_front::ImageFrame> frames;
 frames.push_back(input_frame);
 std::vector<vis_vehiclecard_front::general_vertical_kv_ret> ocrgvesdk_response;

 clock_t start, finish;
 double  duration;
 start = clock();
 res = _engine->process_ocrgvesdk(frames, vis_vehiclecard_front::IMAGE_ORIENTATION_UP, ocrgvesdk_response);
 finish = clock();
 duration = (double)(finish - start) / CLOCKS_PER_SEC;
 printf("img_process time: %2.1f ms\r\n", duration * 1000);
 if (res != vis_vehiclecard_front::SUCCESS) {
  return res;
 }

 std::string res_str("");
 std::string res_str2("");

 auto final_result = ocrgvesdk_response[0];
 int direction = 0;

 for (auto it : final_result.kv_content)
 {
  res_str += "\"" + it.first + "\":";

  res_str += "\"" + it.second[0].get_str() + "\"";
  res_str += ",";

  std::string str = ("{\"value\":\"") + it.second[0].get_str() + ("\",") +
   "\"coordinator\":\"" + std::to_string(it.second[0].get_coord()[0]) + (" ") +
   std::to_string(it.second[0].get_coord()[1]) + (" ") +
   std::to_string(it.second[0].get_coord()[2]) + (" ") +
   std::to_string(it.second[0].get_coord()[3]) + (" ") +
   std::to_string(it.second[0].get_coord()[4]) + (" ") +
   std::to_string(it.second[0].get_coord()[5]) + (" ") +
   std::to_string(it.second[0].get_coord()[6]) + (" ") +
   std::to_string(it.second[0].get_coord()[7]) + ("\"") +
   +",\"score\":\"" + std::to_string(it.second[0].get_det_score()) + "\"}";

  res_str2 = res_str2 + str.c_str();
  res_str2 += ",";

 }
 std::string res_header =
  "\"logid\":\"\",\"err_no\":0,\"err_msg\":\"SUCCESS\",\"querysign\":\"4188554259,1723708640\",\"image_dir\":\"" + std::to_string(direction) + "\",\"ret\":{";

 if (res_str.empty()) {
  return -1;
 }

 res_str.pop_back();
 res_str = "{" + res_header + res_str + "}}";

 const char *cstr = res_str.c_str();
 strcpy(ocr_result1, cstr);

 res_str2.erase(res_str2.length() - 1);
 res_str2 = "[" + res_str2 + "]";
 const char *cstr2 = res_str2.c_str();
 strcpy(ocr_result2, cstr2);

 return res;
}

//释放
void __stdcall dl_front_destroy(void* engine) {
 vis_vehiclecard_front::IOcrgveEngine* _engine = (vis_vehiclecard_front::IOcrgveEngine*)engine;
 _engine->uninit();
 vis_vehiclecard_front::IOcrgveEngine::destroy(&_engine);
}

编译生成

C#调用测试

新建项目

绘制界面、添加依赖等

拷贝生成的封装的DLSharp.dll及相关依赖到bin\x64\Release下

完整测试代码如下,测试效果见文章开头

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 FormTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        const string DllName = "DLSharp.dll";

        //行驶证正页

        [DllImport(DllName, EntryPoint = "dl_front_init_license", CallingConvention = CallingConvention.Cdecl)]
        internal extern static int dl_front_init_license(string key, string licenseFile, bool is_remote);

        [DllImport(DllName, EntryPoint = "dl_front_create", CallingConvention = CallingConvention.Cdecl)]
        internal extern static IntPtr dl_front_create();

        [DllImport(DllName, EntryPoint = "dl_front_init", CallingConvention = CallingConvention.Cdecl)]
        internal extern static int dl_front_init(IntPtr engine, string ini_path);

        [DllImport(DllName, EntryPoint = "dl_front_ocr", CallingConvention = CallingConvention.Cdecl)]
        internal extern static int dl_front_ocr(IntPtr engine, string image_path, StringBuilder ocr_result1, StringBuilder ocr_result2);

        [DllImport(DllName, EntryPoint = "dl_front_ocr2", CallingConvention = CallingConvention.Cdecl)]
        internal extern static int dl_front_ocr2(IntPtr engine, IntPtr image, StringBuilder ocr_result1, StringBuilder ocr_result2);

        [DllImport(DllName, EntryPoint = "dl_front_destroy", CallingConvention = CallingConvention.Cdecl)]
        internal extern static void dl_front_destroy(IntPtr engine);

        IntPtr front_engine;

        string image_path = "";

        private void Form1_Load(object sender, EventArgs e)
        {
            string key = "AISEE_xingshizheng_win_0530_3_3";
            string licenseFile = Application.StartupPath + "\\license\\license.ini";
            int res = -1;
            string ini_path = "";

            res = dl_front_init_license(key, licenseFile, false);
            Console.WriteLine(res.ToString());

            front_engine = dl_front_create();

            ini_path = Application.StartupPath + "\\resource\\vehiclecard_front_resource";
            res = dl_front_init(front_engine, ini_path);
            Console.WriteLine(res.ToString());

            image_path = Application.StartupPath + "\\front_images\\2.jpg";

            pictureBox1.Image = new Bitmap(image_path);
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            dl_front_destroy(front_engine);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (image_path == "")
            {
                return;
            }

            textBox1.Text = "";
            Application.DoEvents();

            StringBuilder ocr_result1 = new StringBuilder(1024);
            StringBuilder ocr_result2 = new StringBuilder(2048);
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            int res = dl_front_ocr(front_engine, image_path, ocr_result1, ocr_result2);
            //int res = dl_front_ocr2(front_engine, image.CvPtr, ocr_result1, ocr_result2);
            double totalTime = stopwatch.Elapsed.TotalSeconds;
            stopwatch.Stop();
            textBox1.Text += $"耗时: {totalTime:F2}s";
            textBox1.Text += "\r\n-------------------\r\n";
            Mat image = new Mat(image_path);

            if (res == 0)
            {
                Object jsonObject = JsonConvert.DeserializeObject(ocr_result1.ToString());
                textBox1.Text += JsonConvert.SerializeObject(jsonObject, Newtonsoft.Json.Formatting.Indented);

                textBox1.Text += "\r\n-------------------\r\n";

                Object jsonObject2 = JsonConvert.DeserializeObject(ocr_result2.ToString());
                textBox1.Text += JsonConvert.SerializeObject(jsonObject2, Newtonsoft.Json.Formatting.Indented);

                List<OcrRes2> lt = JsonConvert.DeserializeObject<List<OcrRes2>>(ocr_result2.ToString());

                foreach (OcrRes2 item in lt)
                {
                    string[] pts = item.coordinator.Split(' ');

                    //多边形的顶点
                    OpenCvSharp.Point[] points = new OpenCvSharp.Point[]
                    {
                        new OpenCvSharp.Point(Convert.ToDouble( pts[0]), Convert.ToDouble( pts[1])),
                        new OpenCvSharp.Point(Convert.ToDouble( pts[2]), Convert.ToDouble( pts[3])),
                        new OpenCvSharp.Point(Convert.ToDouble( pts[4]), Convert.ToDouble( pts[5])),
                        new OpenCvSharp.Point(Convert.ToDouble( pts[6]), Convert.ToDouble( pts[7])),
                    };

                    // 绘制多边形
                    Cv2.Polylines(image, new OpenCvSharp.Point[][] { points }, isClosed: true, color: new Scalar(0, 255, 0), thickness: 3);
                }
                if (pictureBox1.Image != null)
                {
                    pictureBox1.Image.Dispose();
                    pictureBox1.Image = null;
                }

                pictureBox1.Image = new Bitmap(image.ToMemoryStream());
                image.Dispose();
            }
            else
            {
                textBox1.Text = "识别失败";
            }
        }
    }

    public class OcrRes2
    {
        public OcrRes2(string value, string coordinator, double score)
        {
            this.value = value;
            this.coordinator = coordinator;
            this.score = score;
        }

        public string value { set; get; }
        public string coordinator { set; get; }
        public double score { set; get; }
    }
}

其他

至此,完成基本的封装调用,行驶证副页封装、调用同理可得。

看完啦,快去动手试试吧!

浏览 11
9点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
9点赞
评论
收藏
分享

手机扫一扫分享

举报