docs: def get_kapur_threshold(image, mask=None):
      """The Kapur, Sahoo, & Wong method of thresholding, adapted to log-space."""
      cropped_image = np.array(image.flat) if mask is None else image[mask]
      if np.product(cropped_image.shape)<3:
          return 0
      if np.min(cropped_image) == np.max(cropped_image):
          return cropped_image[0]
      log_image = np.log2(smooth_with_noise(cropped_image, 8))
      min_log_image = np.min(log_image)
      max_log_image = np.max(log_image)
      histogram = scipy.ndimage.histogram(log_image,
                                          min_log_image,
                                          max_log_image,
                                          256)
      histogram_values = (min_log_image + (max_log_image - min_log_image)*
                          np.arange(256, dtype=float) / 255)
      # drop any zero bins
      keep = histogram != 0
      histogram = histogram[keep]
      histogram_values = histogram_values[keep]
      # check for corner cases
      if np.product(histogram_values)==1:
          return 2**histogram_values[0] 
      # Normalize to probabilities
      p = histogram.astype(float) / float(np.sum(histogram))
      # Find the probabilities totals up to and above each possible threshold.
      lo_sum = np.cumsum(p);
      hi_sum = lo_sum[-1] - lo_sum;
      lo_e = np.cumsum(p * np.log2(p));
      hi_e = lo_e[-1] - lo_e;
  
      # compute the entropies
      lo_entropy = lo_e / lo_sum - np.log2(lo_sum);
      hi_entropy = hi_e / hi_sum - np.log2(hi_sum);
  
      sum_entropy = lo_entropy[:-1] + hi_entropy[:-1];
      sum_entropy[np.logical_not(np.isfinite(sum_entropy))] = np.Inf
      entry = np.argmin(sum_entropy);
      return 2**((histogram_values[entry] + histogram_values[entry+1]) / 2);