docs: public boolean process(T image) {
  		// update feature tracks
  		tracker.process(image);
  
  		tick++;
  
  		if (first) {
  			// start motion estimation by spawning tracks and estimating their pose
  			addNewTracks();
  			first = false;
  		} else {
  			// Use updated tracks to update motion estimate and track states
  
  			// use geometry to prune tracks and perform pre-processing for motion estimation
  			sortTracksForEstimation();
  
  			// estimate rotation using points at infinity
  			estimateFar();
  
  			// estimate rotation and translation using points on the plane
  			if (!estimateClose()) {
  				// if this fails it can't do anything
  				return false;
  			}
  
  			// merge the two motion estimates together
  			fuseEstimates();
  
  			// discard tracks which aren't being used
  			dropUnusedTracks();
  
  			// see if new tracks need to be added
  			if (thresholdAdd <= 0 || closeInlierCount < thresholdAdd) {
  				changeCurrToReference();
  				addNewTracks();
  			}
  		}
  
  		return true;
  	}