docs: public boolean process( T image ) {
  
  		if( failed )
  			return false;
  
  		targetModel.setImage(image);
  
  		// mark the region where the pdf has been modified as dirty
  		dirty.set(location.x0, location.y0, location.x0 + location.width, location.y0 + location.height);
  		// compute the pdf inside the initial rectangle
  		updatePdfImage(location.x0 , location.y0 , location.x0+location.width , location.y0+location.height);
  
  		// current location of the target
  		int x0 = location.x0;
  		int y0 = location.y0;
  
  		// previous location of the target in the most recent iteration
  		int prevX = x0;
  		int prevY = y0;
  
  		// iterate until it converges or reaches the maximum number of iterations
  		for( int i = 0; i < maxIterations; i++ ) {
  
  			// compute the weighted centroid using the likelihood function
  			float totalPdf = 0;
  			float sumX = 0;
  			float sumY = 0;
  
  			for( int y = 0; y < location.height; y++ ) {
  				int indexPdf = pdf.startIndex + pdf.stride*(y+y0) + x0;
  				for( int x = 0; x < location.width; x++ ) {
  					float p = pdf.data[indexPdf++];
  
  					totalPdf += p;
  					sumX += (x0+x)*p;
  					sumY += (y0+y)*p;
  				}
  			}
  
  			// if the target isn't likely to be in view, give up
  			if( totalPdf <= minimumSum ) {
  				failed = true;
  				return false;
  			}
  
  			// Use the new center to find the new top left corner, while rounding to the nearest integer
  			x0 = (int)(sumX/totalPdf-location.width/2+0.5f);
  			y0 = (int)(sumY/totalPdf-location.height/2+0.5f);
  
  			// make sure it doesn't go outside the image
  			if( x0 < 0 )
  				x0 = 0;
  			else if( x0 >= image.width-location.width )
  				x0 = image.width-location.width;
  
  			if( y0 < 0 )
  				y0 = 0;
  			else if( y0 >= image.height-location.height )
  				y0 = image.height-location.height;
  
  			// see if it has converged
  			if( x0 == prevX && y0 == prevY )
  				break;
  
  			// save the previous location
  			prevX = x0;
  			prevY = y0;
  
  			// update the pdf
  			updatePdfImage(x0,y0,x0+location.width,y0+location.height);
  		}
  
  		// update the output
  		location.x0 = x0;
  		location.y0 = y0;
  
  		// clean up the image for the next iteration
  		ImageMiscOps.fillRectangle(pdf,-1,dirty.x0,dirty.y0,dirty.x1-dirty.x0,dirty.y1-dirty.y0);
  
  		return true;
  	}