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