270 lines
11 KiB
C++
270 lines
11 KiB
C++
#ifndef __WOOD_POINTCLOUD_DETECTOR_INTERFACE_H__
|
||
#define __WOOD_POINTCLOUD_DETECTOR_INTERFACE_H__
|
||
|
||
// ============================================================
|
||
// 接口版本
|
||
// ============================================================
|
||
|
||
/// @brief 接口版本号
|
||
/// @details 每当接口发生不兼容变更(虚函数增删、签名修改、枚举值调整)时必须递增。
|
||
/// 调用方在加载插件后须先通过 WoodDetector_GetInterfaceVersion() 校验版本,
|
||
/// 版本不一致时禁止调用任何接口方法,否则将导致 vtable 错位崩溃。
|
||
#define WOOD_DETECTOR_INTERFACE_VERSION 1
|
||
|
||
// ============================================================
|
||
// 基础数据结构
|
||
// ============================================================
|
||
|
||
struct SVzPointXYZ {
|
||
float x;
|
||
float y;
|
||
float z;
|
||
};
|
||
|
||
// ============================================================
|
||
// 输入数据格式
|
||
// ============================================================
|
||
|
||
/// @brief 算法输入数据类型
|
||
enum EWoodInputDataType
|
||
{
|
||
kInputDataLaserLine = 0x01, ///< 单条激光线数据,对应 IWoodLaserLine
|
||
kInputDataPointCloud = 0x02, ///< 多条激光线累积的原始点云,对应 IWoodPointCloud
|
||
kInputDataRaster = 0x04, ///< 栅格化数据(点云投影到二维网格),对应 IWoodRasterData
|
||
};
|
||
|
||
/// @brief 点数据内存布局格式
|
||
/// @details 用于 getLineData() / getData() 返回数据时描述缓冲区的实际结构,
|
||
/// 调用方根据此值将 unsigned char* 转型为对应结构体进行访问。
|
||
enum EWoodPointDataType
|
||
{
|
||
kPointDataAlign32XYZ = 0x01, ///< 每点 32 字节对齐,包含 XYZ 三维坐标(float x, y, z + 填充)
|
||
kPointDataAlign32XYZRGBA = 0x02, ///< 每点 32 字节对齐,包含 XYZ 坐标及 RGBA 颜色(float x, y, z + uint8 r, g, b, a + 填充)
|
||
kPointDataIndexPositionD = 0x03, ///< 每点包含索引、位置及深度值(具体结构由实现定义)
|
||
};
|
||
|
||
/// @brief 算法输入数据基类接口
|
||
/// @details 所有输入数据类型均继承此接口,调用方通过 getDataType()
|
||
/// 判断实际类型后向下转型为具体接口使用。
|
||
class IWoodInputData
|
||
{
|
||
public:
|
||
virtual ~IWoodInputData() = default;
|
||
|
||
/// @brief 获取数据类型
|
||
/// @return 返回 EWoodInputDataType 中的一个值
|
||
virtual EWoodInputDataType getDataType() const = 0;
|
||
};
|
||
|
||
/// @brief 单条激光线数据接口(对应 kInputDataLaserLine)
|
||
/// @details 每次 detect() 传入一条激光线,算法逐行实时处理。
|
||
class IWoodLaserLine : public IWoodInputData
|
||
{
|
||
public:
|
||
virtual ~IWoodLaserLine() = default;
|
||
|
||
EWoodInputDataType getDataType() const override { return kInputDataLaserLine; }
|
||
|
||
/// @brief 获取当前激光线的点数据
|
||
/// @param pointType [out] 缓冲区的点数据格式
|
||
/// @param pointCount [out] 点数量
|
||
/// @return 返回数据缓冲区首地址,由 IWoodLaserLine 管理生命周期,调用方不需释放
|
||
virtual const unsigned char* getLineData(EWoodPointDataType& pointType, unsigned int& pointCount) = 0;
|
||
};
|
||
|
||
/// @brief 原始点云数据接口(对应 kInputDataPointCloud)
|
||
/// @details 通过多次调用 pushLaserLine() 累积激光线,
|
||
/// 形成完整的一帧点云后再传入 detect()。
|
||
class IWoodPointCloud : public IWoodInputData
|
||
{
|
||
public:
|
||
virtual ~IWoodPointCloud() = default;
|
||
|
||
EWoodInputDataType getDataType() const override { return kInputDataPointCloud; }
|
||
|
||
/// @brief 推入一条激光线数据
|
||
/// @param pointArray 点数组
|
||
/// @param pointCount 点数量
|
||
/// @return 返回错误码
|
||
virtual int pushLaserLine(SVzPointXYZ* pointArray, int pointCount) = 0;
|
||
|
||
/// @brief 获取当前累积的总点数
|
||
virtual unsigned int getTotalPointCount() const = 0;
|
||
|
||
/// @brief 获取当前累积的激光线数
|
||
virtual unsigned int getLaserLineCount() const = 0;
|
||
|
||
/// @brief 获取当前全部点云数据
|
||
/// @param pointType [out] 缓冲区的点数据格式
|
||
/// @param pointCount [out] 点数量
|
||
/// @return 返回数据缓冲区首地址,由 IWoodPointCloud 管理生命周期,调用方不需释放
|
||
virtual const unsigned char* getLineData(EWoodPointDataType& pointType, unsigned int& pointCount) const = 0;
|
||
};
|
||
|
||
/// @brief 栅格化数据接口(对应 kInputDataRaster)
|
||
/// @details 通过多次调用 pushLaserLine() 将激光线投影到二维网格,
|
||
/// 形成完整栅格后再传入 detect()。无效格元(无点云覆盖)填充零值。
|
||
class IWoodRasterData : public IWoodInputData
|
||
{
|
||
public:
|
||
virtual ~IWoodRasterData() = default;
|
||
|
||
EWoodInputDataType getDataType() const override { return kInputDataRaster; }
|
||
|
||
/// @brief 推入一条激光线数据,内部自动投影到栅格
|
||
/// @param pointArray 点数组
|
||
/// @param pointCount 点数量
|
||
/// @return 返回错误码
|
||
virtual int pushLaserLine(SVzPointXYZ* pointArray, int pointCount) = 0;
|
||
|
||
/// @brief 获取网格列数(X 方向)
|
||
virtual int getWidth() const = 0;
|
||
|
||
/// @brief 获取网格行数(Y 方向)
|
||
virtual int getHeight() const = 0;
|
||
|
||
/// @brief 获取栅格数据
|
||
/// @param pointType [out] 缓冲区的点数据格式,决定每个格元的数据结构
|
||
/// @return 返回 width * height 个格元的数据缓冲区首地址,按行优先(row-major)排列;
|
||
/// 由 IWoodRasterData 管理生命周期,调用方不需释放
|
||
virtual const unsigned char* getData(EWoodPointDataType& pointType) const = 0;
|
||
};
|
||
|
||
// ============================================================
|
||
// 检测结果
|
||
// ============================================================
|
||
|
||
/// @brief 检测结果基类接口
|
||
/// @details 各算法通过派生此接口返回具体检测结果,
|
||
/// 调用方可按需向下转型为具体结果类型。
|
||
class IWoodDetectResult
|
||
{
|
||
public:
|
||
virtual ~IWoodDetectResult() = default;
|
||
};
|
||
|
||
// ============================================================
|
||
// 算法检测器
|
||
// ============================================================
|
||
|
||
/// @brief 算法能力标志位,用于 getCapability() 返回值
|
||
enum EWoodDetectorCapability
|
||
{
|
||
kCapabilityUnknown = 0x00000000,
|
||
kCapabilityDefect = 0x00000001, ///< 支持缺陷检测
|
||
kCapabilityMeasurement = 0x00000002, ///< 支持尺寸测量
|
||
kCapabilityClassify = 0x00000004, ///< 支持分类识别
|
||
};
|
||
|
||
/// @brief 算法检测通用接口
|
||
class IWoodPointCloudDetector
|
||
{
|
||
public:
|
||
virtual ~IWoodPointCloudDetector() = default;
|
||
|
||
/// @brief 获取算法名称
|
||
virtual const char* getName() const = 0;
|
||
|
||
/// @brief 获取版本号
|
||
virtual const char* getVersion() const = 0;
|
||
|
||
/// @brief 获取算法能力标志位
|
||
/// @return 返回 EWoodDetectorCapability 各标志位的组合
|
||
virtual unsigned int getCapability() const = 0;
|
||
|
||
/// @brief 获取算法所需的输入数据格式
|
||
/// @return 返回 EWoodInputDataType 中的一个值;
|
||
/// 调用方须按此类型准备对应接口的数据并传入 detect()
|
||
virtual EWoodInputDataType getRequiredInputType() const = 0;
|
||
|
||
/// @brief 获取参数个数
|
||
/// @return 返回参数个数
|
||
virtual int getParamCount() const = 0;
|
||
|
||
/// @brief 按索引获取参数名和当前值
|
||
/// @param index 参数索引,范围 [0, getParamCount())
|
||
/// @param szParamName [out] 参数名缓冲区
|
||
/// @param nameLen szParamName 缓冲区大小(字节)
|
||
/// @param szValue [out] 参数值缓冲区
|
||
/// @param valueLen szValue 缓冲区大小(字节)
|
||
/// @return 返回错误码
|
||
virtual int getParam(int index, char* szParamName, int nameLen, char* szValue, int valueLen) const = 0;
|
||
|
||
/// @brief 按名称获取参数值
|
||
/// @param lpszParamName 参数名
|
||
/// @param szValue [out] 参数值缓冲区
|
||
/// @param valueLen szValue 缓冲区大小(字节)
|
||
/// @return 返回错误码
|
||
virtual int getParam(const char* lpszParamName, char* szValue, int valueLen) const = 0;
|
||
|
||
/// @brief 按名称设置参数值
|
||
/// @param lpszParamName 参数名
|
||
/// @param lpszValue 参数值
|
||
/// @return 返回错误码
|
||
virtual int setParam(const char* lpszParamName, const char* lpszValue) = 0;
|
||
|
||
/// @brief 执行检测
|
||
/// @param pInputData 输入数据,其类型须与 getRequiredInputType() 返回值一致,不可为空
|
||
/// @param ppIResult [out] 检测结果指针的指针;检测成功后写入结果地址,
|
||
/// 由算法实现管理生命周期,调用方不需释放;
|
||
/// 在下一次 detect() 或 clear() 调用后失效
|
||
/// @return 返回错误码
|
||
virtual int detect(IWoodInputData* pInputData, IWoodDetectResult** ppIResult) = 0;
|
||
|
||
/// @brief 清除检测状态
|
||
/// @details 若 detect() 依赖历史帧数据(如多帧积累),
|
||
/// 调用 clear() 将重置全部历史状态及检测结果
|
||
virtual void clear() = 0;
|
||
};
|
||
|
||
// ============================================================
|
||
// 插件导出规范(动态加载约定)
|
||
// ============================================================
|
||
//
|
||
// 插件 DLL 必须以 extern "C" 导出以下三个函数:
|
||
//
|
||
// [1] int WoodDetector_GetInterfaceVersion()
|
||
// 返回插件编译时使用的接口版本号(即 WOOD_DETECTOR_INTERFACE_VERSION)。
|
||
// 调用方加载 DLL 后必须首先调用此函数:
|
||
// - 若返回值 == 调用方的 WOOD_DETECTOR_INTERFACE_VERSION,方可继续使用;
|
||
// - 若不一致,必须立即卸载插件并上报错误,禁止调用后续任何接口。
|
||
//
|
||
// [2] IWoodPointCloudDetector* WoodDetector_Create()
|
||
// 创建并返回一个检测器实例。
|
||
// 调用方使用完毕后必须通过 WoodDetector_Destroy() 释放,
|
||
// 禁止直接 delete,以保证内存在同一模块内分配和释放。
|
||
//
|
||
// [3] void WoodDetector_Destroy(IWoodPointCloudDetector* pDetector)
|
||
// 销毁由 WoodDetector_Create() 创建的实例。
|
||
//
|
||
// 插件侧实现示例:
|
||
//
|
||
// extern "C" {
|
||
// int WoodDetector_GetInterfaceVersion() {
|
||
// return WOOD_DETECTOR_INTERFACE_VERSION;
|
||
// }
|
||
// IWoodPointCloudDetector* WoodDetector_Create() {
|
||
// return new CMyDetector();
|
||
// }
|
||
// void WoodDetector_Destroy(IWoodPointCloudDetector* p) {
|
||
// delete p;
|
||
// }
|
||
// }
|
||
//
|
||
// 调用方加载示例:
|
||
//
|
||
// typedef int (*FnGetVersion)();
|
||
// typedef IWoodPointCloudDetector* (*FnCreate)();
|
||
// typedef void (*FnDestroy)(IWoodPointCloudDetector*);
|
||
//
|
||
// HMODULE hDll = LoadLibrary("MyDetector.dll");
|
||
// FnGetVersion fnVer = (FnGetVersion)GetProcAddress(hDll, "WoodDetector_GetInterfaceVersion");
|
||
// if (!fnVer || fnVer() != WOOD_DETECTOR_INTERFACE_VERSION) {
|
||
// FreeLibrary(hDll);
|
||
// // 版本不匹配,拒绝加载
|
||
// }
|
||
// FnCreate fnCreate = (FnCreate)GetProcAddress(hDll, "WoodDetector_Create");
|
||
// IWoodPointCloudDetector* pDet = fnCreate();
|
||
|
||
#endif
|