跳到主要内容

高性能SDK套件 - C++接口

信息

本文对应 dlcv_infer_cpp_dll 的 C++ 封装(dlcv_infer.h/.cpp),底层仍通过 dlcv_infer.dll 的 C 接口工作。

接口概览

namespace dlcv_infer
{
using json = nlohmann::json;

class Model
{
public:
int modelIndex = -1;
bool OwnModelIndex = true;

Model();
Model(const std::string& modelPath, int device_id);
virtual ~Model();

void FreeModel();
json GetModelInfo();

Result Infer(const cv::Mat& image, const json& params_json = nullptr);
Result InferBatch(const std::vector<cv::Mat>& image_list, const json& params_json = nullptr);

// 单张图输出 JSON:返回 sample_results[0].results(mask 会被转成轮廓点)
json InferOneOutJson(const cv::Mat& image, const json& params_json = nullptr);
};

class Utils
{
public:
static std::string JsonToString(const json& j);
static void FreeAllModels();
static json GetDeviceInfo();
static Result OcrInfer(Model& detectModel, Model& recognizeModel, const cv::Mat& image);
static json GetGpuInfo();
};
}

加载模型

接口定义:

dlcv_infer::Model::Model(const std::string& modelPath, int device_id)
  • modelPath,模型文件路径(传入参数编码是 GBK 编码,底层是 UTF-8 编码,会自动转换)
  • device_id,设备 id,如果有多张显卡,可以传入此参数,从 0 开始

样例代码:

#include "dlcv_infer.h"

int main()
{
std::string modelPath = R"(C:\Users\Administrator\Desktop\测试模型\det.dvt)";
int deviceId = 0;

dlcv_infer::Model model(modelPath, deviceId);
// ...
return 0;
}

获取模型信息

auto info = model.GetModelInfo();
std::cout << dlcv_infer::Utils::JsonToString(info) << std::endl;

模型推理

注意

彩色图像的通道顺序是 RGB。OpenCV imread 读出的默认是 BGR,需要自行转换:

cv::Mat bgr = cv::imread(R"(C:\Users\Administrator\Desktop\balloon.jpg)");
cv::Mat rgb;
cv::cvtColor(bgr, rgb, cv::COLOR_BGR2RGB);

接口定义:

dlcv_infer::Result Model::Infer(const cv::Mat& image, const dlcv_infer::json& params_json = nullptr);
dlcv_infer::Result Model::InferBatch(const std::vector<cv::Mat>& image_list, const dlcv_infer::json& params_json = nullptr);
dlcv_infer::json Model::InferOneOutJson(const cv::Mat& image, const dlcv_infer::json& params_json = nullptr);
  • params_json,额外推理参数,会合并到请求 JSON 中(例如传入 with_mask=false 时不返回 mask)

数据结构(C++封装结果):

struct ObjectResult {
int categoryId;
std::string categoryName;
float score;
float area;

bool withBbox;
std::vector<double> bbox; // 常见 [x,y,w,h];旋转框可能为 [cx,cy,w,h,angle]

bool withMask;
cv::Mat mask; // 0/255

bool withAngle;
float angle; // 弧度制(非旋转框一般为 -100)
};

struct SampleResult {
std::vector<ObjectResult> results;
};

struct Result {
std::vector<SampleResult> sampleResults;
};

样例代码(单张):

dlcv_infer::json params;
params["with_mask"] = false;

auto result = model.Infer(rgb, params);

样例代码(batch):

std::vector<cv::Mat> imgs = { rgb };
auto result = model.InferBatch(imgs);

样例代码(直接拿 JSON):

auto resultsJson = model.InferOneOutJson(rgb);
// resultsJson 是一个数组,对应 sample_results[0].results;mask 会被转成轮廓点数组

返回结果解析

  • sampleResults,列表,每个元素是一张图片的结果
  • results,列表,每个元素是一张图片中的物体
    • categoryId / categoryName / score / area
    • withBbox / bbox
    • withMask / mask(OpenCV Mat)
    • withAngle / angle(弧度制)

结果示例

内存管理

内存管理
  • Infer/InferBatch/InferOneOutJson 内部会自动调用 dlcv_free_model_result 释放底层返回结果指针,无需手动释放
  • Model 析构时默认释放底层模型;如果你复用/借用同一个 modelIndex,可将 OwnModelIndex=false 避免重复释放
  • 程序退出前可调用 dlcv_infer::Utils::FreeAllModels() 做一次全局释放(可选)

压力测试创建模型:

压力测试推理: