# Create and integrate your algorithm in workflows ```{toctree} :hidden: algo_parameters algo_widget algo_IO ``` Creating and integrating your own algorithms into workflows can be a powerful way to automate and streamline your data processing tasks. In this document, we will provide an overview of the steps involved in creating and integrating your own algorithm into a workflow using the Ikomia API. ## Algorithm creation with `ikomia-cli` The Ikomia API provides a command-line interface tool called `ikomia-cli` that can be used to create a new algorithm. Here's how to get started: 1. First, make sure you have the `ikomia-cli` tool installed. You can do this by running the following command in your terminal: ```shell pip install 'ikomia-cli[full]' ``` 2. Once you have installed `ikomia-cli`, you can create a new algorithm by running the following command: ```bash ikcli algo local create my_first_algo ``` This will create a new directory called **"my_first_algo"** in "Ikomia/Plugins/Python/" directory. Inside this directory, you will find several files that make up your algorithm. 3. The main file of your algorithm is **"my_first_algo_process.py"**. This file contains the Python code that implements your algorithm. You can open this file in a text editor or IDE to begin editing it. Here's an example of what this file might look like: ```python import copy from ikomia import core, dataprocess # -------------------- # - Class to handle the process parameters # - Inherits core.CWorkflowTaskParam from Ikomia API # -------------------- class MyFirstAlgoParam(core.CWorkflowTaskParam): def __init__(self): core.CWorkflowTaskParam.__init__(self) # Place default value initialization here # Example : self.windowSize = 25 def set_values(self, params): # Set parameters values from Ikomia application # Parameters values are stored as string and accessible like a python dict # Example : self.windowSize = int(params["windowSize"]) pass def get_values(self): # Send parameters values to Ikomia application # Create the specific dict structure (string container) params = {} # Example : params["windowSize"] = str(self.windowSize) return params # -------------------- # - Class which implements the process # - Inherits core.CWorkflowTask or derived from Ikomia API # -------------------- class MyFirstAlgo(core.CWorkflowTask): def __init__(self, name, param): core.CWorkflowTask.__init__(self, name) # Add input/output of the process here # Example : self.add_input(dataprocess.CImageIO()) # self.add_output(dataprocess.CImageIO()) # Create parameters class if param is None: self.set_param_object(MyFirstAlgoParam()) else: self.set_param_object(copy.deepcopy(param)) def get_progress_steps(self): # Function returning the number of progress steps for this process # This is handled by the main progress bar of Ikomia application return 1 def run(self): # Core function of your process # Call begin_task_run() for initialization self.begin_task_run() # Examples : # Get input : # task_input = self.get_input(index_of_input) # Get output : # task_output = self.get_output(index_of_output) # Get parameters : # param = self.get_param_object() # Get image from input/output (numpy array): # src_image = task_input.get_image() # Call to the process main routine # dst_image = ... # Set image of input/output (numpy array): # task_output.set_image(dst_image) # Step progress bar: self.emit_step_progress() # Call end_task_run() to finalize process self.end_task_run() # -------------------- # - Factory class to build process object # - Inherits dataprocess.CTaskFactory from Ikomia API # -------------------- class MyFirstAlgoFactory(dataprocess.CTaskFactory): def __init__(self): dataprocess.CTaskFactory.__init__(self) # Set process information as string here self.info.name = "my_first_algo" self.info.short_description = "your short description" # relative path -> as displayed in Ikomia Studio process tree self.info.path = "Plugins/Python" self.info.version = "1.0.0" # self.info.icon_path = "your path to a specific icon" self.info.authors = "algorithm author" self.info.article = "title of associated research article" self.info.journal = "publication journal" self.info.year = 2022 self.info.license = "MIT License" # Ikomia API compatibility # self.info.min_ikomia_version = "0.10.0" # self.info.max_ikomia_version = "0.11.0" # Python compatibility # self.info.min_python_version = "3.10.0" # self.info.max_python_version = "3.11.0" # URL of documentation self.info.documentation_link = "" # Code source repository self.info.repository = "" self.info.original_repository = "" # Keywords used for search self.info.keywords = "your,keywords,here" # General type: INFER, TRAIN, DATASET or OTHER # self.info.algo_type = core.AlgoType.OTHER # Algorithms tasks: CLASSIFICATION, COLORIZATION, IMAGE_CAPTIONING, IMAGE_GENERATION, # IMAGE_MATTING, INPAINTING, INSTANCE_SEGMENTATION, KEYPOINTS_DETECTION, # OBJECT_DETECTION, OBJECT_TRACKING, OCR, OPTICAL_FLOW, OTHER, PANOPTIC_SEGMENTATION, # SEMANTIC_SEGMENTATION or SUPER_RESOLUTION # self.info.algo_tasks = "OTHER" def create(self, param=None): # Create process object return MyFirstAlgo(self.info.name, param) ``` As you can see, there are 3 classes: * One for the parameters * One for the core algorithm * One for the meta-data description. 4. By default, this algorithm does nothing. Let's create an algorithm that takes 1 input image and outputs a Canny edge detection of it. To do this, you need to edit the `__init__()` function in `MyFirstAlgo` class: ```python class MyFirstAlgo(core.CWorkflowTask): def __init__(self, name, param): core.CWorkflowTask.__init__(self, name) # Add input/output of the process here self.add_input(dataprocess.CImageIO()) # <-- Add input object of type image self.add_output(dataprocess.CImageIO()) # <-- Add output object of type image # Create parameters class if param is None: self.set_param_object(MyFirstAlgoParam()) else: self.set_param_object(copy.deepcopy(param)) ``` You now have an algorithm which takes 1 input image and outputs 1 image. Then, you can edit the `run()` function like this (don't forget to import `cv2`) : ```python import cv2 ... def run(self): # Core function of your process # Call begin_task_run() for initialization self.begin_task_run() # Examples : # Get input : task_input = self.get_input(0) # <-- Get first input object # Get output : task_output = self.get_output(0) # <-- Get first output object # Get input image (numpy array): src_image = task_input.get_image() # <-- Get image from your input object # Call to the process main routine dst_image = cv2.Canny(src_image, threshold1=100, threshold2=200) # <-- Use OpenCV Canny edge detector # Set output image (numpy array): task_output.set_image(dst_image) # <-- Set processed image to your output object # Step progress bar: self.emit_step_progress() # Call end_task_run() to finalize process self.end_task_run() ``` 6. Your algorithm is now ready to be integrated into an Ikomia workflow. That's it! With just a few simple steps, you can create your own algorithm using the Ikomia API and `ikomia-cli`. ## Algorithm integration Once you have created and edited your algorithm, you can integrate it into a larger workflow using the Ikomia API. Here are the basic steps for integrating your algorithm: 1. Import the necessary modules from the Ikomia API: ```python from ikomia.dataprocess.workflow import Workflow from ikomia.utils import ik from ikomia.utils.displayIO import display ``` 2. Create a new workflow object: ```python wf = Workflow() ``` 3. Add your algorithm to the workflow: ```python my_algorithm = wf.add_task(ik.my_first_algo(), auto_connect=True) ``` 4. Connect the inputs and outputs of your algorithm to other tasks in the workflow as needed. This can be done using the `auto_connect=True` argument when adding your algorithm to the workflow, or by manually connecting inputs and outputs using the `connect_tasks()` method. 5. Run the workflow on any input image: ```python wf.run_on(url="https://raw.githubusercontent.com/Ikomia-dev/notebooks/main/examples/img/img_fireman.jpg") ``` 6. Retrieve the output of your algorithm and display it: ```python output_data = my_algorithm.get_output(0).get_image() display(output_data) ``` The full code: ```python from ikomia.dataprocess.workflow import Workflow from ikomia.utils.displayIO import display from ikomia.utils import ik # Init the workflow wf = Workflow() # Add your algorithm my_algo = wf.add_task(ik.my_first_algo(), auto_connect=True) # Run on your image wf.run_on(url="https://raw.githubusercontent.com/Ikomia-dev/notebooks/main/examples/img/img_fireman.jpg") # Inspect your results output_data = my_algo.get_output(0).get_image() display(output_data) ``` By following these steps, you can easily integrate your algorithm into a larger workflow and process your data with other algorithms. You can also use the Ikomia STUDIO to create and visualize your workflow, and save your workflows for later use.