# Path: moonlight/staves/base.py
# class BaseStaffDetector(object):
# class ComputedStaves(BaseStaffDetector):
#   def __init__(self, image=None):
#   def data(self):
#   def staves_interpolated_y(self):
#     def _get_staff_center_line_y(staff):
#       def loop_body(i, ys_array):
#   def compute(self, session=None, feed_dict=None):
#   def __init__(self, staves, staffline_distance, staffline_thickness,
#                staves_interpolated_y):
#   def staves_interpolated_y(self):
#   def compute(self, session=None, feed_dict=None):
# 
# Path: moonlight/staves/filter.py
# MIN_STAFF_SLICES = 0.25
# def staff_center_filter(image,
#                         staffline_distance,
#                         staffline_thickness,
#                         threshold=127):
# def _shift_y(image, y_offset):
#   def invalid():
#   def shift_up():
#   def shift_down():
# def _get_staff_ys(is_staff, staffline_thickness):
# 
# Path: moonlight/staves/staffline_distance.py
# _MAX_STAFFLINE_DISTANCE_THICKNESS_VALUE = 256
# _MIN_STAFFLINE_DISTANCE_SCORE = 10000
# _MAX_ALLOWED_UNIQUE_STAFFLINE_DISTANCES = 3
# _STAFFLINE_DISTANCE_INVALIDATE_DISTANCE = 1
# _STAFFLINE_THICKNESS_INVALIDATE_DISTANCE = 1
# _PEAK_CUTOFF = 0.5
# def _single_peak(values, relative_cutoff, minval, invalidate_distance):
# def _estimate_staffline_distance(columns, lengths):
#     def do_filter_peaks():
# def _estimate_staffline_thickness(columns, values, lengths, staffline_distance):
#     def do_estimate():
# def estimate_staffline_distance_and_thickness(image, threshold=127):
# 
# Path: moonlight/util/memoize.py
# class MemoizedFunction(object):
#   def __init__(self, function):
#   def __call__(self, *args):
# 
# Path: moonlight/vision/hough.py
# def hough_lines(image, thetas):
# def hough_peaks(hough_bins, thetas, minval=0, invalidate_distance=0):
# def _bincount_2d(values, num_values):


import math
import numpy as np
import tensorflow as tf
from moonlight.staves import base
from moonlight.staves import filter as staves_filter
from moonlight.staves import staffline_distance as distance
from moonlight.util import memoize
from moonlight.vision import hough
      staffline_thickness: The staffline thickness.
      max_abs_theta: The maximum deviation of the angle for the staff from the
        horizontal, in radians.
      num_theta: The number of thetas to be detected, between `pi/2 -
        max_abs_theta` and `pi/2 + max_abs_theta`.
    """
    self.image = image
    self.estimated_staffline_distance = staffline_distance
    self.estimated_staffline_thickness = staffline_thickness
    self.max_abs_theta = float(max_abs_theta)
    self.num_theta = int(num_theta)

  # Memoize this to not re-compute "staves" as a different tensor each time this
  # property is referenced. TF's common subexpression elimination doesn't seem
  # to handle this case, maybe because we have too many ops.
  @property
  def staves(self):
    """The staves detected for a single staffline distance.

    Returns:
      A staves tensor of shape (N, 2, 2).
    """
    height = tf.shape(self.image)[0]
    width = tf.shape(self.image)[1]
    staff_center = staves_filter.staff_center_filter(
        self.image, self.estimated_staffline_distance,
        self.estimated_staffline_thickness)
    all_thetas = tf.linspace(math.pi / 2 - self.max_abs_theta,
                             math.pi / 2 + self.max_abs_theta, self.num_theta)
    hough_bins = hough.hough_lines(staff_center, all_thetas)

# Path: moonlight/staves/base.py
# class BaseStaffDetector(object):
# class ComputedStaves(BaseStaffDetector):
#   def __init__(self, image=None):
#   def data(self):
#   def staves_interpolated_y(self):
#     def _get_staff_center_line_y(staff):
#       def loop_body(i, ys_array):
#   def compute(self, session=None, feed_dict=None):
#   def __init__(self, staves, staffline_distance, staffline_thickness,
#                staves_interpolated_y):
#   def staves_interpolated_y(self):
#   def compute(self, session=None, feed_dict=None):
# 
# Path: moonlight/staves/filter.py
# MIN_STAFF_SLICES = 0.25
# def staff_center_filter(image,
#                         staffline_distance,
#                         staffline_thickness,
#                         threshold=127):
# def _shift_y(image, y_offset):
#   def invalid():
#   def shift_up():
#   def shift_down():
# def _get_staff_ys(is_staff, staffline_thickness):
# 
# Path: moonlight/staves/staffline_distance.py
# _MAX_STAFFLINE_DISTANCE_THICKNESS_VALUE = 256
# _MIN_STAFFLINE_DISTANCE_SCORE = 10000
# _MAX_ALLOWED_UNIQUE_STAFFLINE_DISTANCES = 3
# _STAFFLINE_DISTANCE_INVALIDATE_DISTANCE = 1
# _STAFFLINE_THICKNESS_INVALIDATE_DISTANCE = 1
# _PEAK_CUTOFF = 0.5
# def _single_peak(values, relative_cutoff, minval, invalidate_distance):
# def _estimate_staffline_distance(columns, lengths):
#     def do_filter_peaks():
# def _estimate_staffline_thickness(columns, values, lengths, staffline_distance):
#     def do_estimate():
# def estimate_staffline_distance_and_thickness(image, threshold=127):
# 
# Path: moonlight/util/memoize.py
# class MemoizedFunction(object):
#   def __init__(self, function):
#   def __call__(self, *args):
# 
# Path: moonlight/vision/hough.py
# def hough_lines(image, thetas):
# def hough_peaks(hough_bins, thetas, minval=0, invalidate_distance=0):
# def _bincount_2d(values, num_values):


# Path: moonlight/staves/hough.py
import math
import numpy as np
import tensorflow as tf
from moonlight.staves import base
from moonlight.staves import filter as staves_filter
from moonlight.staves import staffline_distance as distance
from moonlight.util import memoize
from moonlight.vision import hough

      staffline_thickness: The staffline thickness.
      max_abs_theta: The maximum deviation of the angle for the staff from the
        horizontal, in radians.
      num_theta: The number of thetas to be detected, between `pi/2 -
        max_abs_theta` and `pi/2 + max_abs_theta`.
    """
    self.image = image
    self.estimated_staffline_distance = staffline_distance
    self.estimated_staffline_thickness = staffline_thickness
    self.max_abs_theta = float(max_abs_theta)
    self.num_theta = int(num_theta)

  # Memoize this to not re-compute "staves" as a different tensor each time this
  # property is referenced. TF's common subexpression elimination doesn't seem
  # to handle this case, maybe because we have too many ops.
  @property
  def staves(self):
    """The staves detected for a single staffline distance.

    Returns:
      A staves tensor of shape (N, 2, 2).
    """
    height = tf.shape(self.image)[0]
    width = tf.shape(self.image)[1]
    staff_center = staves_filter.staff_center_filter(
        self.image, self.estimated_staffline_distance,
        self.estimated_staffline_thickness)
    all_thetas = tf.linspace(math.pi / 2 - self.max_abs_theta,
                             math.pi / 2 + self.max_abs_theta, self.num_theta)
    hough_bins = hough.hough_lines(staff_center, all_thetas)

    staff_rhos, staff_thetas = hough.hough_peaks(