code: protected void findBitCounts(GrayF32 gray , double threshold ) {
  		// compute binary image using an adaptive algorithm to handle shadows
  		ThresholdImageOps.threshold(gray,binaryInner,(float)threshold,true);
  
  		Arrays.fill(counts, 0);
  		for (int row = 0; row < gridWidth; row++) {
  			int y0 = row * binaryInner.width / gridWidth + 2;
  			int y1 = (row + 1) * binaryInner.width / gridWidth - 2;
  			for (int col = 0; col < gridWidth; col++) {
  				int x0 = col * binaryInner.width / gridWidth + 2;
  				int x1 = (col + 1) * binaryInner.width / gridWidth - 2;
  
  				int total = 0;
  				for (int i = y0; i < y1; i++) {
  					int index = i * binaryInner.width + x0;
  					for (int j = x0; j < x1; j++) {
  						total += binaryInner.data[index++];
  					}
  				}
  
  				counts[row * gridWidth + col] = total;
  			}
  		}
  	}
docs: Converts the gray scale image into a binary number.  Skip the outer 1 pixel of each inner square.  These
  tend to be incorrectly classified due to distortion.