from pierogis.ingredients import Pierogi, SpatialQuantize, Sort, Threshold, Dish, Recipe...
These two methods are usually called implicitly,
cook obfuscated in the typical usage flow.
prep can be seen as parameterizing the manipulation
cook applies it (to an array).
Here are some examples of
Pierogi is unique in that the array it returns from its
is not based on the input
pierogi = Pierogi(file="/Users/kyle/Desktop/image.jpg") pierogi = Pierogi(pixels=np.array( [[[0, 0, 0], [0, 0, 0]], [[255, 255, 255], [255, 255, 255]]] )
There is also the
SpatialQuantize variant which is used by the cli tool.
palette = [ [0, 0, 0], [127, 127, 127], [255, 255, 255] ] quantize = Quantize(palette=palette) quantized_pixels = quantize.cook(pierogi.pixels)
This should produce a pixel for pixel quantized version of the input array.
As you can see above, a
Pierogi has a
This is the internal numpy pixel array of that Pierogi
(width, height, 3).
A typical flow allows you to create a pipeline of
that sequentially apply their
cook method on to
the previous array of pixels.
recipe = Recipe(ingredients=[pierogi, quantize]) recipe.cook() recipe = Recipe(ingredients=[quantize]) recipe.cook(pierogi.pixels)
The two will produce the same result. But there’s a better way.
“get to the point already”
a wiser man
dish = Dish(recipe=recipe, pierogi=pierogi) cooked_dish = dish.serve()
The recipe gets cooked sequentially for each pierogi in
pierogi member set with cooked pixels.
There is also a concept of seasonings. They can be used to apply something like a mask to other ingredients that affect the pixels they act on.
sort = Sort() threshold = Threshold() # season sort with threshold sort.season(threshold)
cook() outputs a black and white array.
That’s what makes it a seasoning.
sort is seasoned with the
it will only sort pixels that have been “colored”
white by the
class Custom(Ingredient): def prep(self, brighten: int, scale: int, **kwargs): self.brighten = brighten self.scale = scale def cook(self, pixels: np.ndarray): return (self.pixels + self.brighten) /*self.scale
Override to parameterize your manipulation
This means any settings, constants,
or inputs that configure the new functionality.
Think about the
palette used with
def prep(self, brighten: int, scale: int, *args, **kwargs): self.brighten = brighten self.scale = scale
Override to perform the manipulation
This is the function that you acts on an input pixel grid.
More specifically, this function receives
(width, height, 3)
and should return a 3d array that is also size 3 in the last dimension.
def cook(self, pixels: np.ndarray): return (self.pixels + self.brighten) * self.scale
This function increases the r, g, and b of every pixel by
then multiplies that sum for each by
Numpy operations can be pretty fast if you can keep them vectorized. This means try to avoid looping over the columns and rows of an array.