diff --git a/modules/calib3d/src/stereobm.cpp b/modules/calib3d/src/stereobm.cpp index e7094c642c..2c8e23f4a9 100644 --- a/modules/calib3d/src/stereobm.cpp +++ b/modules/calib3d/src/stereobm.cpp @@ -344,7 +344,7 @@ static void findStereoCorrespondenceBM_SSE2( const Mat& left, const Mat& right, { hsad = hsad0 - dy0*ndisp; cbuf = cbuf0 + (x + wsz2 + 1)*cstep - dy0*ndisp; lptr = lptr0 + MIN(MAX(x, -lofs), width-lofs-1) - dy0*sstep; - rptr = rptr0 + MIN(MAX(x, -rofs), width-rofs-1) - dy0*sstep; + rptr = rptr0 + MIN(MAX(x, -rofs), width-rofs-ndisp) - dy0*sstep; for( y = -dy0; y < height + dy1; y++, hsad += ndisp, cbuf += ndisp, lptr += sstep, rptr += sstep ) { @@ -385,7 +385,7 @@ static void findStereoCorrespondenceBM_SSE2( const Mat& left, const Mat& right, hsad = hsad0 - dy0*ndisp; lptr_sub = lptr0 + MIN(MAX(x0, -lofs), width-1-lofs) - dy0*sstep; lptr = lptr0 + MIN(MAX(x1, -lofs), width-1-lofs) - dy0*sstep; - rptr = rptr0 + MIN(MAX(x1, -rofs), width-1-rofs) - dy0*sstep; + rptr = rptr0 + MIN(MAX(x1, -rofs), width-ndisp-rofs) - dy0*sstep; for( y = -dy0; y < height + dy1; y++, cbuf += ndisp, cbuf_sub += ndisp, hsad += ndisp, lptr += sstep, lptr_sub += sstep, rptr += sstep ) @@ -610,7 +610,7 @@ findStereoCorrespondenceBM( const Mat& left, const Mat& right, { hsad = hsad0 - dy0*ndisp; cbuf = cbuf0 + (x + wsz2 + 1)*cstep - dy0*ndisp; lptr = lptr0 + std::min(std::max(x, -lofs), width-lofs-1) - dy0*sstep; - rptr = rptr0 + std::min(std::max(x, -rofs), width-rofs-1) - dy0*sstep; + rptr = rptr0 + std::min(std::max(x, -rofs), width-rofs-ndisp) - dy0*sstep; for( y = -dy0; y < height + dy1; y++, hsad += ndisp, cbuf += ndisp, lptr += sstep, rptr += sstep ) { @@ -661,7 +661,7 @@ findStereoCorrespondenceBM( const Mat& left, const Mat& right, hsad = hsad0 - dy0*ndisp; lptr_sub = lptr0 + MIN(MAX(x0, -lofs), width-1-lofs) - dy0*sstep; lptr = lptr0 + MIN(MAX(x1, -lofs), width-1-lofs) - dy0*sstep; - rptr = rptr0 + MIN(MAX(x1, -rofs), width-1-rofs) - dy0*sstep; + rptr = rptr0 + MIN(MAX(x1, -rofs), width-ndisp-rofs) - dy0*sstep; for( y = -dy0; y < height + dy1; y++, cbuf += ndisp, cbuf_sub += ndisp, hsad += ndisp, lptr += sstep, lptr_sub += sstep, rptr += sstep ) diff --git a/modules/calib3d/src/stereosgbm.cpp b/modules/calib3d/src/stereosgbm.cpp index 01661813a2..4c8adb9f9d 100644 --- a/modules/calib3d/src/stereosgbm.cpp +++ b/modules/calib3d/src/stereosgbm.cpp @@ -99,7 +99,7 @@ StereoSGBM::~StereoSGBM() } /* - For each pixel row1[x], max(-maxD, 0) <= minX <= x < maxX <= width - max(0, -minD), + For each pixel row1[x], max(-maxD, 0) <= minX <= x < maxX <= width - max(0, minD), and for each disparity minD<=d(y), *row2 = img2.ptr(y); PixType *prow1 = buffer + width2*2, *prow2 = prow1 + width*cn*2; @@ -200,6 +200,19 @@ static void calcPixelCostBT( const Mat& img1, const Mat& img2, int y, int u0 = min(ul, ur); u0 = min(u0, u); int u1 = max(ul, ur); u1 = max(u1, u); + int minDlocal = max(minD, x-width+1); + int maxDlocal = min(maxD, x); + int d; + for( d = minD; d < minDlocal; d++ ) + { + int v = prow2[0]; + int v0 = buffer[0]; + int v1 = buffer[width2]; + int c0 = max(0, u - v1); c0 = max(c0, v0 - u); + int c1 = max(0, v - u1); c1 = max(c1, u0 - v); + + cost[x*D + d] = (CostType)(cost[x*D+d] + (min(c0, c1) >> diff_scale)); + } #if CV_SSE2 if( useSIMD ) { @@ -207,7 +220,7 @@ static void calcPixelCostBT( const Mat& img1, const Mat& img2, int y, __m128i _u1 = _mm_set1_epi8((char)u1), z = _mm_setzero_si128(); __m128i ds = _mm_cvtsi32_si128(diff_scale); - for( int d = minD; d < maxD; d += 16 ) + for( ; d < maxDlocal - 15; d += 16 ) { __m128i _v = _mm_loadu_si128((const __m128i*)(prow2 + width-x-1 + d)); __m128i _v0 = _mm_loadu_si128((const __m128i*)(buffer + width-x-1 + d)); @@ -223,19 +236,26 @@ static void calcPixelCostBT( const Mat& img1, const Mat& img2, int y, _mm_store_si128((__m128i*)(cost + x*D + d + 8), _mm_adds_epi16(c1, _mm_srl_epi16(_mm_unpackhi_epi8(diff,z), ds))); } } - else #endif + for( ; d < maxDlocal; d++ ) { - for( int d = minD; d < maxD; d++ ) - { - int v = prow2[width-x-1 + d]; - int v0 = buffer[width-x-1 + d]; - int v1 = buffer[width-x-1 + d + width2]; - int c0 = max(0, u - v1); c0 = max(c0, v0 - u); - int c1 = max(0, v - u1); c1 = max(c1, u0 - v); + int v = prow2[width-x-1 + d]; + int v0 = buffer[width-x-1 + d]; + int v1 = buffer[width-x-1 + d + width2]; + int c0 = max(0, u - v1); c0 = max(c0, v0 - u); + int c1 = max(0, v - u1); c1 = max(c1, u0 - v); - cost[x*D + d] = (CostType)(cost[x*D+d] + (min(c0, c1) >> diff_scale)); - } + cost[x*D + d] = (CostType)(cost[x*D+d] + (min(c0, c1) >> diff_scale)); + } + for( ; d < maxD; d++ ) + { + int v = prow2[width-1]; + int v0 = buffer[width-1]; + int v1 = buffer[width-1 + width2]; + int c0 = max(0, u - v1); c0 = max(c0, v0 - u); + int c1 = max(0, v - u1); c1 = max(c1, u0 - v); + + cost[x*D + d] = (CostType)(cost[x*D+d] + (min(c0, c1) >> diff_scale)); } } } @@ -329,7 +349,7 @@ static void computeDisparitySGBM( const Mat& img1, const Mat& img2, int disp12MaxDiff = params.disp12MaxDiff > 0 ? params.disp12MaxDiff : 1; int P1 = params.P1 > 0 ? params.P1 : 2, P2 = max(params.P2 > 0 ? params.P2 : 5, P1+1); int k, width = disp1.cols, height = disp1.rows; - int minX1 = max(-maxD, 0), maxX1 = width + min(minD, 0); + int minX1 = max(-maxD, 0), maxX1 = width + min(-minD, 0); int D = maxD - minD, width1 = maxX1 - minX1; int INVALID_DISP = minD - 1, INVALID_DISP_SCALED = INVALID_DISP*DISP_SCALE; int SW2 = SADWindowSize.width/2, SH2 = SADWindowSize.height/2; @@ -377,6 +397,7 @@ static void computeDisparitySGBM( const Mat& img1, const Mat& img2, // summary cost over different (nDirs) directions CostType* Cbuf = (CostType*)alignPtr(buffer.data, ALIGN); + memset(Cbuf, 0, CSBufSize*sizeof(CostType)); CostType* Sbuf = Cbuf + CSBufSize; CostType* hsumBuf = Sbuf + CSBufSize; CostType* pixDiff = hsumBuf + costBufSize*hsumBufNRows;