docs: public void process( ImagePyramid<T> pyramidPrev , ImagePyramid<T> pyramidCurr ) {
  
  		InputSanityCheck.checkSameShape(pyramidPrev, pyramidCurr);
  
  		int numLayers = pyramidPrev.getNumLayers();
  
  		for( int i = numLayers-1; i >= 0; i-- ) {
  
  			T prev = pyramidPrev.getLayer(i);
  			T curr = pyramidCurr.getLayer(i);
  
  			flowCurrLayer.reshape(prev.width, prev.height);
  
  			int N = prev.width*prev.height;
  			if( scores.length < N )
  				scores = new float[N];
  			// mark all the scores as being very large so that if it has not been processed its score
  			// will be set inside of checkNeighbors.
  			Arrays.fill(scores,0,N,Float.MAX_VALUE);
  
  			int x1 = prev.width-regionRadius;
  			int y1 = prev.height-regionRadius;
  
  			if( i == numLayers-1 ) {
  				// the top most layer in the pyramid has no hint
  				for( int y = regionRadius; y < y1; y++ ) {
  					for( int x = regionRadius; x < x1; x++ ) {
  						extractTemplate(x,y,prev);
  						float score = findFlow(x,y,curr,tmp);
  
  						if( tmp.isValid() )
  							checkNeighbors(x,y,tmp, flowCurrLayer,score);
  						else
  							flowCurrLayer.unsafe_get(x, y).markInvalid();
  					}
  				}
  			} else {
  				// for all the other layers use the hint of the previous layer to start its search
  				double scale = pyramidPrev.getScale(i+1)/pyramidPrev.getScale(i);
  				for( int y = regionRadius; y < y1; y++ ) {
  					for( int x = regionRadius; x < x1; x++ ) {
  						// grab the flow in higher level pyramid
  						ImageFlow.D p = flowPrevLayer.get((int)(x/scale),(int)(y/scale));
  						if( !p.isValid() )
  							continue;
  
  						// get the template around the current point in this layer
  						extractTemplate(x,y,prev);
  
  						// add the flow from the higher layer (adjusting for scale and rounding) as the start of
  						// this search
  						int deltaX = (int)(p.x*scale+0.5);
  						int deltaY = (int)(p.y*scale+0.5);
  
  						int startX = x + deltaX;
  						int startY = y + deltaY;
  
  						float score = findFlow(startX,startY,curr,tmp);
  
  						// find flow only does it relative to the starting point
  						tmp.x += deltaX;
  						tmp.y += deltaY;
  
  						if( tmp.isValid() )
  							checkNeighbors(x,y,tmp, flowCurrLayer,score);
  						else
  							flowCurrLayer.unsafe_get(x,y).markInvalid();
  					}
  				}
  			}
  
  			// swap the flow images
  			ImageFlow tmp = flowPrevLayer;
  			flowPrevLayer = flowCurrLayer;
  			flowCurrLayer = tmp;
  		}
  	}