diff --git a/src/VizumCamera.cpp b/src/VizumCamera.cpp index 352efca..d6f0244 100755 --- a/src/VizumCamera.cpp +++ b/src/VizumCamera.cpp @@ -112,15 +112,11 @@ std::mutex& OutputRoiModeMutex() return mutex; } -class FullFrameRoiRestoreGuard +class OutputRoiModeRestoreGuard { public: - FullFrameRoiRestoreGuard(VZNLHANDLE deviceHandle, - const SVzNLROIRect& initialLeftROI, - const SVzNLROIRect& initialRightROI) - : m_guardDeviceHandle(deviceHandle), - m_initialLeftROI(initialLeftROI), - m_initialRightROI(initialRightROI) + explicit OutputRoiModeRestoreGuard(VZNLHANDLE deviceHandle) + : m_guardDeviceHandle(deviceHandle) { int queryError = 0; m_previousCalibRoi = VzNL_IsEnableCalibROI(m_guardDeviceHandle, &queryError); @@ -132,57 +128,24 @@ public: return; } - VzNL_SetOutputROIImage(VzTrue); - int ret = VzNL_EnableCalibROI(m_guardDeviceHandle, VzTrue); - if (ret != 0) { - char errorMsg[256] = {0}; - VzNL_GetErrorInfo(ret, errorMsg); - LOG_ERROR("[VizumCamera] Cannot enable CalibROI before configuring full-frame ROI: {} " - "(error code: {})", errorMsg, ret); - return; - } - m_restoreRequired = true; - - SVzVideoResolution resolution{}; - ret = VzNL_GetResolution(m_guardDeviceHandle, &resolution); - if (ret != 0 || resolution.nFrameWidth == 0 || resolution.nFrameHeight == 0) { - char errorMsg[256] = {0}; - VzNL_GetErrorInfo(ret, errorMsg); - LOG_ERROR("[VizumCamera] Cannot read full-frame resolution after enabling CalibROI: {} " - "(error code: {}), size={}x{}", - errorMsg, ret, resolution.nFrameWidth, resolution.nFrameHeight); - RestoreNow(); - return; - } - m_frameWidth = resolution.nFrameWidth; - m_frameHeight = resolution.nFrameHeight; - - SVzNLROIRect fullLeftROI{}; - fullLeftROI.right = m_frameWidth; - fullLeftROI.bottom = m_frameHeight; - SVzNLROIRect fullRightROI{}; - fullRightROI.right = m_frameWidth; - fullRightROI.bottom = m_frameHeight; - ret = VzNL_ConfigDetectROI(m_guardDeviceHandle, &fullLeftROI, &fullRightROI); - if (ret != 0) { - char errorMsg[256] = {0}; - VzNL_GetErrorInfo(ret, errorMsg); - LOG_ERROR("[VizumCamera] Cannot configure full-frame detection ROI: {} " - "(error code: {}), requested=[0, {}, 0, {}]", - errorMsg, ret, m_frameWidth, m_frameHeight); - RestoreNow(); - 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 raw full-frame capture: {} " + "(error code: {})", errorMsg, ret); + return; + } + m_calibRoiChanged = true; } + // 官方接口语义:VzFalse 输出完整原始图,检测/点云 ROI 不参与也不得改写。 + VzNL_SetOutputROIImage(VzFalse); + m_outputModeChanged = true; m_ready = true; - LOG_INFO("[VizumCamera] Temporary full-frame ROI configured through SDK: " - "left/right=[0, {}, 0, {}]; initial left=[{}, {}, {}, {}], " - "right=[{}, {}, {}, {}]", - m_frameWidth, m_frameHeight, - m_initialLeftROI.left, m_initialLeftROI.right, - m_initialLeftROI.top, m_initialLeftROI.bottom, - m_initialRightROI.left, m_initialRightROI.right, - m_initialRightROI.top, m_initialRightROI.bottom); + LOG_INFO("[VizumCamera] Full-frame 2D mode applied: CalibROI=false, " + "OutputROI=false; configured detection/point-cloud ROI untouched"); } bool IsReady() const @@ -190,89 +153,53 @@ public: return m_ready; } - unsigned int FrameWidth() const - { - return m_frameWidth; - } - - unsigned int FrameHeight() const - { - return m_frameHeight; - } - bool RestoreNow() { - if (m_restoreAttempted && m_restoreSucceeded) + if (m_restoreAttempted) return m_restoreSucceeded; m_restoreAttempted = true; - if (!m_restoreRequired) { + if (!m_outputModeChanged && !m_calibRoiChanged) { m_restoreSucceeded = true; return true; } + if (m_outputModeChanged) + VzNL_SetOutputROIImage(VzTrue); + m_restoreSucceeded = true; - int ret = VzNL_EnableCalibROI(m_guardDeviceHandle, VzFalse); - if (ret != 0) { - char errorMsg[256] = {0}; - VzNL_GetErrorInfo(ret, errorMsg); - LOG_ERROR("[VizumCamera] Failed to disable CalibROI before restoring initial ROI: {} " - "(error code: {})", errorMsg, ret); - m_restoreSucceeded = false; + 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; + } } - ret = VzNL_ConfigDetectROI(m_guardDeviceHandle, &m_initialLeftROI, &m_initialRightROI); - if (ret != 0) { - char errorMsg[256] = {0}; - VzNL_GetErrorInfo(ret, errorMsg); - LOG_ERROR("[VizumCamera] Failed to restore initial detection ROI: {} " - "(error code: {}), left=[{}, {}, {}, {}], right=[{}, {}, {}, {}]", - errorMsg, ret, - m_initialLeftROI.left, m_initialLeftROI.right, - m_initialLeftROI.top, m_initialLeftROI.bottom, - m_initialRightROI.left, m_initialRightROI.right, - m_initialRightROI.top, m_initialRightROI.bottom); - m_restoreSucceeded = false; - } - - 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 mode after full-frame capture: {} " - "(error code: {})", errorMsg, ret); - m_restoreSucceeded = false; - } - VzNL_SetOutputROIImage(VzTrue); - if (m_restoreSucceeded) { - LOG_INFO("[VizumCamera] Initial detection ROI restored after full-frame capture: " - "left=[{}, {}, {}, {}], right=[{}, {}, {}, {}], CalibROI={}", - m_initialLeftROI.left, m_initialLeftROI.right, - m_initialLeftROI.top, m_initialLeftROI.bottom, - m_initialRightROI.left, m_initialRightROI.right, - m_initialRightROI.top, m_initialRightROI.bottom, + LOG_INFO("[VizumCamera] ROI image mode restored: CalibROI={}, OutputROI=true; " + "configured detection/point-cloud ROI untouched", m_previousCalibRoi == VzTrue); } return m_restoreSucceeded; } - ~FullFrameRoiRestoreGuard() + ~OutputRoiModeRestoreGuard() { RestoreNow(); } - FullFrameRoiRestoreGuard(const FullFrameRoiRestoreGuard&) = delete; - FullFrameRoiRestoreGuard& operator=(const FullFrameRoiRestoreGuard&) = delete; + OutputRoiModeRestoreGuard(const OutputRoiModeRestoreGuard&) = delete; + OutputRoiModeRestoreGuard& operator=(const OutputRoiModeRestoreGuard&) = delete; private: VZNLHANDLE m_guardDeviceHandle = nullptr; - SVzNLROIRect m_initialLeftROI{}; - SVzNLROIRect m_initialRightROI{}; VzBool m_previousCalibRoi = VzFalse; - unsigned int m_frameWidth = 0; - unsigned int m_frameHeight = 0; - bool m_restoreRequired = false; + bool m_calibRoiChanged = false; + bool m_outputModeChanged = false; bool m_ready = false; bool m_restoreAttempted = false; bool m_restoreSucceeded = false; @@ -1120,25 +1047,13 @@ bool VizumCamera::CaptureFullFrameLeftImage(SLImage& image, return false; } - // Official SDK sample sequence starts by disabling CalibROI before - // reading the ROI that will be restored after the full-frame capture. - int ret = VzNL_EnableCalibROI(m_deviceHandle, VzFalse); - if (ret != 0) { - char errorMsg[256] = {0}; - VzNL_GetErrorInfo(ret, errorMsg); - LOG_ERROR("[VizumCamera] Official full-frame transaction cannot disable CalibROI " - "before reading initial ROI: {} (error code: {})", errorMsg, ret); - return false; - } - LOG_INFO("[VizumCamera] Official full-frame transaction baseline applied: CalibROI=false"); - const SVzNLROIRect expectedLeftROI{initialLeftROI.left, initialLeftROI.right, initialLeftROI.top, initialLeftROI.bottom}; const SVzNLROIRect expectedRightROI{initialRightROI.left, initialRightROI.right, initialRightROI.top, initialRightROI.bottom}; SVzNLROIRect currentLeftROI{}; SVzNLROIRect currentRightROI{}; - ret = VzNL_GetConfigDetectROI(m_deviceHandle, ¤tLeftROI, ¤tRightROI); + int ret = VzNL_GetConfigDetectROI(m_deviceHandle, ¤tLeftROI, ¤tRightROI); if (ret != 0) { char errorMsg[256] = {0}; VzNL_GetErrorInfo(ret, errorMsg); @@ -1150,7 +1065,7 @@ bool VizumCamera::CaptureFullFrameLeftImage(SLImage& image, if (!SameSdkRoi(currentLeftROI, expectedLeftROI) || !SameSdkRoi(currentRightROI, expectedRightROI)) { LOG_ERROR("[VizumCamera] Current ROI differs from the connection-time point-cloud ROI; " - "restoring expected state and rejecting this capture. current left=[{}, {}, {}, {}], " + "rejecting full-frame capture without writing camera ROI. current left=[{}, {}, {}, {}], " "right=[{}, {}, {}, {}]; expected left=[{}, {}, {}, {}], right=[{}, {}, {}, {}]", currentLeftROI.left, currentLeftROI.right, currentLeftROI.top, currentLeftROI.bottom, @@ -1160,63 +1075,19 @@ bool VizumCamera::CaptureFullFrameLeftImage(SLImage& image, expectedLeftROI.top, expectedLeftROI.bottom, expectedRightROI.left, expectedRightROI.right, expectedRightROI.top, expectedRightROI.bottom); - ret = VzNL_ConfigDetectROI(m_deviceHandle, &expectedLeftROI, &expectedRightROI); - const bool recoverySucceeded = ret == 0; - if (!recoverySucceeded) { - char errorMsg[256] = {0}; - VzNL_GetErrorInfo(ret, errorMsg); - LOG_ERROR("[VizumCamera] Failed to restore expected ROI while CalibROI=false: {} " - "(error code: {})", errorMsg, ret); - } - ret = VzNL_GetConfigDetectROI(m_deviceHandle, ¤tLeftROI, ¤tRightROI); - cameraStateRestored = recoverySucceeded && ret == 0 - && SameSdkRoi(currentLeftROI, expectedLeftROI) - && SameSdkRoi(currentRightROI, expectedRightROI); return false; } - FullFrameRoiRestoreGuard roiGuard(m_deviceHandle, expectedLeftROI, expectedRightROI); - if (!roiGuard.IsReady()) { - const bool restoreSucceeded = roiGuard.RestoreNow(); - ret = VzNL_GetConfigDetectROI(m_deviceHandle, ¤tLeftROI, ¤tRightROI); - cameraStateRestored = restoreSucceeded && ret == 0 - && SameSdkRoi(currentLeftROI, expectedLeftROI) - && SameSdkRoi(currentRightROI, expectedRightROI); - return false; - } - const unsigned int frameWidth = roiGuard.FrameWidth(); - const unsigned int frameHeight = roiGuard.FrameHeight(); + LOG_INFO("[VizumCamera] Point-cloud ROI snapshot verified before full-frame 2D capture: " + "left=[{}, {}, {}, {}], right=[{}, {}, {}, {}]", + currentLeftROI.left, currentLeftROI.right, + currentLeftROI.top, currentLeftROI.bottom, + currentRightROI.left, currentRightROI.right, + currentRightROI.top, currentRightROI.bottom); - SVzNLROIRect configuredLeftROI{}; - SVzNLROIRect configuredRightROI{}; - ret = VzNL_GetConfigDetectROI(m_deviceHandle, &configuredLeftROI, &configuredRightROI); - const auto isFullFrameRoi = [frameWidth, frameHeight](const SVzNLROIRect& roi) { - return roi.left == 0 && roi.top == 0 - && roi.right == static_cast(frameWidth) - && roi.bottom == static_cast(frameHeight); - }; - if (ret != 0 || !isFullFrameRoi(configuredLeftROI) || !isFullFrameRoi(configuredRightROI)) { - char errorMsg[256] = {0}; - VzNL_GetErrorInfo(ret, errorMsg); - LOG_ERROR("[VizumCamera] SDK full-frame ROI readback verification failed: {} " - "(error code: {}), left=[{}, {}, {}, {}], right=[{}, {}, {}, {}], " - "expected=[0, {}, 0, {}]", - errorMsg, ret, - configuredLeftROI.left, configuredLeftROI.right, - configuredLeftROI.top, configuredLeftROI.bottom, - configuredRightROI.left, configuredRightROI.right, - configuredRightROI.top, configuredRightROI.bottom, - frameWidth, frameHeight); - const bool restoreSucceeded = roiGuard.RestoreNow(); - ret = VzNL_GetConfigDetectROI(m_deviceHandle, ¤tLeftROI, ¤tRightROI); - cameraStateRestored = restoreSucceeded && ret == 0 - && SameSdkRoi(currentLeftROI, expectedLeftROI) - && SameSdkRoi(currentRightROI, expectedRightROI); + OutputRoiModeRestoreGuard outputModeGuard(m_deviceHandle); + if (!outputModeGuard.IsReady()) return false; - } - LOG_INFO("[VizumCamera] SDK full-frame ROI readback verified before 2D capture: " - "left/right=[0, {}, 0, {}]", - frameWidth, frameHeight); SVzNLImageData* leftImage = nullptr; SVzNLImageData* rightImage = nullptr; @@ -1239,18 +1110,16 @@ bool VizumCamera::CaptureFullFrameLeftImage(SLImage& image, const bool rightReleased = rightImageGuard.ReleaseNow(); const bool imagesReleased = leftReleased && rightReleased; + // OutputROI=false 返回原始全画幅;它与校正画布分辨率属于不同坐标空间。 const bool validFullFrame = converted && !image.empty() - && image.originX == 0 && image.originY == 0 - && image.width == frameWidth - && image.height == frameHeight; + && image.originX == 0 && image.originY == 0; if (converted && !validFullFrame) { - LOG_ERROR("[VizumCamera] Configured full-frame image contract failed: " - "image={}x{} origin=({}, {}), expected={}x{} origin=(0, 0)", - image.width, image.height, image.originX, image.originY, - frameWidth, frameHeight); + LOG_ERROR("[VizumCamera] Raw full-frame image has invalid payload/origin: " + "image={}x{} origin=({}, {})", + image.width, image.height, image.originX, image.originY); } - const bool initialRoiRestored = roiGuard.RestoreNow(); + const bool imageModesRestored = outputModeGuard.RestoreNow(); ret = VzNL_GetConfigDetectROI(m_deviceHandle, ¤tLeftROI, ¤tRightROI); const bool roiUnchanged = ret == 0 @@ -1262,7 +1131,7 @@ bool VizumCamera::CaptureFullFrameLeftImage(SLImage& image, LOG_ERROR("[VizumCamera] Failed to query detection ROI after full-frame capture: {} " "(error code: {})", errorMsg, ret); } else if (!roiUnchanged) { - LOG_ERROR("[VizumCamera] Detection ROI was not restored after full-frame capture; " + LOG_ERROR("[VizumCamera] Detection ROI changed during output-only full-frame capture; " "before left=[{}, {}, {}, {}], right=[{}, {}, {}, {}]; " "after left=[{}, {}, {}, {}], right=[{}, {}, {}, {}]", expectedLeftROI.left, expectedLeftROI.right, @@ -1282,7 +1151,7 @@ bool VizumCamera::CaptureFullFrameLeftImage(SLImage& image, currentRightROI.top, currentRightROI.bottom); } - cameraStateRestored = initialRoiRestored && roiUnchanged; + cameraStateRestored = imageModesRestored && roiUnchanged; if (!validFullFrame || !imagesReleased || !cameraStateRestored) { image.clear(); @@ -1291,8 +1160,8 @@ bool VizumCamera::CaptureFullFrameLeftImage(SLImage& image, const uint64_t id = ++m_frameCounter; frameId = "VZ_FULL_" + std::to_string(id); - LOG_INFO("[VizumCamera] Full-frame 2D transaction completed: " - "frameId={}, output={}x{} origin=(0, 0), initial ROI restored", + LOG_INFO("[VizumCamera] Full-frame 2D transaction completed without writing camera ROI: " + "frameId={}, output={}x{} origin=(0, 0), image modes restored", frameId, image.width, image.height); return true; #else