scales(image) -> scale, shape

    Computes the all possible scales for the given image and yields a tuple of the scale and the scaled image shape as an iterator.

    **Parameters::**

    ``image`` : array_like(2D or 3D)
      The image, for which the scales should be computed

    **Yields:**

    ``scale`` : float
      The next scale of the image to be considered

    ``shape`` : (int, int) or (int, int, int)
      The shape of the image, when scaled with the current ``scale``

def scales(self, image):
    """scales(image) -> scale, shape

    Computes the all possible scales for the given image and yields a tuple of the scale and the scaled image shape as an iterator.

    **Parameters::**

    ``image`` : array_like(2D or 3D)
      The image, for which the scales should be computed

    **Yields:**

    ``scale`` : float
      The next scale of the image to be considered

    ``shape`` : (int, int) or (int, int, int)
      The shape of the image, when scaled with the current ``scale``
    """
    # compute the minimum scale so that the patch size still fits into the given image
    minimum_scale = max(self.m_patch_box.size_f[0] / image.shape[-2], self.m_patch_box.size_f[1] / image.shape[-1])
    if self.m_lowest_scale:
      maximum_scale = min(minimum_scale / self.m_lowest_scale, 1.)
    else:
      maximum_scale = 1.
    current_scale_power = 0.

    # iterate over all possible scales
    while True:
      # scale the image
      scale = minimum_scale * math.pow(self.m_scale_factor, current_scale_power)
      if scale > maximum_scale:
        # image is smaller than the requested minimum size
        break
      current_scale_power -= 1.
      scaled_image_shape = bob.ip.base.scaled_output_shape(image, scale)

      # return both the scale and the scaled image size
      yield scale, scaled_image_shape