def hough_peaks()

in moonlight/vision/hough.py [0:0]


def hough_peaks(hough_bins, thetas, minval=0, invalidate_distance=0):
  """Finds the peak lines in Hough space.

  Args:
    hough_bins: Hough bins returned by `hough_lines`.
    thetas: Angles; argument given to `hough_lines`.
    minval: Minimum vote count for a Hough bin to be considered. int or float.
    invalidate_distance: When selecting a line `(rho, theta)`, invalidate all
      lines with the same theta and `+- invalidate_distance` from `rho`.
        int32. Caveat: this should only be used if all theta values are similar.
          If thetas cover a wide range, this will invalidate lines that might
          not even intersect.

  Returns:
    Tensor of peak rho indices (int32).
    Tensor of peak theta values (float32).
  """
  thetas = tf.convert_to_tensor(thetas)
  bin_score_dtype = thetas.dtype  # floating point score derived from hough_bins
  minval = tf.convert_to_tensor(minval)
  if minval.dtype.is_floating:
    minval = tf.ceil(minval)
  invalidate_distance = tf.convert_to_tensor(
      invalidate_distance, dtype=tf.int32)
  # Choose the theta with the highest bin value for each rho.
  selected_theta_ind = tf.argmax(hough_bins, axis=0)
  # Take the Hough bin value for each rho and the selected theta.
  hough_bins = tf.gather_nd(
      hough_bins,
      tf.stack([
          tf.cast(selected_theta_ind, tf.int32),
          tf.range(tf.shape(hough_bins)[1])
      ],
               axis=1))
  # hough_bins are integers. Subtract a penalty (< 1) for lines that are not
  # horizontal or vertical, so that we break ties in favor of the more
  # horizontal or vertical line.
  infinitesimal = tf.constant(1e-10, bin_score_dtype)
  # Decrease minval so we don't discard bins that are penalized, if they
  # originally equalled minval.
  minval = tf.cast(minval, bin_score_dtype) - infinitesimal
  selected_thetas = tf.gather(thetas, selected_theta_ind)
  # min(|sin(t)|, |cos(t)|) is 0 for horizontal and vertical angles, and between
  # 0 and 1 otherwise.
  penalty = tf.multiply(
      tf.minimum(
          tf.abs(tf.sin(selected_thetas)), tf.abs(tf.cos(selected_thetas))),
      infinitesimal)
  bin_score = tf.cast(hough_bins, bin_score_dtype) - penalty
  # Find the peaks in the 1D hough_bins array.
  peak_rhos = segments.peaks(
      bin_score, minval=minval, invalidate_distance=invalidate_distance)
  # Get the actual angles for each selected peak.
  peak_thetas = tf.gather(thetas, tf.gather(selected_theta_ind, peak_rhos))
  return peak_rhos, peak_thetas