diff --git a/src/VizumCamera.cpp b/src/VizumCamera.cpp index f079ee6..4676f06 100755 --- a/src/VizumCamera.cpp +++ b/src/VizumCamera.cpp @@ -119,20 +119,74 @@ std::mutex& OutputRoiModeMutex() class OutputRoiModeRestoreGuard { public: - OutputRoiModeRestoreGuard() + explicit OutputRoiModeRestoreGuard(VZNLHANDLE deviceHandle) + : m_guardDeviceHandle(deviceHandle) { + int queryError = 0; + m_previousCalibRoi = VzNL_IsEnableCalibROI(m_guardDeviceHandle, &queryError); + if (queryError != 0) { + char errorMsg[256] = {0}; + VzNL_GetErrorInfo(queryError, errorMsg); + LOG_ERROR("[VizumCamera] Cannot query CalibROI before full-frame capture: {} " + "(error code: {})", errorMsg, queryError); + return; + } + + if (m_previousCalibRoi == VzTrue) { + const int ret = VzNL_EnableCalibROI(m_guardDeviceHandle, VzFalse); + if (ret != 0) { + char errorMsg[256] = {0}; + VzNL_GetErrorInfo(ret, errorMsg); + LOG_ERROR("[VizumCamera] Cannot disable CalibROI for true full-frame pixels: {} " + "(error code: {})", errorMsg, ret); + return; + } + m_calibRoiChanged = true; + } + VzNL_SetOutputROIImage(VzFalse); - LOG_INFO("[VizumCamera] SDK image output switched to full-frame mode; detection ROI unchanged"); + m_outputModeChanged = true; + m_ready = true; + LOG_INFO("[VizumCamera] Full-frame 2D mode applied: CalibROI=false, " + "OutputROI=false; configured detection ROI and point-cloud ROI unchanged"); } - void RestoreNow() + bool IsReady() const { - if (m_restored) - return; + return m_ready; + } - VzNL_SetOutputROIImage(VzTrue); - m_restored = true; - LOG_INFO("[VizumCamera] SDK image output restored to configured-ROI mode"); + bool RestoreNow() + { + if (m_restoreAttempted) + return m_restoreSucceeded; + + m_restoreAttempted = true; + if (!m_outputModeChanged && !m_calibRoiChanged) { + m_restoreSucceeded = true; + return true; + } + + if (m_outputModeChanged) + VzNL_SetOutputROIImage(VzTrue); + + m_restoreSucceeded = true; + if (m_calibRoiChanged) { + const int ret = VzNL_EnableCalibROI(m_guardDeviceHandle, m_previousCalibRoi); + if (ret != 0) { + char errorMsg[256] = {0}; + VzNL_GetErrorInfo(ret, errorMsg); + LOG_ERROR("[VizumCamera] Failed to restore CalibROI after full-frame capture: {} " + "(error code: {})", errorMsg, ret); + m_restoreSucceeded = false; + } + } + + if (m_restoreSucceeded) { + LOG_INFO("[VizumCamera] ROI detection image mode restored: CalibROI={}, " + "OutputROI=true", m_previousCalibRoi == VzTrue); + } + return m_restoreSucceeded; } ~OutputRoiModeRestoreGuard() @@ -144,7 +198,13 @@ public: OutputRoiModeRestoreGuard& operator=(const OutputRoiModeRestoreGuard&) = delete; private: - bool m_restored = false; + VZNLHANDLE m_guardDeviceHandle = nullptr; + VzBool m_previousCalibRoi = VzFalse; + bool m_calibRoiChanged = false; + bool m_outputModeChanged = false; + bool m_ready = false; + bool m_restoreAttempted = false; + bool m_restoreSucceeded = false; }; class SdkImageReleaseGuard @@ -1006,7 +1066,9 @@ bool VizumCamera::CaptureFullFrameLeftImage(SLImage& image, std::string& frameId return false; } - OutputRoiModeRestoreGuard outputModeGuard; + OutputRoiModeRestoreGuard outputModeGuard(m_deviceHandle); + if (!outputModeGuard.IsReady()) + return false; SVzNLImageData* leftImage = nullptr; SVzNLImageData* rightImage = nullptr; @@ -1041,7 +1103,7 @@ bool VizumCamera::CaptureFullFrameLeftImage(SLImage& image, std::string& frameId resolution.nFrameWidth, resolution.nFrameHeight); } - outputModeGuard.RestoreNow(); + const bool imageModesRestored = outputModeGuard.RestoreNow(); SVzNLROIRect currentLeftROI{}; SVzNLROIRect currentRightROI{}; @@ -1073,15 +1135,16 @@ bool VizumCamera::CaptureFullFrameLeftImage(SLImage& image, std::string& frameId currentRightROI.top, currentRightROI.bottom); } - if (!exactFullFrame || !imagesReleased || !roiUnchanged) { + if (!exactFullFrame || !imagesReleased || !imageModesRestored || !roiUnchanged) { image.clear(); return false; } const uint64_t id = ++m_frameCounter; frameId = "VZ_FULL_" + std::to_string(id); - LOG_INFO("[VizumCamera] Full-frame capture completed without writing detection ROI: frameId={}, " - "output={}x{} origin=(0, 0)", frameId, image.width, image.height); + LOG_INFO("[VizumCamera] True full-frame 2D capture completed without writing detection ROI: " + "frameId={}, output={}x{} origin=(0, 0), CalibROI restored", + frameId, image.width, image.height); return true; #else return false; diff --git a/src/VizumCamera.h b/src/VizumCamera.h index 90c45ee..e36eecc 100755 --- a/src/VizumCamera.h +++ b/src/VizumCamera.h @@ -128,11 +128,11 @@ public: bool GetRightImage(SLImage& image); /** - * @brief 不修改检测 ROI,仅切换 SDK 输出模式采集全幅左目图像 + * @brief 不修改检测 ROI,临时关闭 CalibROI/ROI输出并采集真实全幅左目图像 * @param[out] image SDK 原始返回的设备全分辨率图像(原点必须为(0,0)) * @param[out] frameId 本次采集帧编号 - * @return 采集、SDK 图像释放、精确全幅校验、输出模式恢复及检测 ROI 未变化校验是否全部成功 - * @note 保持当前 CalibROI 和检测 ROI 不变;任何失败路径都会恢复 ROI 图输出模式 + * @return 采集、SDK 图像释放、精确全幅校验、模式恢复及检测 ROI 未变化校验是否全部成功 + * @note 检测 ROI 始终只读;任何失败路径都会恢复原 CalibROI 和 ROI 图输出模式 */ bool CaptureFullFrameLeftImage(SLImage& image, std::string& frameId);