diff --git a/modules/calib3d/src/stereosgbm.cpp b/modules/calib3d/src/stereosgbm.cpp index 74d5068ac5..ff033e7a0c 100644 --- a/modules/calib3d/src/stereosgbm.cpp +++ b/modules/calib3d/src/stereosgbm.cpp @@ -2074,41 +2074,44 @@ void SGBM3WayMainLoop::impl(const Range& range) const { d = 0; #if (CV_SIMD || CV_SIMD_SCALABLE) - horPassCostVolume+=x; - int thresh = (100*min_cost)/(100-uniquenessRatio); - v_int16 thresh_reg = vx_setall_s16((short)(thresh+1)); - v_int16 d1 = vx_setall_s16((short)(best_d-1)); - v_int16 d2 = vx_setall_s16((short)(best_d+1)); - v_int16 eight_reg = vx_setall_s16((short)VTraits::vlanes()); - v_int16 cur_d = vx_load(idx_row); - v_int16 mask; + if(uniquenessRatio<100) + { + horPassCostVolume+=x; + int thresh = (100*min_cost)/(100-uniquenessRatio); + v_int16 thresh_reg = vx_setall_s16(saturate_cast(thresh+1)); + v_int16 d1 = vx_setall_s16((short)(best_d-1)); + v_int16 d2 = vx_setall_s16((short)(best_d+1)); + v_int16 eight_reg = vx_setall_s16((short)VTraits::vlanes()); + v_int16 cur_d = vx_load(idx_row); + v_int16 mask; - for( ; d <= D - 2*VTraits::vlanes(); d+=2*VTraits::vlanes() ) - { - mask = v_and(v_lt(vx_load_aligned(horPassCostVolume + d), thresh_reg), v_or(v_lt(cur_d, d1), v_gt(cur_d, d2))); - cur_d = v_add(cur_d, eight_reg); - if( v_check_any(mask) ) - break; - mask = v_and(v_lt(vx_load_aligned(horPassCostVolume + d + VTraits::vlanes()), thresh_reg), v_or(v_lt(cur_d, d1), v_gt(cur_d, d2))); - cur_d = v_add(cur_d, eight_reg); - if( v_check_any(mask) ) - break; - } - if( d <= D - 2*VTraits::vlanes() ) - { - horPassCostVolume-=x; - continue; - } - if( d <= D - VTraits::vlanes() ) - { - if( v_check_any(v_and(v_lt(vx_load_aligned(horPassCostVolume + d), thresh_reg), v_or(v_lt(cur_d, d1), v_gt(cur_d, d2)))) ) + for( ; d <= D - 2*VTraits::vlanes(); d+=2*VTraits::vlanes() ) + { + mask = v_and(v_lt(vx_load_aligned(horPassCostVolume + d), thresh_reg), v_or(v_lt(cur_d, d1), v_gt(cur_d, d2))); + cur_d = v_add(cur_d, eight_reg); + if( v_check_any(mask) ) + break; + mask = v_and(v_lt(vx_load_aligned(horPassCostVolume + d + VTraits::vlanes()), thresh_reg), v_or(v_lt(cur_d, d1), v_gt(cur_d, d2))); + cur_d = v_add(cur_d, eight_reg); + if( v_check_any(mask) ) + break; + } + if( d <= D - 2*VTraits::vlanes() ) { horPassCostVolume-=x; continue; } - d+=VTraits::vlanes(); + if( d <= D - VTraits::vlanes() ) + { + if( v_check_any(v_and(v_lt(vx_load_aligned(horPassCostVolume + d), thresh_reg), v_or(v_lt(cur_d, d1), v_gt(cur_d, d2)))) ) + { + horPassCostVolume-=x; + continue; + } + d+=VTraits::vlanes(); + } + horPassCostVolume-=x; } - horPassCostVolume-=x; #endif for( ; d < D; d++ ) { diff --git a/modules/calib3d/test/test_stereomatching.cpp b/modules/calib3d/test/test_stereomatching.cpp index 9ea16110b1..910dd50a12 100644 --- a/modules/calib3d/test/test_stereomatching.cpp +++ b/modules/calib3d/test/test_stereomatching.cpp @@ -952,6 +952,18 @@ TEST(Calib3d_StereoSGBM, deterministic) { } +TEST(Calib3d_StereoSGBM, regression_29761) +{ + Mat leftImg(256, 256, CV_8UC1), rightImg(256, 256, CV_8UC1); + randu(leftImg, Scalar(0), Scalar(255)); + randu(rightImg, Scalar(0), Scalar(255)); + + Ptr sgbm = StereoSGBM::create( 0, 64, 5, 100, 200, 1, 31, 100, 0, 0, StereoSGBM::MODE_SGBM_3WAY); + Mat leftDisp; + sgbm->compute( leftImg, rightImg, leftDisp); + EXPECT_EQ(countNonZero(leftDisp != -StereoMatcher::DISP_SCALE), 0); +} + TEST(Calib3d_StereoSGBM_HH4, regression) { String path = cvtest::TS::ptr()->get_data_path() + "cv/stereomatching/datasets/teddy/";