Source code for pierogis.ingredients.seasonings.rectangle
import math
from typing import Union, Tuple
import numpy as np
from .cartography import Direction, Coordinate
from .seasoning import Seasoning
[docs]class Rectangle(Seasoning):
width: Union[int, float]
height: Union[int, float]
x: Union[int, float]
y: Union[int, float]
aspect: float
origin: Direction
ORIGIN: Direction = Direction.SW
[docs] def prep(
self,
width: Union[int, float] = None, height: Union[int, float] = None,
x: Union[int, float] = 0, y: Union[int, float] = 0,
aspect: float = None, origin: Union[str, Direction] = ORIGIN,
**kwargs
):
"""
:param x: 0 = left
:param y: 0 = bottom
:param width: width in pixels
:param height: height in pixels
:param aspect: aspect ratio to fill missing height or width (width/height, 1 means square)
:param origin: location of origin for direction of crop select
"""
super().prep(**kwargs)
self.width = width
self.height = height
self.x = x
self.y = y
self.aspect = aspect
if isinstance(origin, str):
origin = Direction(origin)
self.origin = origin
[docs] def cook(self, pixels: np.ndarray):
# create an array of all excludes
boolean_array = np.zeros(pixels.shape[:2], dtype=bool)
bottom_left, top_right = self.get_corner_coordinates(pixels.shape[0], pixels.shape[1])
boolean_array[bottom_left.x:top_right.x, bottom_left.y:top_right.y] = True
boolean_array = np.expand_dims(boolean_array, 2)
binary_pixels = np.where(
boolean_array, self.include_pixel, self.exclude_pixel
)
return binary_pixels
# include all pixels that are inside of the bounding coords
[docs] def get_corner_coordinates(
self, bounding_width: int, bounding_height: int
) -> Tuple[Coordinate, Coordinate]:
# x, y for bottom left and top right
if self.origin is Direction.SW:
x = 0
y = 0
bl_x_multiplier = 0
tr_x_multiplier = 1
bl_y_multiplier = 0
tr_y_multiplier = 1
elif self.origin is Direction.SE:
x = bounding_width
y = 0
bl_x_multiplier = 1
tr_x_multiplier = 0
bl_y_multiplier = 0
tr_y_multiplier = 1
elif self.origin is Direction.NW:
x = 0
y = bounding_height
bl_x_multiplier = 0
tr_x_multiplier = 1
bl_y_multiplier = 1
tr_y_multiplier = 0
elif self.origin is Direction.NE:
x = bounding_width
y = bounding_height
bl_x_multiplier = 1
tr_x_multiplier = 0
bl_y_multiplier = 1
tr_y_multiplier = 0
elif self.origin is Direction.C:
x = bounding_width * .5
y = bounding_height * .5
bl_x_multiplier = .5
tr_x_multiplier = .5
bl_y_multiplier = .5
tr_y_multiplier = .5
elif self.origin is Direction.N:
x = bounding_width * .5
y = bounding_height
bl_x_multiplier = .5
tr_x_multiplier = .5
bl_y_multiplier = 1
tr_y_multiplier = 0
elif self.origin is Direction.E:
x = bounding_width
y = bounding_height * .5
bl_x_multiplier = 1
tr_x_multiplier = 0
bl_y_multiplier = .5
tr_y_multiplier = .5
elif self.origin is Direction.S:
x = bounding_width * .5
y = 0
bl_x_multiplier = .5
tr_x_multiplier = .5
bl_y_multiplier = 0
tr_y_multiplier = 1
elif self.origin is Direction.W:
x = 0
y = bounding_height * .5
bl_x_multiplier = 0
tr_x_multiplier = 1
bl_y_multiplier = .5
tr_y_multiplier = .5
else:
raise Exception()
if self.x != 0:
if 1 > self.x > -1:
x += self.x * bounding_width
else:
x += self.x
if self.y != 0:
if 1 > self.y > -1:
y += self.y * bounding_height
else:
y += self.y
origin = Coordinate(x, y)
width = None
height = None
if self.width is not None:
width = self.width
if 1 > width > -1:
width *= bounding_width
if self.height is not None:
height = self.height
if 1 > height > -1:
height *= bounding_height
if not (self.width is not None and self.height is not None):
if self.width is not None:
if self.aspect is not None:
height = width / self.aspect
else:
height = bounding_height
elif self.height is not None:
if self.aspect is not None:
width = height * self.aspect
else:
width = bounding_width
else:
width = bounding_width
height = bounding_height
if self.aspect is not None:
if width / height > self.aspect:
width = height * self.aspect
else:
height = width / self.aspect
bl_x = int(math.ceil(origin.x - bl_x_multiplier * width))
if bl_x < 0:
bl_x = 0
bl_y = int(math.ceil(origin.y - bl_y_multiplier * height))
if bl_y < 0:
bl_y = 0
tr_x = int(math.ceil(origin.x + tr_x_multiplier * width))
if tr_x > bounding_width:
tr_x = bounding_width
tr_y = int(math.ceil(origin.y + tr_y_multiplier * height))
if tr_y > bounding_height:
tr_y = bounding_height
bottom_left = Coordinate(
bl_x,
bl_y
)
top_right = Coordinate(
tr_x,
tr_y
)
return bottom_left, top_right