#pragma once #include "IStructuredLightCamera.h" #include #include #include /** * @file VizumCamera.h * @brief 伟景智能 Vizum 结构光相机封装类 * * 基于 VzNLSDK 封装,实现 IStructuredLightCamera 接口。 * 伟景相机是一款基于双目+激光扫描的3D相机。 */ namespace StructuredLight { struct ROIRect { int left = 0; int right = 0; int top = 0; int bottom = 0; }; /** * @brief 伟景智能 Vizum 结构光相机实现类 */ class VizumCamera : public IStructuredLightCamera { public: VizumCamera(); ~VizumCamera() override; // 禁用拷贝 VizumCamera(const VizumCamera&) = delete; VizumCamera& operator=(const VizumCamera&) = delete; // ======================================================================== // IStructuredLightCamera 接口实现 - 基本操作 // ======================================================================== std::string GetSDKVersion() const override; SLCameraBrand GetBrand() const override { return SLCameraBrand::Vizum; } bool SearchCameras(std::vector& deviceList) override; bool Connect(const std::string& ipAddress) override; void Disconnect() override; bool IsConnected() const override; bool GetDeviceInfo(SLDeviceInfo& info) override; // ======================================================================== // IStructuredLightCamera 接口实现 - 同步采集 // ======================================================================== bool TriggerCapture(std::string& frameId, CaptureType captureType = CaptureType::All) override; bool GetImage(const std::string& frameId, SLImage& image) override; bool GetPointCloud(const std::string& frameId, PointCloud& cloud) override; bool GetPointCloudRaw(const std::string& frameId, float* buffer, size_t bufferSize) override; bool GetPointCloudVector(const std::string& frameId, std::vector& data) override; bool GetDepthMap(const std::string& frameId, DepthMap& depthMap) override; bool GetDepthMapRaw(const std::string& frameId, float* buffer, size_t bufferSize) override; bool CaptureFrame(FrameData& frameData, CaptureType captureType = CaptureType::All) override; // ======================================================================== // IStructuredLightCamera 接口实现 - 异步采集(预留) // ======================================================================== bool StartAsyncCapture(FrameCallback callback, CaptureType captureType = CaptureType::All) override; void StopAsyncCapture() override; bool IsAsyncCapturing() const override; // ======================================================================== // IStructuredLightCamera 接口实现 - 相机参数 // ======================================================================== bool GetCameraMatrix(CameraMatrix& matrix) override; bool GetCameraMatrixVector(std::vector& matrix) override; bool GetDistortionCoeffs(DistortionCoeffs& coeffs) override; bool GetDistortionCoeffsVector(std::vector& coeffs) override; // ======================================================================== // IStructuredLightCamera 接口实现 - 配置 // ======================================================================== bool GetIntParam(const std::string& name, int& value) override; bool SetIntParam(const std::string& name, int value) override; bool GetFloatParam(const std::string& name, float& value) override; bool SetFloatParam(const std::string& name, float value) override; bool GetStringParam(const std::string& name, std::string& value) override; bool SetStringParam(const std::string& name, const std::string& value) override; bool GetConfig(std::string& configJson) override; bool SetConfig(const std::string& configJson) override; // ======================================================================== // 伟景相机特有方法 // ======================================================================== /** * @brief 初始化SDK(全局只需调用一次) * @return 是否成功 */ static bool InitSDK(); /** * @brief 销毁SDK(程序退出时调用) */ static void DestroySDK(); /** * @brief 获取左目图像 * @param[out] image 输出图像 * @return 是否成功 */ bool GetLeftImage(SLImage& image); /** * @brief 获取右目图像 * @param[out] image 输出图像 * @return 是否成功 */ bool GetRightImage(SLImage& image); /** * @brief 临时把左右检测 ROI 配置为全幅,采集左目全图后恢复初始 ROI * @param[out] image SDK 返回的矫正全幅左目图(尺寸等于设备分辨率,原点必须为(0,0)) * @param[out] frameId 本次采集帧编号 * @param[in] initialLeftROI 连接时缓存的左目点云 ROI,也是唯一恢复目标 * @param[in] initialRightROI 连接时缓存的右目点云 ROI,也是唯一恢复目标 * @param[out] cameraStateRestored 返回前是否确认初始 ROI、CalibROI 和输出模式均已恢复 * @return 全幅 ROI 配置、采集、SDK 图像释放、初始 ROI 恢复及校验是否全部成功 * @note 该事务按 SDK 官方示例调用 ConfigDetectROI;任何失败路径都会尝试恢复初始左右 ROI */ bool CaptureFullFrameLeftImage(SLImage& image, std::string& frameId, const ROIRect& initialLeftROI, const ROIRect& initialRightROI, bool& cameraStateRestored); /** * @brief 启用/禁用矫正 ROI 图像输出(VzNL_EnableCalibROI) * @param enable true=启用;启用后 GetLeftImage/GetRightImage 返回 SDK 矫正图 * @return 是否成功 * @note 需在 Connect 成功后调用 */ bool SetCalibROIEnabled(bool enable); /** * @brief 读取当前左右目检测 ROI,不修改相机配置 * @param[out] leftROI 左目检测 ROI(全幅图坐标) * @param[out] rightROI 右目检测 ROI(全幅图坐标) * @return 是否成功 */ bool GetDetectROI(ROIRect& leftROI, ROIRect& rightROI); /** * @brief 启动自动检测模式进行摆镜扫描采集点云 * @param[out] pointCloud 输出点云 * @param[in] timeoutMs 超时时间(毫秒),默认3000ms * @return 是否成功 * @note 此方法用于静态场景,通过摆镜扫描累积点云 * @note 重写基类方法 */ bool CapturePointCloudWithAutoDetect(PointCloud& pointCloud, int timeoutMs = 3000) override; /** * @brief 获取累积的扫描线数据(用于保存点云文件) * @return 扫描线数据,每条扫描线包含一组3D点 */ std::vector> GetAccumulatedScanLines(); /** * @brief 清除累积的扫描线数据 */ void ClearAccumulatedScanLines(); private: struct Impl; friend struct VizumCameraCallbackHooks; // SDK初始化状态 static std::atomic s_sdkInitialized; static std::mutex s_sdkMutex; // 内部辅助方法 bool UpdateDeviceInfo(); bool CaptureAndCacheData(CaptureType captureType); bool ConvertVzImageToSLImage(void* vzImage, SLImage& slImage); void HandleAutoOutputLaserLine(int dataType, void* laserLinePoint); void HandleDeviceStatusChange(int status); void ConvertLaserLineDataToPointCloud(void* laserLinePoint); std::unique_ptr m_impl; }; SLCameraPtr CreateVizumCamera(); } // namespace StructuredLight