BOOT_CODE bool_t add_allocated_p_region(p_region_t reg) { unsigned int i, j; assert(reg.start <= reg.end); assert(!p_region_overlaps(reg)); /* Walk the existing regions and see if we can merge with an existing * region, or insert in order */ for (i = 0; i < allocated_p_regions.cur_pos; i++) { /* see if we can merge before or after this region */ if (allocated_p_regions.regs[i].end == reg.start) { allocated_p_regions.regs[i].end = reg.end; merge_regions(); return true; } if (allocated_p_regions.regs[i].start == reg.end) { allocated_p_regions.regs[i].start = reg.start; merge_regions(); return true; } /* see if this new one should be inserted before */ if (reg.end < allocated_p_regions.regs[i].start) { /* ensure there's space to bump the regions up */ if (allocated_p_regions.cur_pos + 1 == NUM_RESERVED_REGIONS) { printf("Ran out of reserved physical regions\n"); return false; } /* Copy the regions up to make a gap */ for (j = allocated_p_regions.cur_pos; j != i; j--) { allocated_p_regions.regs[j] = allocated_p_regions.regs[j - 1]; } /* Put this region in the gap */ allocated_p_regions.regs[i] = reg; allocated_p_regions.cur_pos++; return true; } } /* nothing else matched, put this one at the end */ if (i + 1 == NUM_RESERVED_REGIONS) { printf("Ran out of reserved physical regions\n"); return false; } allocated_p_regions.regs[i] = reg; allocated_p_regions.cur_pos = i + 1; return true; }
void AbsScarRegionDetector::insert_point(float * d, bool is_correct){ if(!this->is_valid(d)) return; /* * try and optimistically find a region the float belongs to */ int id = find_region(d); // case: update an existing a group if(id > 0 || !is_correct){ this->update_train_regions(id,d,is_correct); //updates statistics. return; } // case: create a new group //create a new node. region_t * r = new region_t[1]; this->allocate_region(r,d); this->regions[this->n_regions] = r; this->n_regions++; this->update_train_regions(this->n_regions-1,d, is_correct); //add region //if we're full of space, make room for another region. if(this->n_regions == this->max_regions){ //if we're full. //find the region with the most similar dynamics that isn't //completely obstructed by another region. int merge_1=-1; int merge_2=-1; float score = 0; for(int i=0; i < this->n_regions; i++){ float tmp_score=0; int tmp_other = find_closest_region(i, &tmp_score); if(merge_1 < 0 || tmp_score > score){ score = tmp_score; merge_1 = i; merge_2 = tmp_other; } } merge_regions(merge_1, merge_2); this->n_regions--; } /* * */ }
static void build_regions( Segmenter *s, const unsigned char *source ) { //Span *new_span; int x, y, i; RegionReference **current_row = &s->regions_under_construction[0]; RegionReference **previous_row = &s->regions_under_construction[s->width]; s->region_ref_count = 0; s->region_count = 0; s->freed_regions_head = 0; // top line x = 0; y = 0; current_row[0] = new_region( s, x, y, source[0] ); current_row[0]->region->flags |= ADJACENT_TO_ROOT_REGION_FLAG; for( x=1, y=0, i=1 ; x < s->width; ++x, ++i ){ if( source[i] == source[i-1] ){ current_row[x] = current_row[x-1]; }else{ // current_row[x-1]->region->last_span->end=i-1; // current_row[x-1]->region->area += i-current_row[x-1]->region->last_span->start; current_row[x] = new_region( s, x, y, source[i] ); current_row[x]->region->flags |= ADJACENT_TO_ROOT_REGION_FLAG; make_adjacent( s, current_row[x]->region, current_row[x-1]->region ); } } // process lines for( y=1; y < s->height; ++y ){ // swap previous and current rows RegionReference **temp = previous_row; previous_row = current_row; current_row = temp; i = y * s->width; x = 0; // left edge RESOLVE_REGIONREF_REDIRECTS( previous_row[x], previous_row[x] ); if( source[i] == previous_row[x]->region->colour ){ current_row[x] = previous_row[x]; /* new_span = LOOKUP_SEGMENTER_SPAN( s, i ); new_span->start = i; new_span->end = i; new_span->next = NULL; current_row[x]->region->last_span->next = new_span; current_row[x]->region->last_span = new_span; */ }else{ // source[i] != previous_row[x]->colour current_row[x] = new_region( s, x, y, source[i] ); current_row[x]->region->flags |= ADJACENT_TO_ROOT_REGION_FLAG; make_adjacent( s, current_row[x]->region, previous_row[x]->region ); } ++i; x=1; // center span for( ; x < s->width; ++x, ++i ){ //RESOLVE_REGIONREF_REDIRECTS( current_row[x-1], current_row[x-1] ); // this isn't needed because the the west cell's redirect is always up to date RESOLVE_REGIONREF_REDIRECTS( previous_row[x], previous_row[x] ); if( source[i] == source[i-1] ){ current_row[x] = current_row[x-1]; if( current_row[x] != previous_row[x] && source[i] == previous_row[x]->region->colour ){ // merge the current region into the previous one // this should be more efficient than merging the previous // into the current because it keeps long-lived regions // alive and only frees newer (less connected?) ones /* previous_row[x]->region->last_span->next = current_row[x]->region->first_span; previous_row[x]->region->last_span = current_row[x]->region->last_span; previous_row[x]->region->area += current_row[x]->region->area; */ merge_regions( s, previous_row[x]->region, current_row[x]->region ); current_row[x]->region->flags = FREE_REGION_FLAG; current_row[x]->region->next = s->freed_regions_head; s->freed_regions_head = current_row[x]->region; current_row[x]->region = 0; current_row[x]->redirect = previous_row[x]; current_row[x] = previous_row[x]; } }else{ // source_image_[i] != source_image_[i-1] /* current_row[x-1]->region->last_span->end=i-1; // set the span end, it is more efficient here current_row[x-1]->region->area+=i-current_row[x-1]->region->last_span->start; // mark single pixels fragmented if (current_row[x-1]->region->area<=REGION_GATE_AREA) { if (((y+1)==s->height) || (source[i-1]!=source[i-1+s->width])) make_fragmented(current_row[x-1]->region); } */ if( current_row[x-1]->region->right < x - 1 ) current_row[x-1]->region->right = (short)( x - 1 ); if( source[i] == previous_row[x]->region->colour ){ current_row[x] = previous_row[x]; current_row[x]->region->bottom = (short)y; /* new_span = LOOKUP_SEGMENTER_SPAN( s, i ); new_span->start = i; new_span->end = i; new_span->next = NULL; current_row[x]->region->last_span->next = new_span; current_row[x]->region->last_span = new_span; */ }else{ current_row[x] = new_region( s, x, y, source[i] ); make_adjacent( s, current_row[x]->region, previous_row[x]->region ); if( current_row[x-1]->region != previous_row[x]->region ) make_adjacent( s, current_row[x]->region, current_row[x-1]->region ); } } } // right edge current_row[s->width-1]->region->flags |= ADJACENT_TO_ROOT_REGION_FLAG; // current_row[s->width-1]->region->last_span->end=i; // current_row[x-1]->region->area+=i-current_row[x-1]->region->last_span->start+2; } // make regions of bottom row adjacent or merge with root for( x = 0; x < s->width; ++x ){ RESOLVE_REGIONREF_REDIRECTS( current_row[x], current_row[x] ); current_row[x]->region->flags |= ADJACENT_TO_ROOT_REGION_FLAG; } }
void mexFunction(int nlhs, /* No. of output arguments */ mxArray *plhs[], /* Output arguments. */ int nrhs, /* No. of input arguments. */ const mxArray *prhs[]) /* Input arguments. */ { int i=0; int ndim=0, lima_ndim=0; int nc=0, nr=0, ni=0; const int *cdim=NULL, *lima_cdim=NULL; unsigned int dim[3]; int *nn=NULL; int *rs=NULL; int *rw=NULL; int *lima=NULL; double *pp=NULL; double *pm=NULL; double *d_tmp=NULL; double *opm=NULL; if (nrhs == 0) mexErrMsgTxt("usage: pm = pm_merge_regions(pm,lima,i,j,n,p,rs)"); if (nrhs != 7) mexErrMsgTxt("pm_merge_regions: 7 input arguments required"); /* if (nlhs != 1) mexErrMsgTxt("pm_merge_regions: 1 output argument required"); */ /* Get phase map. */ if (!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) || !mxIsDouble(prhs[0])) { mexErrMsgTxt("pm_merge_regions: pm must be numeric, real, full and double"); } ndim = mxGetNumberOfDimensions(prhs[0]); if ((ndim < 2) | (ndim > 3)) { mexErrMsgTxt("pm_merge_regions: pm must be 2 or 3-dimensional"); } cdim = mxGetDimensions(prhs[0]); pm = mxGetPr(prhs[0]); /* Get image of labels. */ if (!mxIsNumeric(prhs[1]) || mxIsComplex(prhs[1]) || mxIsSparse(prhs[1]) || !mxIsDouble(prhs[1])) { mexErrMsgTxt("pm_merge_regions: lima must be numeric, real, full and double"); } lima_ndim = mxGetNumberOfDimensions(prhs[1]); if (lima_ndim != ndim) { mexErrMsgTxt("pm_merge_regions: pm and lima must have same dimensionality"); } lima_cdim = mxGetDimensions(prhs[1]); for (i=0; i<ndim; i++) { if (cdim[i] != lima_cdim[i]) { mexErrMsgTxt("pm_merge_regions: pm and lima must have same size"); } } d_tmp = mxGetPr(prhs[1]); /* Fix dimensions to allow for 2D and 3D data. */ dim[0]=cdim[0]; dim[1]=cdim[1]; if (ndim==2) {dim[2]=1; ndim=3;} else {dim[2]=cdim[2];} for (i=0, ni=1; i<ndim; i++) { ni *= dim[i]; } /* Convert double representation of lima into int's. */ lima = (int *) mxCalloc(ni,sizeof(int)); for (i=0; i<ni; i++) {lima[i] = ((int) (d_tmp[i]+0.1));} /* Get vector of row indicies into connectogram matrix */ if (!mxIsNumeric(prhs[2]) || mxIsComplex(prhs[2]) || mxIsSparse(prhs[2]) || !mxIsDouble(prhs[2])) { mexErrMsgTxt("pm_merge_regions: i must be numeric, real, full and double"); } nc = mxGetM(prhs[2]); d_tmp = mxGetPr(prhs[2]); if (mxGetN(prhs[2]) != 1) { mexErrMsgTxt("pm_merge_regions: i must be a column matrix"); } ii = (int *) mxCalloc(nc,sizeof(int)); for (i=0; i<nc; i++) {ii[i] = ((int) (d_tmp[i]+0.1));} /* Get vector of column indicies into connectogram matrix */ if (!mxIsNumeric(prhs[3]) || mxIsComplex(prhs[3]) || mxIsSparse(prhs[3]) || !mxIsDouble(prhs[3])) { mexErrMsgTxt("pm_merge_regions: j must be numeric, real, full and double"); } if (mxGetM(prhs[3]) != nc || mxGetN(prhs[3]) != 1) { mexErrMsgTxt("pm_merge_regions: j must be a column matrix of same size as i"); } d_tmp = mxGetPr(prhs[3]); jj = (int *) mxCalloc(nc,sizeof(int)); for (i=0; i<nc; i++) {jj[i] = ((int) (d_tmp[i]+0.1));} /* Get entrys for first connectogram matrix (containing border sizes). */ if (!mxIsNumeric(prhs[4]) || mxIsComplex(prhs[4]) || mxIsSparse(prhs[4]) || !mxIsDouble(prhs[4])) { mexErrMsgTxt("pm_merge_regions: n must be numeric, real, full and double"); } if (mxGetM(prhs[4]) != nc || mxGetN(prhs[4]) != 1) { mexErrMsgTxt("pm_merge_regions: n must be a column matrix of same size as i"); } d_tmp = mxGetPr(prhs[4]); nn = (int *) mxCalloc(nc,sizeof(int)); for (i=0; i<nc; i++) {nn[i] = ((int) (d_tmp[i]+0.1));} /* Get entrys for second connectogram matrix (containing phase differences along borders). */ if (!mxIsNumeric(prhs[5]) || mxIsComplex(prhs[5]) || mxIsSparse(prhs[5]) || !mxIsDouble(prhs[5])) { mexErrMsgTxt("pm_merge_regions: p must be numeric, real, full and double"); } if (mxGetM(prhs[5]) != nc || mxGetN(prhs[5]) != 1) { mexErrMsgTxt("pm_merge_regions: p must be a column matrix of same size as i"); } d_tmp = mxGetPr(prhs[5]); pp = (double *) mxCalloc(nc,sizeof(double)); /* Use local copy to avoid side effects. */ memcpy(pp,d_tmp,nc*sizeof(double)); /* Get vector of region sizes (in voxels) */ if (!mxIsNumeric(prhs[6]) || mxIsComplex(prhs[6]) || mxIsSparse(prhs[6]) || !mxIsDouble(prhs[6])) { mexErrMsgTxt("pm_merge_regions: rs must be numeric, real, full and double"); } nr = mxGetM(prhs[6]); d_tmp = mxGetPr(prhs[6]); if (mxGetN(prhs[6]) != 1) { mexErrMsgTxt("pm_merge_regions: rs must be a column matrix"); } rs = (int *) mxCalloc(nr,sizeof(int)); for (i=0; i<nr; i++) {rs[i] = ((int) (d_tmp[i]+0.1));} /* Allocate mem for unwrapped output phasemap. */ plhs[0] = mxCreateNumericArray(mxGetNumberOfDimensions(prhs[0]), mxGetDimensions(prhs[0]),mxDOUBLE_CLASS,mxREAL); opm = mxGetPr(plhs[0]); rw = (int *) mxCalloc(nr,sizeof(int)); merge_regions(nn,pp,nc,rs,nr,rw); for (i=0; i<ni; i++) { if (lima[i]) {opm[i] = pm[i] + 2.0*PI*rw[lima[i]-1];} else {opm[i] = pm[i];} } mxFree(lima); mxFree(ii); mxFree(jj); mxFree(nn); mxFree(pp); mxFree(rs); return; }