Transforms¶
Transforms are the most important part of EasyCV. This module contains all the transforms that EasyCV currently supports. It also enables some powerful functionalities that we’ll discuss later on this page.
Introduction¶
All transforms inherit from the base class Transform. The Transform class takes care of most of the core functionality simplifying the process of creating new transforms.
Transforms can be used to modify an image (e.g. blur an image) or to extract valuable information (e.g. count the number of faces in the image). Any of the mentioned types of transform can be applied in the same way. The only difference between them is their outputs.
Transform structure¶
All transforms follow the same structure. They all inherit from Transform and must override the method process
. This method receives the image array and should return the result of applying the transform to the image. process
also receives all the transform arguments, we will talk about arguments in detail later on this documentation.
Let’s implement a simple transform that sets the first color channel to zero.
from easycv.transforms.base import Transform
class FillChannel(Transform): # inherit from Transform
def process(self, image, **kwargs): # override process
image[:, :, 0] = 0
return image
As you can see from the example above it’s really simple to extend EasyCV. Now we can use our transform!
from easycv import Image
img = Image("lenna.jpg")
img.apply(FillChannel()).show() # Opens a popup window with the altered image
Warning
The process method always receives the image as a numpy array not as an easycv.image.Image
instance.
Arguments¶
Some transforms depend on hyper-parameters or other configurations. EasyCV calls them arguments and they can specified be inside the transform class by assigning a dictionary containing the argument specifications to the variable arguments
. In this dictionary argument names are the keys and the values are the argument validators
. Validators enable easy and reliable argument validation/forwarding, more details about validators can be found here.
EasyCV will check if the user is inserting the required arguments (arguments without a default value are considered required) and if the inserted values are valid. A helpful error message is generated automatically from the argument validator is generated in case of an error.
Let’s add argument to the transform we created above. We’ll add the argument fill_value
to enable people to change the value we use to fill the channel! Since fill_value
must be an 8-bit integer we’ll use a Number
validator with some restrictions applied.
Arguments are given to process
through kwargs
. You can assume that process only runs if all arguments are valid and all required arguments have been filled.
Note
The process method receives all the specified arguments on kwargs
regardless of which arguments the user enters (default values are used for this). There is an exception to this case we’ll discuss later (method-specific arguments).
from easycv.validators import Number
class FillChannel(Transform):
# define arguments
arguments = {
"fill_value": Number(min_value=0, max_value=255, only_integer=True, default=0),
}
def process(self, image, **kwargs):
image[:, :, 0] = kwargs["fill_value"] # use the new argument instead of always zero
return image
Now we can use the updated transform with the fill_value
argument!
from easycv import Image
img = Image("lenna.jpg")
img.apply(FillChannel(fill_value=128)).show() # Let's fill the image channel with 128
But what happens if the argument is invalid? Let’s check!
img.apply(FillChannel(fill_value="bad value")).show()
>>> (Exception raised)
>>> InvalidArgumentError: Invalid value for fill_value. Must be an integer between 0 and 255.
As we can see a helpful message is displayed warning the user that fill_value
must be an integer between 0 and 255.