Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Say there’s an existing service that does almost everything you want it to, but there’s some slight changes you wish you could make. Luckily, SIC’s object-oriented architecture enables you to inherit from and extend the component you wish to modify. Let’s take the ‘detect’ function of the FaceDetectionComponent service, for example:

Code Block
    def detect(self, image):
        img = array(image).astype(np.uint8)

        gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)

        faces = self.faceCascade.detectMultiScale(
            gray,
            scaleFactor=1.2,
            minNeighbors=5,
            minSize=(int(self.params.minW), int(self.params.minH)),
        )

        faces = [BoundingBox(x, y, w, h) for (x, y, w, h) in faces]

        return BoundingBoxesMessage(faces)

In this function the ‘scaleFactor’ and ‘minNeighbors’ variables are hidden within the function, meaning the only way to access or change them is to rewrite themthe function. However, rather than rewriting the whole entire FaceDetectionComponent, we can simply create a new component where we inherit from the FaceDetectionComponent, and change just the detect function.

...

  1. Identify the component we wish to change.

  2. Create a new script called ‘custom_{COMPONENT_NAME}.py'.

Info

It is recommended to create add these to a ‘custom_components’ folder within your repo to keep track of these.

...

First, we have already decided we are going to change the ‘detect’ function of the FaceDetectionComponent. So secondlynext, we create a ‘custom_components’ folder in our repo if we do not have one already, and within that add a ‘custom_{COMPONENT}’ script:

...

Info

There also needs to be an ‘__init__.py’ script within the custom_components folder. This script should be empty, but it needs to be there for Python to recognize this folder as a module.

...

Now run ‘pip install -e .’ within your SIC repository. This will create a link in your environment to the custom_components folder so that you can easily import your custom components within your other scripts.

Writing the new component (steps 3, 4, and 5)

...

Code Block
class CustomFaceDetectionComponent(FaceDetectionComponent):
    def __init__(self, *args, **kwargs):
        super(CustomFaceDetectionComponent, self).__init__(*args, **kwargs)
        self.scaleFactor = 1.2
        self.minNeighbors = 3

    def detect(self, image):
        # Override the detect function with custom behavior
        img = array(image).astype(np.uint8)

        gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)

        faces = self.faceCascade.detectMultiScale(
            gray,
            scaleFactor=self.scaleFactor,  # Example of different scale factornow these variables belong to the class
            minNeighbors=self.minNeighbors,    # Example of different minNeighborsthey can be accessed and changed outside this function
            minSize=(int(self.params.minW), int(self.params.minH)),
        )

        faces = [BoundingBox(x, y, w, h) for (x, y, w, h) in faces]

        return BoundingBoxesMessage(faces)

...

The work on the new custom component is done. Now, you must change the scripts that you want to use the new component. Here the demo_desktop_camera_facedetection.py is used as an example.

First, make sure your script is able to find your new component. Here is one way of doing so:

Code Block
import sys
from pathlib import Path
# Get the absolute path to the custom_services folder
custom_services_path = Path(__file__).resolve().parent.parent.parent / "custom_components"
sys.path.append(str(custom_services_path))

Alternatively, you can append the ‘custom_components' folder path to the PYTHONPATH environment variable within the ‘activate’ script of your virtual environment. For example:

Code Block
export PYTHONPATH="/path/to/custom_components:$PYTHONPATH"
Info

If you go this route, you will have to deactivate and reactivate your virtual environment

Next, import the new connector rather than the old one

import the new connector rather than the old one

Info

Make sure you ran ‘pip install -e .’ within the directory so that the ‘custom_components’ folder is linked to your environment’s packages.

Code Block
### from sic_framework.services.face_detection.face_detection import FaceDetection
from custom_components.custom_face_detection import CustomFaceDetection

...