docs: public static void process(GrayU8 input, GrayU8 output , int radius, @Nullable IWorkArrays work )
  	{
  		if( work == null )
  			work = new IWorkArrays();
  		work.reset(256);
  		final IWorkArrays _work = work;
  
  		int w = 2*radius+1;
  
  		// sanity check to make sure the image isn't too small to be processed by this algorithm
  		if( input.width < w || input.height < w )
  			return;
  
  		// defines what the median is. technically this is an approximation because if even it's the ave
  		// of the two elements in the middle. I'm not aware of libraries which actually do this.
  		int threshold = (w*w)/2+1;
  
  		//CONCURRENT_BELOW BoofConcurrency.loopBlocks(radius, output.height-radius, w,(y0,y1)->{
  		final int y0 = radius, y1 = input.height-radius;
  		int[] histogram = _work.pop();
  		for( int y = y0; y < y1; y++ ) {
  			int seed = input.startIndex + (y-radius)*input.stride;
  			Arrays.fill(histogram,0);
  
  			// compute the median value for the first x component and initialize the system
  			for( int i = 0; i < w; i++ ) {
  				int idx = seed + i*input.stride;
  				int end = idx + w;
  				while( idx < end ) {
  					histogram[(input.data[idx++]&0xFF)]++;
  				}
  			}
  
  			// Compute the median value
  			int count = 0, median = 0;
  			while( true ) {
  				count += histogram[median];
  				if( count >= threshold )
  					break;
  				median++;
  			}
  			output.data[ output.startIndex+y*output.stride+radius] = (byte)median;
  
  			// remove the left most pixel from the histogram
  			count += removeSide(input.data,input.stride, w, histogram, seed, median);
  
  			for( int x = radius+1; x < input.width-radius; x++ ) {
  				seed = input.startIndex + (y - radius) * input.stride + (x - radius);
  
  				// add the right most pixels to the histogram
  				count += addSide(input.data, input.stride, w, histogram, seed + w - 1, median);
  
  				// find the median, using the previous solution as a starting point
  				if (count >= threshold) {
  					while (count >= threshold) {
  						count -= histogram[median--];
  					}
  					median += 1;
  					count += histogram[median];
  				} else {
  					while (count < threshold) {
  						median += 1;
  						count += histogram[median];
  					}
  				}
  				output.data[output.startIndex + y * output.stride + x] = (byte) median;
  
  				// remove the left most pixels from the histogram
  				count += removeSide(input.data, input.stride, w, histogram, seed, median);
  			}
  		}
  		//CONCURRENT_ABOVE }});
  	}