WoodAlgo/Core/CoreAPI/IWoodPointCloudDetector.h
2026-03-11 00:04:01 +08:00

270 lines
11 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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