/* * @src Frame image * @contour contour processing * @testImageHistogram histogram from model image * @h_bins number of hue bins * @s_bins number of sat bins * @min minimum similarity to achieve when comparing histograms */ int Contours::histogramMatchingFilter(IplImage * src, CvHistogram * testImageHistogram,int h_bins,int s_bins, double min){ CvRect box; CvMemStorage* mem = cvCreateMemStorage(0); double val; //get contour bounding box box=cvBoundingRect(this->c,0); //printf("box x:%d y:%d \n",box.x,box.y); IplImage * src_bbox=cvCreateImage(cvSize(box.width,box.height),src->depth,src->nChannels); //gets subimage bounded by box cvGetSubArr( src,(CvMat*)src_bbox, box ); //gets subimage histogram utils::Histogram * h = new Histogram(h_bins,s_bins); CvHistogram* hist = h->getHShistogramFromRGB(src_bbox); //compares with object histogram val=cvCompareHist(hist,testImageHistogram,CV_COMP_BHATTACHARYYA); cvReleaseHist(&hist); cvReleaseImage(&src_bbox); cvReleaseMemStorage(&mem); delete h; return (val<min); }
CV_IMPL double cvPseudoInv( CvArr* srcarr, CvArr* dstarr, int flags ) { uchar* buffer = 0; int local_alloc = 0; double condition_number = 0; CV_FUNCNAME( "cvPseudoInv" ); __BEGIN__; CvMat astub, *a = (CvMat*)srcarr; CvMat bstub, *b = (CvMat*)dstarr; CvMat ustub, *u = &ustub; CvMat vstub, *v = &vstub; CvMat tmat; uchar* tw = 0; int type, n, m, nm, mn; int buf_size, pix_size; if( !CV_IS_ARR( a )) CV_CALL( a = cvGetMat( a, &astub )); if( !CV_IS_ARR( b )) CV_CALL( b = cvGetMat( b, &bstub )); if( !CV_ARE_TYPES_EQ( a, b )) CV_ERROR( CV_StsUnmatchedSizes, "" ); n = a->width; m = a->height; nm = MIN( n, m ); mn = MAX( n, m ); if( n != b->height || m != b->width ) CV_ERROR( CV_StsUnmatchedSizes, "" ); type = CV_ARR_TYPE( a->type ); pix_size = icvPixSize[type]; buf_size = nm*2 + mn + m*mn + n*n; if( !(flags & CV_SVD_MODIFY_A) ) buf_size += m*n; buf_size *= pix_size; if( buf_size <= CV_MAX_LOCAL_SIZE ) { buffer = (uchar*)alloca( buf_size ); local_alloc = 1; } else { CV_CALL( buffer = (uchar*)cvAlloc( buf_size )); } if( !(flags & CV_SVD_MODIFY_A) ) { cvInitMatHeader( &tmat, a->height, a->width, type, buffer + buf_size - n*m*pix_size ); cvCopy( a, &tmat ); a = &tmat; } tw = buffer + (nm + mn)*pix_size; cvInitMatHeader( u, m, m, type, tw + nm*pix_size ); cvInitMatHeader( v, n, n, type, u->data.ptr + m*mn*pix_size ); if( type == CV_32FC1 ) { IPPI_CALL( icvSVD_32f( a->data.fl, a->step/sizeof(float), (float*)tw, u->data.fl, u->step/sizeof(float), v->data.fl, v->step/sizeof(float), icvGetMatSize(a), (float*)buffer )); } else if( type == CV_64FC1 ) { IPPI_CALL( icvSVD_64f( a->data.db, a->step/sizeof(double), (double*)tw, u->data.db, u->step/sizeof(double), v->data.db, v->step/sizeof(double), icvGetMatSize(a), (double*)buffer )); } else { CV_ERROR( CV_StsUnsupportedFormat, "" ); } cvT( v, v ); cvGetRow( u, &tmat, 0 ); if( type == CV_32FC1 ) { for( int i = 0; i < nm; i++ ) { double t = ((float*)tw)[i]; tmat.data.ptr = u->data.ptr + i*u->step; t = t > FLT_EPSILON ? 1./t : 0; if( i == mn - 1 ) condition_number = t != 0 ? ((float*)tw)[0]*t : DBL_MAX; cvScale( &tmat, &tmat, t ); } } else { for( int i = 0; i < nm; i++ ) { double t = ((double*)tw)[i]; tmat.data.ptr = u->data.ptr + i*u->step; t = t > DBL_EPSILON ? 1./t : 0; if( i == mn - 1 ) condition_number = t != 0 ? ((double*)tw)[0]*t : DBL_MAX; cvScale( &tmat, &tmat, t ); } } u->height = n; if( n > m ) { cvGetSubArr( u, &tmat, cvRect( 0, m, m, n - m )); cvSetZero( &tmat ); } cvMatMulAdd( v, u, 0, b ); CV_CHECK_NANS( b ); __END__; if( buffer && !local_alloc ) cvFree( (void**)&buffer ); return condition_number; }
static CvStatus icvSnake8uC1R( unsigned char *src, int srcStep, CvSize roi, CvPoint * pt, int n, float *alpha, float *beta, float *gamma, int coeffUsage, CvSize win, CvTermCriteria criteria, int scheme ) { int i, j, k; int neighbors = win.height * win.width; int centerx = win.width >> 1; int centery = win.height >> 1; float invn; int iteration = 0; int converged = 0; float *Econt; float *Ecurv; float *Eimg; float *E; float _alpha, _beta, _gamma; /*#ifdef GRAD_SNAKE */ float *gradient = NULL; uchar *map = NULL; int map_width = ((roi.width - 1) >> 3) + 1; int map_height = ((roi.height - 1) >> 3) + 1; CvSepFilter pX, pY; #define WTILE_SIZE 8 #define TILE_SIZE (WTILE_SIZE + 2) short dx[TILE_SIZE*TILE_SIZE], dy[TILE_SIZE*TILE_SIZE]; CvMat _dx = cvMat( TILE_SIZE, TILE_SIZE, CV_16SC1, dx ); CvMat _dy = cvMat( TILE_SIZE, TILE_SIZE, CV_16SC1, dy ); CvMat _src = cvMat( roi.height, roi.width, CV_8UC1, src ); /* inner buffer of convolution process */ //char ConvBuffer[400]; /*#endif */ /* check bad arguments */ if( src == NULL ) return CV_NULLPTR_ERR; if( (roi.height <= 0) || (roi.width <= 0) ) return CV_BADSIZE_ERR; if( srcStep < roi.width ) return CV_BADSIZE_ERR; if( pt == NULL ) return CV_NULLPTR_ERR; if( n < 3 ) return CV_BADSIZE_ERR; if( alpha == NULL ) return CV_NULLPTR_ERR; if( beta == NULL ) return CV_NULLPTR_ERR; if( gamma == NULL ) return CV_NULLPTR_ERR; if( coeffUsage != CV_VALUE && coeffUsage != CV_ARRAY ) return CV_BADFLAG_ERR; if( (win.height <= 0) || (!(win.height & 1))) return CV_BADSIZE_ERR; if( (win.width <= 0) || (!(win.width & 1))) return CV_BADSIZE_ERR; invn = 1 / ((float) n); if( scheme == _CV_SNAKE_GRAD ) { pX.init_deriv( TILE_SIZE+2, CV_8UC1, CV_16SC1, 1, 0, 3 ); pY.init_deriv( TILE_SIZE+2, CV_8UC1, CV_16SC1, 0, 1, 3 ); gradient = (float *) cvAlloc( roi.height * roi.width * sizeof( float )); if( !gradient ) return CV_OUTOFMEM_ERR; map = (uchar *) cvAlloc( map_width * map_height ); if( !map ) { cvFree( &gradient ); return CV_OUTOFMEM_ERR; } /* clear map - no gradient computed */ memset( (void *) map, 0, map_width * map_height ); } Econt = (float *) cvAlloc( neighbors * sizeof( float )); Ecurv = (float *) cvAlloc( neighbors * sizeof( float )); Eimg = (float *) cvAlloc( neighbors * sizeof( float )); E = (float *) cvAlloc( neighbors * sizeof( float )); while( !converged ) { float ave_d = 0; int moved = 0; converged = 0; iteration++; /* compute average distance */ for( i = 1; i < n; i++ ) { int diffx = pt[i - 1].x - pt[i].x; int diffy = pt[i - 1].y - pt[i].y; ave_d += cvSqrt( (float) (diffx * diffx + diffy * diffy) ); } ave_d += cvSqrt( (float) ((pt[0].x - pt[n - 1].x) * (pt[0].x - pt[n - 1].x) + (pt[0].y - pt[n - 1].y) * (pt[0].y - pt[n - 1].y))); ave_d *= invn; /* average distance computed */ for( i = 0; i < n; i++ ) { /* Calculate Econt */ float maxEcont = 0; float maxEcurv = 0; float maxEimg = 0; float minEcont = _CV_SNAKE_BIG; float minEcurv = _CV_SNAKE_BIG; float minEimg = _CV_SNAKE_BIG; float Emin = _CV_SNAKE_BIG; int offsetx = 0; int offsety = 0; float tmp; /* compute bounds */ int left = MIN( pt[i].x, win.width >> 1 ); int right = MIN( roi.width - 1 - pt[i].x, win.width >> 1 ); int upper = MIN( pt[i].y, win.height >> 1 ); int bottom = MIN( roi.height - 1 - pt[i].y, win.height >> 1 ); maxEcont = 0; minEcont = _CV_SNAKE_BIG; for( j = -upper; j <= bottom; j++ ) { for( k = -left; k <= right; k++ ) { int diffx, diffy; float energy; if( i == 0 ) { diffx = pt[n - 1].x - (pt[i].x + k); diffy = pt[n - 1].y - (pt[i].y + j); } else { diffx = pt[i - 1].x - (pt[i].x + k); diffy = pt[i - 1].y - (pt[i].y + j); } Econt[(j + centery) * win.width + k + centerx] = energy = (float) fabs( ave_d - cvSqrt( (float) (diffx * diffx + diffy * diffy) )); maxEcont = MAX( maxEcont, energy ); minEcont = MIN( minEcont, energy ); } } tmp = maxEcont - minEcont; tmp = (tmp == 0) ? 0 : (1 / tmp); for( k = 0; k < neighbors; k++ ) { Econt[k] = (Econt[k] - minEcont) * tmp; } /* Calculate Ecurv */ maxEcurv = 0; minEcurv = _CV_SNAKE_BIG; for( j = -upper; j <= bottom; j++ ) { for( k = -left; k <= right; k++ ) { int tx, ty; float energy; if( i == 0 ) { tx = pt[n - 1].x - 2 * (pt[i].x + k) + pt[i + 1].x; ty = pt[n - 1].y - 2 * (pt[i].y + j) + pt[i + 1].y; } else if( i == n - 1 ) { tx = pt[i - 1].x - 2 * (pt[i].x + k) + pt[0].x; ty = pt[i - 1].y - 2 * (pt[i].y + j) + pt[0].y; } else { tx = pt[i - 1].x - 2 * (pt[i].x + k) + pt[i + 1].x; ty = pt[i - 1].y - 2 * (pt[i].y + j) + pt[i + 1].y; } Ecurv[(j + centery) * win.width + k + centerx] = energy = (float) (tx * tx + ty * ty); maxEcurv = MAX( maxEcurv, energy ); minEcurv = MIN( minEcurv, energy ); } } tmp = maxEcurv - minEcurv; tmp = (tmp == 0) ? 0 : (1 / tmp); for( k = 0; k < neighbors; k++ ) { Ecurv[k] = (Ecurv[k] - minEcurv) * tmp; } /* Calculate Eimg */ for( j = -upper; j <= bottom; j++ ) { for( k = -left; k <= right; k++ ) { float energy; if( scheme == _CV_SNAKE_GRAD ) { /* look at map and check status */ int x = (pt[i].x + k)/WTILE_SIZE; int y = (pt[i].y + j)/WTILE_SIZE; if( map[y * map_width + x] == 0 ) { int l, m; /* evaluate block location */ int upshift = y ? 1 : 0; int leftshift = x ? 1 : 0; int bottomshift = MIN( 1, roi.height - (y + 1)*WTILE_SIZE ); int rightshift = MIN( 1, roi.width - (x + 1)*WTILE_SIZE ); CvRect g_roi = { x*WTILE_SIZE - leftshift, y*WTILE_SIZE - upshift, leftshift + WTILE_SIZE + rightshift, upshift + WTILE_SIZE + bottomshift }; CvMat _src1; cvGetSubArr( &_src, &_src1, g_roi ); pX.process( &_src1, &_dx ); pY.process( &_src1, &_dy ); for( l = 0; l < WTILE_SIZE + bottomshift; l++ ) { for( m = 0; m < WTILE_SIZE + rightshift; m++ ) { gradient[(y*WTILE_SIZE + l) * roi.width + x*WTILE_SIZE + m] = (float) (dx[(l + upshift) * TILE_SIZE + m + leftshift] * dx[(l + upshift) * TILE_SIZE + m + leftshift] + dy[(l + upshift) * TILE_SIZE + m + leftshift] * dy[(l + upshift) * TILE_SIZE + m + leftshift]); } } map[y * map_width + x] = 1; } Eimg[(j + centery) * win.width + k + centerx] = energy = gradient[(pt[i].y + j) * roi.width + pt[i].x + k]; } else { Eimg[(j + centery) * win.width + k + centerx] = energy = src[(pt[i].y + j) * srcStep + pt[i].x + k]; } maxEimg = MAX( maxEimg, energy ); minEimg = MIN( minEimg, energy ); } } tmp = (maxEimg - minEimg); tmp = (tmp == 0) ? 0 : (1 / tmp); for( k = 0; k < neighbors; k++ ) { Eimg[k] = (minEimg - Eimg[k]) * tmp; } /* locate coefficients */ if( coeffUsage == CV_VALUE) { _alpha = *alpha; _beta = *beta; _gamma = *gamma; } else { _alpha = alpha[i]; _beta = beta[i]; _gamma = gamma[i]; } /* Find Minimize point in the neighbors */ for( k = 0; k < neighbors; k++ ) { E[k] = _alpha * Econt[k] + _beta * Ecurv[k] + _gamma * Eimg[k]; } Emin = _CV_SNAKE_BIG; for( j = -upper; j <= bottom; j++ ) { for( k = -left; k <= right; k++ ) { if( E[(j + centery) * win.width + k + centerx] < Emin ) { Emin = E[(j + centery) * win.width + k + centerx]; offsetx = k; offsety = j; } } } if( offsetx || offsety ) { pt[i].x += offsetx; pt[i].y += offsety; moved++; } } converged = (moved == 0); if( (criteria.type & CV_TERMCRIT_ITER) && (iteration >= criteria.max_iter) ) converged = 1; if( (criteria.type & CV_TERMCRIT_EPS) && (moved <= criteria.epsilon) ) converged = 1; } cvFree( &Econt ); cvFree( &Ecurv ); cvFree( &Eimg ); cvFree( &E ); if( scheme == _CV_SNAKE_GRAD ) { cvFree( &gradient ); cvFree( &map ); } return CV_OK; }
static CvStatus icvSnakeTrack8uC1R( unsigned char *src, int srcStep, CvSize roi, CvPoint * pt, int n, float *alpha, float *beta, float *gamma, int coeffUsage, CvSize win, CvTermCriteria criteria, int scheme , unsigned char *osrc, //original image where contours are generated. CvPoint *opt, //weights of the original fit float *oalpha, float *obeta, float *ogamma, float *oteta, float *ozeta, float *oomega, IplImage *dux, IplImage *odux, IplImage *duy, IplImage *oduy, float *oEarc_static = NULL, bool oEarc_static_ready = false, int *iterations = NULL) { int i, j, k; int neighbors = win.height * win.width; int centerx = win.width >> 1; int centery = win.height >> 1; float invn; int iteration = 0; int converged = 0; float *E; float _alpha=*alpha, _beta=*beta, _gamma=*gamma; /*#ifdef GRAD_SNAKE */ float *gradient = NULL; uchar *map = NULL; int map_width = ((roi.width - 1) >> 3) + 1; int map_height = ((roi.height - 1) >> 3) + 1; CvSepFilter pX, pY; #define WTILE_SIZE 8 #define TILE_SIZE (WTILE_SIZE + 2) short dx[TILE_SIZE*TILE_SIZE], dy[TILE_SIZE*TILE_SIZE]; CvMat _dx = cvMat( TILE_SIZE, TILE_SIZE, CV_16SC1, dx ); CvMat _dy = cvMat( TILE_SIZE, TILE_SIZE, CV_16SC1, dy ); CvMat _src = cvMat( roi.height, roi.width, CV_8UC1, src ); /* inner buffer of convolution process */ //char ConvBuffer[400]; /*#endif */ /* check bad arguments */ if( src == NULL ) return CV_NULLPTR_ERR; if( osrc == NULL ) return CV_NULLPTR_ERR; if( (roi.height <= 0) || (roi.width <= 0) ) return CV_BADSIZE_ERR; if( srcStep < roi.width ) return CV_BADSIZE_ERR; if( pt == NULL ) return CV_NULLPTR_ERR; if( n < 3 ) return CV_BADSIZE_ERR; if( alpha == NULL ) return CV_NULLPTR_ERR; if( beta == NULL ) return CV_NULLPTR_ERR; if( gamma == NULL ) return CV_NULLPTR_ERR; if( oalpha == NULL ) return CV_NULLPTR_ERR; if( obeta == NULL ) return CV_NULLPTR_ERR; if( ogamma == NULL ) return CV_NULLPTR_ERR; if( oteta == NULL ) return CV_NULLPTR_ERR; if( ozeta == NULL ) return CV_NULLPTR_ERR; if( coeffUsage != CV_VALUE && coeffUsage != CV_ARRAY ) return CV_BADFLAG_ERR; if( (win.height <= 0) || (!(win.height & 1))) return CV_BADSIZE_ERR; if( (win.width <= 0) || (!(win.width & 1))) return CV_BADSIZE_ERR; invn = 1 / ((float) n); if( scheme == _CV_SNAKE_GRAD ) { pX.init_deriv( TILE_SIZE+2, CV_8UC1, CV_16SC1, 1, 0, 3 ); pY.init_deriv( TILE_SIZE+2, CV_8UC1, CV_16SC1, 0, 1, 3 ); gradient = (float *) cvAlloc( roi.height * roi.width * sizeof( float )); memset((void*)gradient, 0, roi.height*roi.width*sizeof(float)); if( !gradient ) return CV_OUTOFMEM_ERR; map = (uchar *) cvAlloc( map_width * map_height ); if( !map ) { cvFree( &gradient ); return CV_OUTOFMEM_ERR; } /* clear map - no gradient computed */ memset( (void *) map, 0, map_width * map_height ); } E = (float *) cvAlloc( neighbors * sizeof( float )); //------------------------- Original Image Parameters ---------------- float _oalpha=*oalpha, _obeta=*obeta, _ogamma=*ogamma, _oteta=*oteta, _ozeta=*ozeta, _oomega=*oomega; CvMat _osrc = cvMat( roi.height, roi.width, CV_8UC1, osrc ); int roisize=roi.width*roi.width; #define INIT_ENERGY_TERM(X) \ float *X = (float *) cvAlloc( neighbors * sizeof( float )); \ float *o##X = (float *) cvAlloc( n * sizeof( float )); \ float *os##X = (float *) cvAlloc( n * sizeof( float )); \ memset(X, 0, neighbors * sizeof(float)); \ memset(o##X, 0, n * sizeof(float)); \ memset(os##X, 0, n * sizeof(float)); INIT_ENERGY_TERM(Econt) INIT_ENERGY_TERM(Ecurv) INIT_ENERGY_TERM(Eimg) INIT_ENERGY_TERM(Eint) INIT_ENERGY_TERM(Earc) INIT_ENERGY_TERM(Edux) INIT_ENERGY_TERM(Eduy) //------------------------ //End Original Image Parameters CvMat *_srcp; unsigned char *srcp; CvPoint *ppt; IplImage *pdux, *pduy; for (int isoriginit=0; isoriginit<2; isoriginit++){ if (!isoriginit){ ppt=opt; _srcp=&_osrc; srcp=osrc; pdux = odux; pduy = oduy; } else{ ppt=pt; _srcp=&_src; srcp=src; converged=0; iteration=0; if( scheme == _CV_SNAKE_GRAD ) memset( (void *) map, 0, map_width * map_height ); pdux = dux; pduy = duy; } while( !converged ) { float ave_d = 0; int moved = 0; converged = 0; iteration++; /* compute average distance */ for( i = 1; i < n; i++ ) { int diffx = ppt[i - 1].x - ppt[i].x; int diffy = ppt[i - 1].y - ppt[i].y; ave_d += cvSqrt( (float) (diffx * diffx + diffy * diffy) ); } ave_d += cvSqrt( (float) ((ppt[0].x - ppt[n - 1].x) * (ppt[0].x - ppt[n - 1].x) + (ppt[0].y - ppt[n - 1].y) * (ppt[0].y - ppt[n - 1].y))); ave_d *= invn; /* average distance computed */ for( i = 0; i < n; i++ ) { float Emin = _CV_SNAKE_BIG; float maxEcont = 0, minEcont = _CV_SNAKE_BIG; float maxEcurv = 0, minEcurv = _CV_SNAKE_BIG; float maxEimg = 0, minEimg = _CV_SNAKE_BIG; float maxEint = 0, minEint = _CV_SNAKE_BIG; float maxEarc = 0, minEarc = _CV_SNAKE_BIG; float maxEdux = 0, minEdux = _CV_SNAKE_BIG; float maxEduy = 0, minEduy = _CV_SNAKE_BIG; int offsetx = 0; int offsety = 0; float tmp, energy; int diffx, diffy; // compute bounds int left = MIN( ppt[i].x, win.width >> 1 ); int right = MIN( roi.width - 1 - ppt[i].x, win.width >> 1 ); int upper = MIN( ppt[i].y, win.height >> 1 ); int bottom = MIN( roi.height - 1 - ppt[i].y, win.height >> 1 ); // Calculate Econt if (!(alpha==0 || oalpha==0)){ for( j = -upper; j <= bottom; j++ ) { for( k = -left; k <= right; k++ ) { if( i == 0 ) { diffx = ppt[n - 1].x - (ppt[i].x + k); diffy = ppt[n - 1].y - (ppt[i].y + j); } else { diffx = ppt[i - 1].x - (ppt[i].x + k); diffy = ppt[i - 1].y - (ppt[i].y + j); } Econt[(j + centery) * win.width + k + centerx] = energy = (float) fabs( ave_d - cvSqrt( (float) (diffx * diffx + diffy * diffy) )); maxEcont = MAX( maxEcont, energy ); minEcont = MIN( minEcont, energy ); } } if(isoriginit){ tmp = maxEcont - minEcont; tmp = (tmp == 0) ? 0 : (1 / tmp); for( k = 0; k < neighbors; k++ ) Econt[k] = (Econt[k] - minEcont) * tmp; osEcont[i] = (oEcont[i] - minEcont)*tmp; } } // Calculate Ecurv if (!(beta==0 || obeta==0)) { for( j = -upper; j <= bottom; j++ ) { for( k = -left; k <= right; k++ ) { int tx, ty; if( i == 0 ) { tx = ppt[n - 1].x - 2 * (ppt[i].x + k) + ppt[i + 1].x; ty = ppt[n - 1].y - 2 * (ppt[i].y + j) + ppt[i + 1].y; } else if( i == n - 1 ) { tx = ppt[i - 1].x - 2 * (ppt[i].x + k) + ppt[0].x; ty = ppt[i - 1].y - 2 * (ppt[i].y + j) + ppt[0].y; } else { tx = ppt[i - 1].x - 2 * (ppt[i].x + k) + ppt[i + 1].x; ty = ppt[i - 1].y - 2 * (ppt[i].y + j) + ppt[i + 1].y; } Ecurv[(j + centery) * win.width + k + centerx] = energy = (float) (tx * tx + ty * ty); maxEcurv = MAX( maxEcurv, energy ); minEcurv = MIN( minEcurv, energy ); } } if(isoriginit){ tmp = maxEcurv - minEcurv; tmp = (tmp == 0) ? 0 : (1 / tmp); for( k = 0; k < neighbors; k++ ) Ecurv[k] = (Ecurv[k] - minEcurv) * tmp; osEcurv[i] = (oEcurv[i] - minEcurv)*tmp; } } // Calculate Eimg if (!(gamma==0 || ogamma==0)) { for( j = -upper; j <= bottom; j++ ) { for( k = -left; k <= right; k++ ) { if( scheme == _CV_SNAKE_GRAD ) { // look at map and check status int x = (ppt[i].x + k)/WTILE_SIZE; int y = (ppt[i].y + j)/WTILE_SIZE; if( map[y * map_width + x] == 0 ) { int l, m; // evaluate block location int upshift = y ? 1 : 0; int leftshift = x ? 1 : 0; int bottomshift = MIN( 1, roi.height - (y + 1)*WTILE_SIZE ); int rightshift = MIN( 1, roi.width - (x + 1)*WTILE_SIZE ); CvRect g_roi = { x*WTILE_SIZE - leftshift, y*WTILE_SIZE - upshift, leftshift + WTILE_SIZE + rightshift, upshift + WTILE_SIZE + bottomshift }; CvMat _src1; cvGetSubArr( _srcp, &_src1, g_roi ); pX.process( &_src1, &_dx ); pY.process( &_src1, &_dy ); for( l = 0; l < WTILE_SIZE + bottomshift; l++ ) { for( m = 0; m < WTILE_SIZE + rightshift; m++ ) { gradient[(y*WTILE_SIZE + l) * roi.width + x*WTILE_SIZE + m] = (float) (dx[(l + upshift) * TILE_SIZE + m + leftshift] * dx[(l + upshift) * TILE_SIZE + m + leftshift] + dy[(l + upshift) * TILE_SIZE + m + leftshift] * dy[(l + upshift) * TILE_SIZE + m + leftshift]); } } map[y * map_width + x] = 1; } Eimg[(j + centery) * win.width + k + centerx] = energy = gradient[(ppt[i].y + j) * roi.width + ppt[i].x + k]; } else Eimg[(j + centery) * win.width + k + centerx] = energy = srcp[(ppt[i].y + j) * srcStep + ppt[i].x + k]; maxEimg = MAX( maxEimg, energy ); minEimg = MIN( minEimg, energy ); } } if(isoriginit){ tmp = (maxEimg - minEimg); tmp = (tmp == 0) ? 0 : (1 / tmp); for( k = 0; k < neighbors; k++ ) Eimg[k] = (minEimg - Eimg[k]) * tmp; osEimg[i] = (minEimg - oEimg[i])*tmp; } } // Calculate Eint if (oteta!=0) { for( j = -upper; j <= bottom; j++ ) { for( k = -left; k <= right; k++ ) { Eint[(j + centery) * win.width + k + centerx] = energy = srcp[(ppt[i].y + j) * srcStep + ppt[i].x + k]; maxEint = MAX( maxEint, energy ); minEint = MIN( minEint, energy ); } } if (isoriginit){ tmp = maxEint - minEint; tmp = (tmp == 0) ? 0 : (1 / tmp); for( k = 0; k < neighbors; k++ ) Eint[k] = (Eint[k] - minEint) * tmp; osEint[i] = (oEint[i] - minEint)*tmp; } } // Calculate Earc if (ozeta!=0) { for( j = -upper; j <= bottom; j++ ) { for( k = -left; k <= right; k++ ) { int diff2x,diff2y; if( i == 0 ) { diffx = opt[n - 1].x - (ppt[i].x + k); diffy = opt[n - 1].y - (ppt[i].y + j); } else { diffx = opt[i - 1].x - (ppt[i].x + k); diffy = opt[i - 1].y - (ppt[i].y + j); } if( i == n-1 ) { diff2x = opt[0].x - (ppt[i].x + k); diff2y = opt[0].y - (ppt[i].y + j); } else { diff2x = opt[i + 1].x - (ppt[i].x + k); diff2y = opt[i + 1].y - (ppt[i].y + j); } Earc[(j + centery) * win.width + k + centerx] = energy = cvSqrt( (float) (diffx * diffx + diffy * diffy) ) + cvSqrt( (float) (diff2x * diff2x + diff2y * diff2y) ); maxEarc = MAX( maxEarc, energy ); minEarc = MIN( minEarc, energy ); } } if (isoriginit){ tmp = maxEarc - minEarc; tmp = (tmp == 0) ? 0 : (1 / tmp); for( k = 0; k < neighbors; k++ ) Earc[k] = (Earc[k] - minEarc) * tmp; osEarc[i] = (oEarc[i] - minEarc)*tmp; } } // Calculate Edu-x/y gradients if (oomega!=0) { for( j = -upper; j <= bottom; j++ ) { for( k = -left; k <= right; k++ ) { float energyy; Edux[(j + centery) * win.width + k + centerx] = energy = (float)pdux->imageData[(ppt[i].y + j) * pdux->widthStep + ppt[i].x + k]; Eduy[(j + centery) * win.width + k + centerx] = energyy = (float)pduy->imageData[(ppt[i].y + j) * pduy->widthStep + ppt[i].x + k]; maxEdux = MAX( maxEdux, energy ); minEdux = MIN( minEdux, energy ); maxEduy = MAX( maxEduy, energyy ); minEduy = MIN( minEduy, energyy ); } } if (isoriginit){ tmp = maxEdux - minEdux; tmp = (tmp == 0) ? 0 : (1 / tmp); for( k = 0; k < neighbors; k++ ) Edux[k] = (Edux[k] - minEdux) * tmp; osEdux[i] = (oEdux[i] - minEdux)*tmp; tmp = maxEduy - minEduy; tmp = (tmp == 0) ? 0 : (1 / tmp); for( k = 0; k < neighbors; k++ ) Eduy[k] = (Eduy[k] - minEduy) * tmp; osEduy[i] = (oEduy[i] - minEduy)*tmp; } } //---------------------- //end E calculations. int loci=centery*win.width+centerx; if (!isoriginit){ //Initialize Original image parameters oEcont[i] = Econt[loci]; oEcurv[i] = Ecurv[loci]; oEimg[i] = Eimg[loci]; oEint[i] = Eint[loci]; if (oEarc_static){ if (oEarc_static_ready) oEarc[i] = oEarc_static[i]; else oEarc[i] = oEarc_static[i] = Earc[loci]; } else oEarc[i] = Earc[loci]; oEdux[i] = Edux[loci]; oEduy[i] = Eduy[loci]; } else{ /* locate coefficients */ if( coeffUsage != CV_VALUE) { _alpha = alpha[i]; _beta = beta[i]; _gamma = gamma[i]; _oalpha = oalpha[i]; _obeta = obeta[i]; _ogamma = ogamma[i]; _oteta = oteta[i]; _ozeta = ozeta[i]; _oomega = oomega[i]; } /* Find Minimize point in the neighbors */ for( k = 0; k < neighbors; k++ ) { E[k] = _alpha * Econt[k] + _beta * Ecurv[k] + _gamma * Eimg[k] + _oalpha*fabs(Econt[k]-osEcont[i]) + _obeta*fabs(Ecurv[k]-osEcurv[i]) + _ogamma*fabs(Eimg[k]-osEimg[i]) + _oteta*fabs(Eint[k]-osEint[i]) + _ozeta*fabs(Earc[k]-osEarc[i]) + _oomega*(fabs(Edux[k]-osEdux[i])+fabs(Eduy[k]-osEduy[i])) ; } // Emin = _CV_SNAKE_BIG; Emin = E[loci]; for( j = -upper; j <= bottom; j++ ) { for( k = -left; k <= right; k++ ) { if( E[(j + centery) * win.width + k + centerx] < Emin )// || (E[(j + centery) * win.width + k + centerx] == Emin && rand()%2)) { Emin = E[(j + centery) * win.width + k + centerx]; offsetx = k; offsety = j; } } } if( offsetx || offsety ) { ppt[i].x += offsetx; ppt[i].y += offsety; moved++; } }//originit /* //Debugging: display gradient image float maxgrad=0; float mingrad=_CV_SNAKE_BIG; for(j=0; j<roi.width; j++){ for(k=0; k<roi.height; k++){ float grad=gradient[k*roi.width+j]; if(grad<mingrad) mingrad=grad; if(grad>maxgrad) maxgrad=grad; } } IplImage *gray = cvCreateImage( cvSize(roi.width, roi.height), IPL_DEPTH_8U, 1 ); tmp = (maxEimg - minEimg); tmp = (tmp == 0) ? 0 : (1 / tmp); for(j=0; j<roi.width; j++){ for(k=0; k<roi.height; k++){ float grad=gradient[k*roi.width+j]; cvSetReal2D(gray,k,j,((grad-mingrad)*tmp*255)); } } cvNamedWindow("tmp"); cvShowImage("tmp",gray); cvReleaseImage(&gray); cvWaitKey(100); */ }//for n converged = (moved == 0); if( (criteria.type & CV_TERMCRIT_ITER) && (iteration >= criteria.max_iter) ) converged = 1; if( (criteria.type & CV_TERMCRIT_EPS) && (moved <= criteria.epsilon) ) converged = 1; }//while !converged }//for isoriginit cvFree( &E ); cvFree( &Econt ); cvFree( &oEcont ); cvFree( &osEcont ); cvFree( &Ecurv ); cvFree( &oEcurv ); cvFree( &osEcurv ); cvFree( &Eimg ); cvFree( &oEimg ); cvFree( &osEimg ); cvFree( &Eint ); cvFree( &oEint ); cvFree( &osEint ); cvFree( &Earc ); cvFree( &oEarc ); cvFree( &osEarc ); cvFree( &Edux ); cvFree( &oEdux ); cvFree( &osEdux ); cvFree( &Eduy ); cvFree( &oEduy ); cvFree( &osEduy ); if( scheme == _CV_SNAKE_GRAD ) { cvFree( &gradient ); cvFree( &map ); } if(iterations) *iterations = iteration; return CV_OK; }