From 8b4c1486df0b253f869b90a2d4c5714571d928dc Mon Sep 17 00:00:00 2001 From: Ben <987807597@qq.com> Date: Wed, 26 Aug 2026 21:36:17 +0800 Subject: [PATCH] fix: restore full-frame roi in raw coordinate mode --- src/VizumCamera.cpp | 39 +++++++++++++++++++++++---------------- src/VizumCamera.h | 5 +++-- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/VizumCamera.cpp b/src/VizumCamera.cpp index 1c77ba4..0cc3e03 100755 --- a/src/VizumCamera.cpp +++ b/src/VizumCamera.cpp @@ -370,6 +370,11 @@ public: "(error code: {})", SdkErrorText(queryError), queryError); return; } + if (m_previousCalibRoi != VzFalse) { + LOG_ERROR("[VizumCamera] Full-frame ROI transaction requires a CalibROI=false " + "point-cloud baseline; refusing cross-coordinate ROI mutation"); + return; + } // SDK 官方 save_gray_depth_map 示例使用 ROI 输出,并在 CalibROI=false // 坐标基准下保存/恢复检测 ROI,再切 CalibROI=true 配置全分辨率 ROI 取图。 @@ -399,12 +404,12 @@ public: m_restoreLeftROI = currentLeftROI; m_restoreRightROI = currentRightROI; m_restoreRoiAvailable = true; - const bool sameAcrossCalibModes = SameSdkRoi(currentLeftROI, m_initialLeftROI) + const bool baselineRoiMatches = SameSdkRoi(currentLeftROI, m_initialLeftROI) && SameSdkRoi(currentRightROI, m_initialRightROI); LOG_INFO("[CaptureState] stage=restore_roi_snapshot calib_roi=false " "left=[{}, {}, {}, {}] right=[{}, {}, {}, {}] " - "connection_mode_left=[{}, {}, {}, {}] " - "connection_mode_right=[{}, {}, {}, {}] same_across_calib_modes={}", + "connection_raw_left=[{}, {}, {}, {}] " + "connection_raw_right=[{}, {}, {}, {}] baseline_roi_matches={}", currentLeftROI.left, currentLeftROI.right, currentLeftROI.top, currentLeftROI.bottom, currentRightROI.left, currentRightROI.right, @@ -413,7 +418,13 @@ public: m_initialLeftROI.top, m_initialLeftROI.bottom, m_initialRightROI.left, m_initialRightROI.right, m_initialRightROI.top, m_initialRightROI.bottom, - sameAcrossCalibModes); + baselineRoiMatches); + if (!baselineRoiMatches) { + LOG_ERROR("[VizumCamera] Raw DetectROI differs from the connection-time raw " + "point-cloud ROI; refusing full-frame transaction"); + RestoreNow(); + return; + } ret = VzNL_EnableCalibROI(m_guardDeviceHandle, VzTrue); LogSdkReturn("apply_full_frame_roi", "VzNL_EnableCalibROI(true)", ret); @@ -478,7 +489,7 @@ public: bool RestoreNow() { - if (m_restoreAttempted && m_restoreSucceeded) + if (m_restoreAttempted) return m_restoreSucceeded; m_restoreAttempted = true; @@ -563,9 +574,6 @@ public: RestoreNow(); } - unsigned int FrameWidth() const { return m_frameWidth; } - unsigned int FrameHeight() const { return m_frameHeight; } - FullFrameRoiRestoreGuard(const FullFrameRoiRestoreGuard&) = delete; FullFrameRoiRestoreGuard& operator=(const FullFrameRoiRestoreGuard&) = delete; @@ -1565,16 +1573,15 @@ bool VizumCamera::CaptureFullFrameLeftImage(SLImage& image, const bool rightReleased = rightImageGuard.ReleaseNow(); const bool imagesReleased = leftReleased && rightReleased; - // SDK 官方示例的有效全画幅条件:CalibROI=true 且 DetectROI=设备全分辨率。 + // GetResolution/DetectROI 使用校正坐标域;GetEyeImage 返回眼图缓冲域。 + // 现场设备分别为 1336x2115 与 1216x1920,禁止跨坐标域比较尺寸。 const bool validFullFrame = converted && !image.empty() - && image.originX == 0 && image.originY == 0 - && image.width == fullFrameGuard.FrameWidth() - && image.height == fullFrameGuard.FrameHeight(); + && image.originX == 0 && image.originY == 0; if (converted && !validFullFrame) { - LOG_ERROR("[VizumCamera] Full-frame SDK image contract failed: " - "image={}x{} origin=({}, {}), expected={}x{} origin=(0, 0)", - image.width, image.height, image.originX, image.originY, - fullFrameGuard.FrameWidth(), fullFrameGuard.FrameHeight()); + LOG_ERROR("[VizumCamera] Full-frame SDK eye buffer has invalid payload/origin: " + "image={}x{} origin=({}, {}); calibrated ROI dimensions are not an " + "eye-buffer size contract", + image.width, image.height, image.originX, image.originY); } const bool imageModesRestored = fullFrameGuard.RestoreNow(); diff --git a/src/VizumCamera.h b/src/VizumCamera.h index f9f1cbf..1c8fc78 100755 --- a/src/VizumCamera.h +++ b/src/VizumCamera.h @@ -129,13 +129,14 @@ public: /** * @brief 临时把左右检测 ROI 配置为全幅,采集左目全图后恢复初始 ROI - * @param[out] image SDK 返回的矫正全幅左目图(尺寸等于设备分辨率,原点必须为(0,0)) + * @param[out] image SDK 返回的全幅左目眼图缓冲(尺寸独立于校正 ROI 分辨率,原点必须为(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 + * @note 初始 ROI 必须在 CalibROI=false 坐标域缓存;事务在校正域配置全幅 ROI, + * 返回前在原始域恢复并校验初始左右 ROI */ bool CaptureFullFrameLeftImage(SLImage& image, std::string& frameId,