SourceXtractorPlusPlus
0.13
Please provide a description of the project.
|
The Partition stage is where the rough detections of the Segmentation stage can be broken down in multiple ones, using more complex algorithms. The Partition class itself does not implement any specific algorithm, it is just responsible for running a number of PartitionSteps (which implement the algorithm logic). The rest of this HowTo describes the actions that need to be performed to add a new algorithm as a PartitionStep and to use it within the SExtractor framework.
Note that SExtractor defines all its classes in the namespace SExtractor. The following coding snippets assumed that the code is in the SExtractor namespace for brevity.
The first thing you need to do is to implement your algorithm logic. This is done by creating a class which implements the PartitionStep interface:
The partitioning algorithm logic is implemented in the partition() method. This method gets as input the source to apply the algorithm to and it returns a vector of sources, which is the result of the partitioning. Note that if you do not want to partition the source, you can just return the input source, as shown at the example.
Retrieving the input source information which is needed by the partitioning algorithm is done via using the methods provided by the SourceInterface class. For example, the following gives access to the sources pixel coordinates:
The full list of the properties provided by SExtractor can be found at the API documentation of the Property class (inheritance diagram). If you need a custom property computed specifically for your partition step, you can refer to howtoaddsourceproperty.
If your algorithm decides that a source should be partitioned, you will need to create new instances of concrete implementations of the SourceInterface. To keep your PartitionStep implementation as flexible as possible, you should not create sources of a specific type yourself. Instead, you can delegate the creation of the sources to a SourceFactory instance, which you can get at your constructor. The following code shows how to modify the example class accordingly:
The SourceFactory itself is an abstract class, which is not bounded to any concrete implementation of the SourceInterface. This gives to your PartitionStep the ability to work with any type of sources. You only have to create them via the factory and set their PixelCoordinateList, according the results of your algorithm (if you are curious to know where the SourceFactory instance will come from, you have to be patient until the Defining the creator for your PartitionStep section bellow). The following code shows an example of how to split the source in two:
Note that you only have to set the PixelCoordinateList property on the sources you create (which is the result of your partitioning). SExtractor is going to compute the rest of the properties for your newly created sources, when they are requested.
After you have finished writing your concrete PartitionStep class, the next step is to let SExtractor to know about its existence. This is done via the configuration system of SExtractor.
SExtractor handes its configuration phase via the Alexandria Configuration framework. Any action done during this phase, is done by implementing the Configuration interface. SExtractor has one such implementation (class PartitionStepConfig), which is responsible for managing the different PartitionSteps. Your configuration class, in its constructor, has to declare that it depends on it. The following code shows the skeleton of the example configuration class:
The initialize() method that is overridden above, is the place where you need to let SExtractor know about your partition step. The above example also contains the code for retrieving the PartitionStepConfig instance.
To register your PartitionStep to SExtractor you need to instruct the PartitionStepConfig class how it can create new instances of it. This is done by using the PartitionStepConfig::addPartitionStepCreator() method. This method gets as input a PartitionStepConfig::PartitionStepCreator, which can be anything that can be called like a function that gets as parameter a SourceFactory and returns a PartitionStep instance. The following code shows how to do this by using a lambda function:
To see what else you can use instead of a lambda function, you can see the documentation of the std::function class.
After you have defined the method which generates your PartitionStep instances you just have to register it to the PartitionStepConfig:
Following the steps described above will instruct SExtractor to always execute your PartitionStep. Instead, it is a good practice to provide a command line option to allow the users to enable or disable the step as they will. To do this you will have to override the getProgramOptions() method of the Configuration interface and define a boolean switch option:
Now you can retrieve the flag at the beginning of your initialize() method and check what the user has requested:
Note that if your PartitionStep needs any other input from the user, you can use the same method to define the command line options to get it. Then, you can pass this information via the constructor of your class.
The final step for enabling your PartitionStep, is to register your configuration class to the SExtractor ConfigManager via the plugin framework. To do this you have to add the following line in the registerPlugin() method of your plugin implementation class:
For more information of how to use the plugin framework you can refer to the related HowTo.
/section partition_step_order Controlling the execution order
Most of the time, the execution order of the partitioning steps is important and might change the results. For this reason, you might want to control which steps are executed before and after your one. Because the ordering of the execution is the same with the order the related configuration classes are initialized, it can be controlled by defining dependencies between the related configuration classes. This has to be done in the constructor of your configuration class. For example:
The following code snipsets contain the full code of the classes described above, for the case you want to copy-paste it:
ExamplePartitionStep.h :
ExamplePartitionConfig.h :
ExamplePartitionPlugin.h :