Table of Contents
In the following chapter, the development of ML modules will be shown in three examples.
An ML module that allows adding a user-defined constant value to image voxels, see Section 14.1, “Creating a New ML Module for Adding Values”.
A more complex ML module that calculates a simple average over voxel values of an entire image, see Section 14.2, “Creating an ML Module For Simple Average”.
Combining the two ML modules in one project (which results in one DLL), with a discussion of the pros and cons of such combinations, see Section 14.3, “Combining Two Modules in One Project”.
The following examples are developed very explicitly to give you some insight into the ML, the MeVis image processing library. Another useful way to start with module development is to copy the source code of an existing module that might already have some of the wanted functionality and adapt it to your needs. For further information, please refer to the ML Guide.
Note | |
---|---|
Developing C++ modules requires a C++ development environment being available on your computer, for example Visual C++ on Windows or Xcode on Mac OS X. |
Note | |
---|---|
It is recommended to open and compile the debug versions for development. |
In the following chapter, we will create a new ML module with the functionality of adding a value to all voxels, in the following steps:
Tip | |
---|---|
This example is delivered with MeVisLab ( |
First of all, make sure that you have a user package defined as described in Section 8.2, “Creating a User Package for Your Project” or create it now.
Then run the Project Wizard and select the link ML Module. This starts the Wizard for C++/ML Modules. Enter the following:
Name: SimpleAdd
Comment: Adds a constant double value to each voxel.
See Also: Arithmetic1
Target Package: Example/General
Project: SimpleAdd
Click Next to proceed.
On the dialog Imaging Module Properties, the inputs and outputs as well as possible sample code can be added to the ML module.
Select the Module Type Classic ML Module. For information on the differences, see the MeVisLab Reference Manual, chapter “ML Wizard”.
Enter the following settings:
Inputs: 1
Outputs: 1
Check Add calculateOutputSubImage() template.
Check Add voxel loop to calculateOutputSubImage().
On the dialog Additional Module Properties, the inputs and outputs as well as possible sample code can be added to the ML module.
Make the following settings:
Check Auto-update output images on field changes (adds handleNotification).
Check Add activateAttachments().
Check Add ML window with fields.
On the dialog Module Field Interface, the fields of the module can be defined (more fields can be added later but this is the easiest way to add fields).
Click New to create a new field, then enter the following:
Field Name: constantValue
Field Type: Double
Field Comment: This constant value is added to each voxel.
Field Value: 0.
Click Create to create the module.
In the default file browser of your system, two folders are opened:
folder with the source code: {packagePath}/Sources/ML/MLSimpleAdd
folder with the module's GUI definition: {packagePath}/Modules/ML/MLSimpleAdd
Note | |
---|---|
For a full list of all created files and their contents, refer to the MeVisLab Reference Manual, chapter “ML Module — Created Files”. |
The foundation of the module has been created with the Wizard. From here on, the programming starts.
Tip | |
---|---|
The Wizard will not close automatically. This way, you can change settings or fields and create the module once more. |
After module creation, the module database needs to be reloaded.
The Project Wizard creates a CMakeLists.txt
file that describes
the typical projects settings and used source files. This file can be translated manually with
the CMake tool into a project
file for your preferred C++ development tool.
But most Integrated Development Environments (IDEs) nowadays can open CMake files directly.
Just make sure that the MLAB_ROOT
environment variable is set on your system
and points to the Packages
directory of your MeVisLab installation,
because this is used to resolve the reference to the 'MeVisLab' project.
For further documentation about our use of CMake see: CMake for MeVisLab - Documentation.
Open the file mlSimpleAdd.cpp
.
Note | |
---|---|
In the following code examples, the comment lines already available in the created |
As we add a constant value to each voxel, we need to adjust the value range of the output image, which results in:
outMin = inMin + constValue outMax = inMax + constValue
In code, this is:
//--------------------------------------------------------------------------------
//! Sets properties of the output image at output outIndex.
//--------------------------------------------------------------------------------
void SimpleAdd::calculateOutputImageProperties (int outIndex, PagedImage* outImage)
{
// get the constant add value
const MLdouble constantValue = _constantValueFld->getDoubleValue();
// get input image's min and max values
const MLdouble inMinValue = getInputImage(0)->getMinVoxelValue();
const MLdouble inMaxValue = getInputImage(0)->getMaxVoxelValue();
// set the output image's min and max values
outputImage->setMinVoxelValue(inMinValue + constantValue);
outputImage->setMaxVoxelValue(inMaxValue + constantValue);
}
Note | |
---|---|
|
Loop over all voxels of the output page and add the constant value. The loop is already generated by the wizard, so only the following line has to be added at the start of the method, to obtain the constant value in the correct data type:
// Compute subimage of output image outIndex from input subimages.
const T constantValue = static_cast<T>(_constantValueFld->getDoubleValue());
That is the datatype of the output image which is the data type of the input image.
Then change the inner line of the following loop from *outVoxel = *inVoxel0;
to *outVoxel = *inVoxel0 + constantValue;
so that the constant value is added to the value of the input voxel:
// Process all row voxels.
for (; p.x <= rowEnd; ++p.x, ++outVoxel, ++inVoxel0)
{
*outVoxel = *inVoxel0 + constantValue;
}
Compile the project (this includes all module files) in the development environment.
(Re)start MeVisLab.
Note | |
---|---|
If the module was edited in the debug version, MeVisLab must be run in the debug mode. |
The restart is necessary
so that the ModuleName.def
file can be found and parsed by MeVisLab.
so that the module DLL is copied to the correct location, from a temporary source folder to the lib folder. (If a .def
file exists but no DLL is found, the module is displayed in red in MeVisLab.)
The module is now available in the (quick) search. Add it to the network.
For optimizing the GUI of the module — that is the panel — open the .def
file. You can do that in two ways:
Open the .def
file in your development environment. The downside is that the development environment does not support the MDL language of the .def
file.
Open the .def
file in the inbuilt text editor MATE, by right-clicking the module in MeVisLab and selecting Related Files → MLSimpleAdd.def from the context menu. The advantage is that MATE supports MDL (and Python). Therefore, it is recommended to edit MDL files primarily with MATE. (More information on MATE can be found in the MeVisLab Reference Manual, chapter “MATE”.)
Add the line
step = 100
to the definition of the field constantValue
in order to adjust the
constant value conveniently. (Smaller steps are barely visible in the output.)
Window {
Vertical {
margin = 3
Field constantValue {
tooltip = "This constant value is added to each voxel."
step = 100 // big change for big effect
}
}
}
Reload the module definition by right-clicking the module and selecting Reload Definition from the context menu. This will only reload the GUI definition, not the module DLL.
To check if everything worked, double-click the module to open the panel and test
Congratulations, you have now implemented your first page-based and demand-driven ML image processing module!
As last step, we will create a little example network.
Load the example network of the module via File → Open. Its name is automatically constructed as <ModuleName>Example.mlab
. So far, the example network only includes the module itself.
Add two modules to the network, namely LocalImage
and View2D
. Connect the image input to the bottom connector and the image output to the top connector of SimpleAdd
.
Double-click SimpleAdd
to open its panel and View2D
to open the viewer. When you now change the steps, the image display changes.
To create the help, right-click the new module and select Edit Help from the context menu. This opens the integrated text editor MATE in a mode to edit a module's help file. See Section 26.9, “Module Help Editor” for more information.
Now the module is ready for usage.
The module including the example network and help file are delivered with the examples of MeVisLab, so feel free to check it out and play around with it.
© 2024 MeVis Medical Solutions AG