text: """Data and functions for dealing with cell contents."""
  
  # pylint: disable=no-member, too-many-instance-attributes, too-many-arguments
  
  
  import numpy as np
  from skimage import util
  from skimage.transform import probabilistic_hough_line
  
  from lib.util import Crop, Offset, intersection
  
  
  class Cell:
      """Data and functions for dealing with cell contents."""
  
      row_label_threshold = 20
      col_label_threshold = 15
      crop = Crop(top=4, bottom=4, left=4, right=4)
      forward_slashes = np.deg2rad(np.linspace(65.0, 25.0, num=161))
      label_lines = np.deg2rad(np.linspace(0.0, 65.0, num=181))
      label_lines += np.deg2rad(np.linspace(-65.0, 0.0, num=181))
  
      def __init__(self, grid, top=None, bottom=None, left=None, right=None):
          """
          Build a cell from the 4 surrounding grid lines.
  
          We will also get the for corners of the cell by finding the
          intersection of the grid lines.
          """
          self.image = grid.edges
          self.top_left = intersection(top, left)
          self.bottom_left = intersection(bottom, left)
          self.top_right = intersection(top, right)
          self.bottom_right = intersection(bottom, right)
          self.width = self.top_right.x - self.top_left.x
          self.height = self.bottom_left.y - self.top_left.y
          self.offset = Offset(x=grid.offset.x + self.top_left.x,
                               y=grid.offset.y + self.top_left.y)
  
      def interior(self, crop=None):
          """
          Get the interior image of the cell.
  
          Sometimes we will want to crop the interior to try and remove the
          surrounding grid lines. That is, we want the cell contents, not the
          grid lines.
          """
          top = max(0, self.top_left.y, self.top_right.y)
          bottom = max(0, self.image.shape[0]
                       - min(self.bottom_left.y, self.bottom_right.y))
          left = max(0, self.top_left.x, self.bottom_left.x)
          right = max(0, self.image.shape[1]
                      - min(self.top_right.x, self.bottom_right.x))
  
          inside = util.crop(self.image, ((top, bottom), (left, right)))
  
          if crop and inside.shape[1] > (crop.right + crop.left) \
                  and inside.shape[0] > (crop.bottom + crop.top):
              inside = util.crop(
                  inside,
                  ((crop.top, crop.bottom), (crop.left, crop.right)))
  
          return inside
  
      def is_label(self, crop=None):
          """Determine if the cell is a column label."""
          if not crop:
              crop = self.crop
          inside = self.interior(crop=crop)
          lines = self.has_line(self.label_lines, line_length=12)
          if not min(inside.shape):
              return False
          return bool(len(lines)) or np.mean(inside) > self.col_label_threshold
  
      def has_line(self, angles=None, line_length=15):
          """Determine if the cell has a line at any of the given angles."""
          return probabilistic_hough_line(
              self.interior(crop=self.crop),
              line_length=line_length,
              line_gap=2,
              theta=angles)
  
      def get_patch(self):
          """Get the cell patch for output."""
          width = self.top_right.x - self.top_left.x
          height = self.bottom_left.y - self.top_left.y
          offset_x = self.offset.x
          offset_y = self.offset.y
          return (offset_x, offset_y), width, height
  