1 //M*//////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
42 #include "precomp.hpp"
45 #define INFINITY 10000
46 #define OCCLUSION_PENALTY 10000
47 #define OCCLUSION_PENALTY2 1000
48 #define DENOMINATOR 16
50 #define OCCLUDED CV_STEREO_GC_OCCLUDED
52 #define IS_BLOCKED(d1, d2) ((d1) > (d2))
74 typedef struct CvStereoGCState2
76 int Ithreshold, interactionRadius;
77 int lambda, lambda1, lambda2, K;
78 int dataCostFuncTab[CUTOFF+1];
79 int smoothnessR[CUTOFF*2+1];
80 int smoothnessGrayDiff[512];
86 // truncTab[x+255] = MAX(x-255,0)
87 static uchar icvTruncTab[512];
88 // cutoffSqrTab[x] = MIN(x*x, CUTOFF)
89 static int icvCutoffSqrTab[256];
91 static void icvInitStereoConstTabs()
93 static volatile int initialized = 0;
97 for( i = 0; i < 512; i++ )
98 icvTruncTab[i] = (uchar)MIN(MAX(i-255,0),255);
99 for( i = 0; i < 256; i++ )
100 icvCutoffSqrTab[i] = MIN(i*i, CUTOFF);
105 static void icvInitStereoTabs( CvStereoGCState2* state2 )
107 int i, K = state2->K;
109 for( i = 0; i <= CUTOFF; i++ )
110 state2->dataCostFuncTab[i] = MIN(i*DENOMINATOR - K, 0);
112 for( i = 0; i < CUTOFF*2 + 1; i++ )
113 state2->smoothnessR[i] = MIN(abs(i-CUTOFF), state2->interactionRadius);
115 for( i = 0; i < 512; i++ )
117 int diff = abs(i - 255);
118 state2->smoothnessGrayDiff[i] = diff < state2->Ithreshold ? state2->lambda1 : state2->lambda2;
123 static int icvGCResizeOrphansBuf( GCVtx**& orphans, int norphans )
125 int i, newNOrphans = MAX(norphans*3/2, 256);
126 GCVtx** newOrphans = (GCVtx**)cvAlloc( newNOrphans*sizeof(orphans[0]) );
127 for( i = 0; i < norphans; i++ )
128 newOrphans[i] = orphans[i];
130 orphans = newOrphans;
134 static int64 icvGCMaxFlow( GCVtx* vtx, int nvtx, GCEdge* edges, GCVtx**& _orphans, int& _maxOrphans )
136 const int TERMINAL = -1, ORPHAN = -2;
137 GCVtx stub, *nilNode = &stub, *first = nilNode, *last = nilNode;
141 int norphans = 0, maxOrphans = _maxOrphans;
142 GCVtx** orphans = _orphans;
145 // initialize the active queue and the graph vertices
146 for( i = 0; i < nvtx; i++ )
152 last = last->next = v;
154 v->parent = TERMINAL;
155 v->t = v->weight < 0;
162 last->next = nilNode;
165 // run the search-path -> augment-graph -> restore-trees loop
169 int e0 = -1, ei = 0, ej = 0, min_weight, weight;
172 // grow S & T search trees, find an edge connecting them
173 while( first != nilNode )
179 for( ei = v->first; ei != 0; ei = edges[ei].next )
181 if( edges[ei^vt].weight == 0 )
189 u->dist = v->dist + 1;
193 last = last->next = u;
204 if( u->dist > v->dist+1 && u->ts <= v->ts )
206 // reassign the parent
209 u->dist = v->dist + 1;
215 // exclude the vertex from the active list
223 // find the minimum edge weight along the path
224 min_weight = edges[e0].weight;
225 assert( min_weight > 0 );
226 // k = 1: source tree, k = 0: destination tree
227 for( k = 1; k >= 0; k-- )
229 for( v = edges[e0^k].dst;; v = edges[ei].dst )
231 if( (ei = v->parent) < 0 )
233 weight = edges[ei^k].weight;
234 min_weight = MIN(min_weight, weight);
235 assert( min_weight > 0 );
237 weight = abs(v->weight);
238 min_weight = MIN(min_weight, weight);
239 assert( min_weight > 0 );
242 // modify weights of the edges along the path and collect orphans
243 edges[e0].weight -= min_weight;
244 edges[e0^1].weight += min_weight;
247 // k = 1: source tree, k = 0: destination tree
248 for( k = 1; k >= 0; k-- )
250 for( v = edges[e0^k].dst;; v = edges[ei].dst )
252 if( (ei = v->parent) < 0 )
254 edges[ei^(k^1)].weight += min_weight;
255 if( (edges[ei^k].weight -= min_weight) == 0 )
257 if( norphans >= maxOrphans )
258 maxOrphans = icvGCResizeOrphansBuf( orphans, norphans );
259 orphans[norphans++] = v;
264 v->weight = (short)(v->weight + min_weight*(1-k*2));
267 if( norphans >= maxOrphans )
268 maxOrphans = icvGCResizeOrphansBuf( orphans, norphans );
269 orphans[norphans++] = v;
274 // restore the search trees by finding new parents for the orphans
276 while( norphans > 0 )
278 GCVtx* v1 = orphans[--norphans];
279 int d, min_dist = INT_MAX;
283 for( ei = v1->first; ei != 0; ei = edges[ei].next )
285 if( edges[ei^(vt^1)].weight == 0 )
288 if( u->t != vt || u->parent == 0 )
290 // compute the distance to the tree root
293 if( u->ts == curr_ts )
314 // update the distance
322 for( u = edges[ei].dst; u->ts != curr_ts; u = edges[u->parent].dst )
330 if( (v1->parent = e0) > 0 )
337 /* no parent is found */
339 for( ei = v1->first; ei != 0; ei = edges[ei].next )
343 if( u->t != vt || !ej )
345 if( edges[ei^(vt^1)].weight && !u->next )
348 last = last->next = u;
350 if( ej > 0 && edges[ej].dst == v1 )
352 if( norphans >= maxOrphans )
353 maxOrphans = icvGCResizeOrphansBuf( orphans, norphans );
354 orphans[norphans++] = u;
362 _maxOrphans = maxOrphans;
368 CvStereoGCState* cvCreateStereoGCState( int numberOfDisparities, int maxIters )
370 CvStereoGCState* state = 0;
372 state = (CvStereoGCState*)cvAlloc( sizeof(*state) );
373 memset( state, 0, sizeof(*state) );
374 state->minDisparity = 0;
375 state->numberOfDisparities = numberOfDisparities;
376 state->maxIters = maxIters <= 0 ? 3 : maxIters;
377 state->Ithreshold = 5;
378 state->interactionRadius = 1;
379 state->K = state->lambda = state->lambda1 = state->lambda2 = -1.f;
380 state->occlusionCost = OCCLUSION_PENALTY;
385 void cvReleaseStereoGCState( CvStereoGCState** _state )
387 CvStereoGCState* state;
389 if( !_state && !*_state )
393 cvReleaseMat( &state->left );
394 cvReleaseMat( &state->right );
395 cvReleaseMat( &state->ptrLeft );
396 cvReleaseMat( &state->ptrRight );
397 cvReleaseMat( &state->vtxBuf );
398 cvReleaseMat( &state->edgeBuf );
402 // ||I(x) - J(x')|| =
406 // max(minJ(x') - I(x), 0),
407 // max(I(x) - maxJ(x'), 0)),
409 // max(minI(x) - J(x'), 0),
410 // max(J(x') - maxI(x), 0)))**2) ==
413 // max(minJ(x') - I(x), 0) +
414 // max(I(x) - maxJ(x'), 0),
416 // max(minI(x) - J(x'), 0) +
417 // max(J(x') - maxI(x), 0)))**2)
418 // where (I, minI, maxI) and
419 // (J, minJ, maxJ) are stored as interleaved 3-channel images.
420 // minI, maxI are computed from I,
421 // minJ, maxJ are computed from J - see icvInitGraySubPix.
422 static inline int icvDataCostFuncGraySubpix( const uchar* a, const uchar* b )
424 int va = a[0], vb = b[0];
425 int da = icvTruncTab[b[1] - va + 255] + icvTruncTab[va - b[2] + 255];
426 int db = icvTruncTab[a[1] - vb + 255] + icvTruncTab[vb - a[2] + 255];
427 return icvCutoffSqrTab[MIN(da,db)];
430 static inline int icvSmoothnessCostFunc( int da, int db, int maxR, const int* stabR, int scale )
432 return da == db ? 0 : (da == OCCLUDED || db == OCCLUDED ? maxR : stabR[da - db])*scale;
435 static void icvInitGraySubpix( const CvMat* left, const CvMat* right,
436 CvMat* left3, CvMat* right3 )
438 int k, x, y, rows = left->rows, cols = left->cols;
440 for( k = 0; k < 2; k++ )
442 const CvMat* src = k == 0 ? left : right;
443 CvMat* dst = k == 0 ? left3 : right3;
444 int sstep = src->step;
446 for( y = 0; y < rows; y++ )
448 const uchar* sptr = src->data.ptr + sstep*y;
449 const uchar* sptr_prev = y > 0 ? sptr - sstep : sptr;
450 const uchar* sptr_next = y < rows-1 ? sptr + sstep : sptr;
451 uchar* dptr = dst->data.ptr + dst->step*y;
452 int v_prev = sptr[0];
454 for( x = 0; x < cols; x++, dptr += 3 )
456 int v = sptr[x], v1, minv = v, maxv = v;
459 minv = MIN(minv, v1); maxv = MAX(maxv, v1);
460 v1 = (v + sptr_prev[x])/2;
461 minv = MIN(minv, v1); maxv = MAX(maxv, v1);
462 v1 = (v + sptr_next[x])/2;
463 minv = MIN(minv, v1); maxv = MAX(maxv, v1);
466 v1 = (v + sptr[x+1])/2;
467 minv = MIN(minv, v1); maxv = MAX(maxv, v1);
471 dptr[1] = (uchar)minv;
472 dptr[2] = (uchar)maxv;
478 // Optimal K is computed as avg_x(k-th-smallest_d(||I(x)-J(x+d)||)),
479 // where k = number_of_disparities*0.25.
481 icvComputeK( CvStereoGCState* state )
483 int x, y, x1, d, i, j, rows = state->left->rows, cols = state->left->cols, n = 0;
484 int mind = state->minDisparity, nd = state->numberOfDisparities, maxd = mind + nd;
485 int k = MIN(MAX((nd + 2)/4, 3), nd), delta, t, sum = 0;
486 std::vector<int> _arr(k+1);
489 for( y = 0; y < rows; y++ )
491 const uchar* lptr = state->left->data.ptr + state->left->step*y;
492 const uchar* rptr = state->right->data.ptr + state->right->step*y;
494 for( x = 0; x < cols; x++ )
496 for( d = maxd-1, i = 0; d >= mind; d-- )
499 if( (unsigned)x1 >= (unsigned)cols )
501 delta = icvDataCostFuncGraySubpix( lptr + x*3, rptr + x1*3 );
505 for( i = 0; i < k; i++ )
507 CV_SWAP( arr[i], delta, t );
510 for( j = 1; j < i; j++ )
511 delta = MAX(delta, arr[j]);
520 static int64 icvComputeEnergy( const CvStereoGCState* state, const CvStereoGCState2* state2,
523 int x, y, rows = state->left->rows, cols = state->left->cols;
525 const int* dtab = state2->dataCostFuncTab;
526 int maxR = state2->interactionRadius;
527 const int* stabR = state2->smoothnessR + CUTOFF;
528 const int* stabI = state2->smoothnessGrayDiff + 255;
529 const uchar* left = state->left->data.ptr;
530 const uchar* right = state->right->data.ptr;
531 short* dleft = state->dispLeft->data.s;
532 short* dright = state->dispRight->data.s;
533 int step = state->left->step;
534 int dstep = (int)(state->dispLeft->step/sizeof(short));
536 assert( state->left->step == state->right->step &&
537 state->dispLeft->step == state->dispRight->step );
540 return (int64)OCCLUSION_PENALTY*rows*cols*2;
542 for( y = 0; y < rows; y++, left += step, right += step, dleft += dstep, dright += dstep )
544 for( x = 0; x < cols; x++ )
546 int d = dleft[x], x1, d1;
548 E += OCCLUSION_PENALTY;
552 if( (unsigned)x1 >= (unsigned)cols )
556 E += dtab[icvDataCostFuncGraySubpix( left + x*3, right + x1*3 )];
562 E += icvSmoothnessCostFunc(d, d1, maxR, stabR, stabI[left[x*3] - left[x*3+3]] );
567 E += icvSmoothnessCostFunc(d, d1, maxR, stabR, stabI[left[x*3] - left[x*3+step]] );
572 E += OCCLUSION_PENALTY;
577 E += icvSmoothnessCostFunc(d, d1, maxR, stabR, stabI[right[x*3] - right[x*3+3]] );
581 d1 = dright[x+dstep];
582 E += icvSmoothnessCostFunc(d, d1, maxR, stabR, stabI[right[x*3] - right[x*3+step]] );
591 static inline void icvAddEdge( GCVtx *x, GCVtx* y, GCEdge* edgeBuf, int nedges, int w, int rw )
593 GCEdge *xy = edgeBuf + nedges, *yx = xy + 1;
595 assert( x != 0 && y != 0 );
598 xy->weight = (short)w;
603 yx->weight = (short)rw;
607 static inline int icvAddTWeights( GCVtx* vtx, int sourceWeight, int sinkWeight )
614 vtx->weight = (short)(sourceWeight - sinkWeight);
615 return MIN(sourceWeight, sinkWeight);
618 static inline int icvAddTerm( GCVtx* x, GCVtx* y, int A, int B, int C, int D,
619 GCEdge* edgeBuf, int& nedges )
623 assert(B - A + C - D >= 0);
626 dE += icvAddTWeights(x, D, B);
627 dE += icvAddTWeights(y, 0, A - B);
628 if( (w = B - A + C - D) != 0 )
630 icvAddEdge( x, y, edgeBuf, nedges, 0, w );
636 dE += icvAddTWeights(x, D, A + D - C);
637 dE += icvAddTWeights(y, 0, C - D);
638 if( (w = B - A + C - D) != 0 )
640 icvAddEdge( x, y, edgeBuf, nedges, w, 0 );
646 dE += icvAddTWeights(x, D, A);
647 if( B != A || C != D )
649 icvAddEdge( x, y, edgeBuf, nedges, B - A, C - D );
656 static int64 icvAlphaExpand( int64 Eprev, int alpha, CvStereoGCState* state, CvStereoGCState2* state2 )
660 int delta, E00=0, E0a=0, Ea0=0, Eaa=0;
661 int k, a, d, d1, x, y, x1, y1, rows = state->left->rows, cols = state->left->cols;
662 int nvtx = 0, nedges = 2;
663 GCVtx* vbuf = (GCVtx*)state->vtxBuf->data.ptr;
664 GCEdge* ebuf = (GCEdge*)state->edgeBuf->data.ptr;
665 int maxR = state2->interactionRadius;
666 const int* dtab = state2->dataCostFuncTab;
667 const int* stabR = state2->smoothnessR + CUTOFF;
668 const int* stabI = state2->smoothnessGrayDiff + 255;
669 const uchar* left0 = state->left->data.ptr;
670 const uchar* right0 = state->right->data.ptr;
671 short* dleft0 = state->dispLeft->data.s;
672 short* dright0 = state->dispRight->data.s;
673 GCVtx** pleft0 = (GCVtx**)state->ptrLeft->data.ptr;
674 GCVtx** pright0 = (GCVtx**)state->ptrRight->data.ptr;
675 int step = state->left->step;
676 int dstep = (int)(state->dispLeft->step/sizeof(short));
677 int pstep = (int)(state->ptrLeft->step/sizeof(GCVtx*));
678 int aa[] = { alpha, -alpha };
680 //double t = (double)cvGetTickCount();
682 assert( state->left->step == state->right->step &&
683 state->dispLeft->step == state->dispRight->step &&
684 state->ptrLeft->step == state->ptrRight->step );
685 for( k = 0; k < 2; k++ )
692 for( y = 0; y < rows; y++ )
694 const uchar* left = left0 + step*y;
695 const uchar* right = right0 + step*y;
696 const short* dleft = dleft0 + dstep*y;
697 const short* dright = dright0 + dstep*y;
698 GCVtx** pleft = pleft0 + pstep*y;
699 GCVtx** pright = pright0 + pstep*y;
700 const uchar* lr[] = { left, right };
701 const short* dlr[] = { dleft, dright };
702 GCVtx** plr[] = { pleft, pright };
704 for( k = 0; k < 2; k++ )
707 for( y1 = y+(y>0); y1 <= y+(y<rows-1); y1++ )
709 const short* disp = (k == 0 ? dleft0 : dright0) + y1*dstep;
710 GCVtx** ptr = (k == 0 ? pleft0 : pright0) + y1*pstep;
711 for( x = 0; x < cols; x++ )
713 GCVtx* v = ptr[x] = &vbuf[nvtx++];
715 v->weight = disp[x] == (short)(OCCLUDED ? -OCCLUSION_PENALTY2 : 0);
720 for( x = 0; x < cols; x++ )
726 // (left + x, right + x + d)
727 if( d != alpha && d != OCCLUDED && (unsigned)x1 < (unsigned)cols )
734 delta = IS_BLOCKED(alpha, d) ? INFINITY : 0;
736 E += icvAddTerm( var, var1,
737 dtab[icvDataCostFuncGraySubpix( left + x*3, right + x1*3 )],
738 delta, delta, 0, ebuf, nedges );
740 else if( IS_BLOCKED(alpha, d) )
741 E += icvAddTerm( var, var1, 0, INFINITY, 0, 0, ebuf, nedges );
744 // (left + x, right + x + alpha)
746 if( (unsigned)x1 < (unsigned)cols )
751 E0a = IS_BLOCKED(d, alpha) ? INFINITY : 0;
752 Ea0 = IS_BLOCKED(-d1, alpha) ? INFINITY : 0;
753 Eaa = dtab[icvDataCostFuncGraySubpix( left + x*3, right + x1*3 )];
754 E += icvAddTerm( var, var1, 0, E0a, Ea0, Eaa, ebuf, nedges );
758 for( k = 0; k < 2; k++ )
761 const short* disp = dlr[k];
762 const uchar* img = lr[k] + x*3;
772 scale = stabI[img[0] - img[3]];
773 E0a = icvSmoothnessCostFunc( d, a, maxR, stabR, scale );
774 Ea0 = icvSmoothnessCostFunc( a, d1, maxR, stabR, scale );
775 E00 = icvSmoothnessCostFunc( d, d1, maxR, stabR, scale );
776 E += icvAddTerm( var, var1, E00, E0a, Ea0, 0, ebuf, nedges );
783 scale = stabI[img[0] - img[step]];
784 E0a = icvSmoothnessCostFunc( d, a, maxR, stabR, scale );
785 Ea0 = icvSmoothnessCostFunc( a, d1, maxR, stabR, scale );
786 E00 = icvSmoothnessCostFunc( d, d1, maxR, stabR, scale );
787 E += icvAddTerm( var, var1, E00, E0a, Ea0, 0, ebuf, nedges );
792 if( d != OCCLUDED && IS_BLOCKED(alpha, -d))
795 if( (unsigned)x1 < (unsigned)cols )
797 if( d != -dleft[x1] )
800 E += icvAddTerm( var, var1, 0, INFINITY, 0, 0, ebuf, nedges );
807 //t = (double)cvGetTickCount() - t;
808 ebuf[0].weight = ebuf[1].weight = 0;
809 E += icvGCMaxFlow( vbuf, nvtx, ebuf, state2->orphans, state2->maxOrphans );
813 for( y = 0; y < rows; y++ )
815 short* dleft = dleft0 + dstep*y;
816 short* dright = dright0 + dstep*y;
817 GCVtx** pleft = pleft0 + pstep*y;
818 GCVtx** pright = pright0 + pstep*y;
819 for( x = 0; x < cols; x++ )
821 GCVtx* var2 = pleft[x];
822 if( var2 && var2->parent && var2->t )
823 dleft[x] = (short)alpha;
826 if( var2 && var2->parent && var2->t )
827 dright[x] = (short)-alpha;
832 return MIN(E, Eprev);
836 CV_IMPL void cvFindStereoCorrespondenceGC( const CvArr* _left, const CvArr* _right,
837 CvArr* _dispLeft, CvArr* _dispRight, CvStereoGCState* state, int useDisparityGuess )
839 CvStereoGCState2 state2;
841 state2.maxOrphans = 0;
843 CvMat lstub, *left = cvGetMat( _left, &lstub );
844 CvMat rstub, *right = cvGetMat( _right, &rstub );
845 CvMat dlstub, *dispLeft = cvGetMat( _dispLeft, &dlstub );
846 CvMat drstub, *dispRight = cvGetMat( _dispRight, &drstub );
848 int iter, i, nZeroExpansions = 0;
849 CvRNG rng = cvRNG(-1);
852 CV_Assert( state != 0 );
853 CV_Assert( CV_ARE_SIZES_EQ(left, right) && CV_ARE_TYPES_EQ(left, right) &&
854 CV_MAT_TYPE(left->type) == CV_8UC1 );
855 CV_Assert( !dispLeft ||
856 (CV_ARE_SIZES_EQ(dispLeft, left) && CV_MAT_CN(dispLeft->type) == 1) );
857 CV_Assert( !dispRight ||
858 (CV_ARE_SIZES_EQ(dispRight, left) && CV_MAT_CN(dispRight->type) == 1) );
860 size = cvGetSize(left);
861 if( !state->left || state->left->width != size.width || state->left->height != size.height )
863 int pcn = (int)(sizeof(GCVtx*)/sizeof(int));
864 int vcn = (int)(sizeof(GCVtx)/sizeof(int));
865 int ecn = (int)(sizeof(GCEdge)/sizeof(int));
866 cvReleaseMat( &state->left );
867 cvReleaseMat( &state->right );
868 cvReleaseMat( &state->ptrLeft );
869 cvReleaseMat( &state->ptrRight );
870 cvReleaseMat( &state->dispLeft );
871 cvReleaseMat( &state->dispRight );
873 state->left = cvCreateMat( size.height, size.width, CV_8UC3 );
874 state->right = cvCreateMat( size.height, size.width, CV_8UC3 );
875 state->dispLeft = cvCreateMat( size.height, size.width, CV_16SC1 );
876 state->dispRight = cvCreateMat( size.height, size.width, CV_16SC1 );
877 state->ptrLeft = cvCreateMat( size.height, size.width, CV_32SC(pcn) );
878 state->ptrRight = cvCreateMat( size.height, size.width, CV_32SC(pcn) );
879 state->vtxBuf = cvCreateMat( 1, size.height*size.width*2, CV_32SC(vcn) );
880 state->edgeBuf = cvCreateMat( 1, size.height*size.width*12 + 16, CV_32SC(ecn) );
883 if( !useDisparityGuess )
885 cvSet( state->dispLeft, cvScalarAll(OCCLUDED));
886 cvSet( state->dispRight, cvScalarAll(OCCLUDED));
890 CV_Assert( dispLeft && dispRight );
891 cvConvert( dispLeft, state->dispLeft );
892 cvConvert( dispRight, state->dispRight );
895 state2.Ithreshold = state->Ithreshold;
896 state2.interactionRadius = state->interactionRadius;
897 state2.lambda = cvRound(state->lambda*DENOMINATOR);
898 state2.lambda1 = cvRound(state->lambda1*DENOMINATOR);
899 state2.lambda2 = cvRound(state->lambda2*DENOMINATOR);
900 state2.K = cvRound(state->K*DENOMINATOR);
902 icvInitStereoConstTabs();
903 icvInitGraySubpix( left, right, state->left, state->right );
905 std::vector<int> disp(state->numberOfDisparities);
906 CvMat _disp = cvMat( 1, (int)disp.size(), CV_32S, &disp[0] );
907 cvRange( &_disp, state->minDisparity, state->minDisparity + state->numberOfDisparities );
908 cvRandShuffle( &_disp, &rng );
910 if( state2.lambda < 0 && (state2.K < 0 || state2.lambda1 < 0 || state2.lambda2 < 0) )
912 float L = icvComputeK(state)*0.2f;
913 state2.lambda = cvRound(L*DENOMINATOR);
917 state2.K = state2.lambda*5;
918 if( state2.lambda1 < 0 )
919 state2.lambda1 = state2.lambda*3;
920 if( state2.lambda2 < 0 )
921 state2.lambda2 = state2.lambda;
923 icvInitStereoTabs( &state2 );
925 E = icvComputeEnergy( state, &state2, !useDisparityGuess );
926 for( iter = 0; iter < state->maxIters; iter++ )
928 for( i = 0; i < state->numberOfDisparities; i++ )
931 int64 Enew = icvAlphaExpand( E, -alpha, state, &state2 );
937 else if( ++nZeroExpansions >= state->numberOfDisparities )
943 cvConvert( state->dispLeft, dispLeft );
945 cvConvert( state->dispRight, dispRight );
947 cvFree( &state2.orphans );