In the following chapter, we will create a new ML module that calculates an average over voxel values, in the following steps:
Tip | |
---|---|
This example is delivered with MeVisLab ( |
For the following example, we expect the user package Example/General
to be available, see Section 14.1.1, “Creating the Basic ML Module with the Project Wizard”.
Run the Project Wizard and select the link ML Module. This starts the Wizard for C++/ML Modules. Enter the following:
Name: SimpleAverage
Comment: Computes the average voxel value of an image.
Keywords: Statistics Average
See Also: ImageStatistics
Target Package: Example/General
Project: SimpleAverage
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().
Note | |
---|---|
Although we will have no real "output" of the module, it is helpful to create an output here, as this will add some of the ML methods necessary for the module functionality. It is easier to exchange or delete some code than to add new code sections manually. |
Click Next to proceed.
On the dialog Additional Module Properties, check Add MDL window with fields.
Click Next to proceed.
On the dialog Module Field Interface, create two new fields:
One field to keep the calculated value:
Field Name: voxelValueAverage
Field Type: Double
Field Value: 0.
One field that will function as Update button:
Field Name: update
Field Type: Notify
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/MLSimpleAverage
folder with the module's GUI definition: {packagePath}/Modules/ML/MLSimpleAverage
Note | |
---|---|
For a full list of all created files and their contents, refer to the MeVisLab Reference Manual, chapter “ML Module — Created Files”. |
Reload the module database.
Prepare the project, as described in Section 14.1.2, “Preparing the Project”.
Open the file mlSimpleAverage.h
.
Add the following two lines to the private
section
//!
NotifyField* _updateFld;
size_t _numVoxels;
MLdouble _sumVoxelValues;
They will be used as follows: All voxel values are added (_sumVoxelValues
) and divided by the number of counted voxels (_numVoxels
).
Remove the following lines.
//! Sets properties of the output image at output outIndex. virtual void calculateOutputImageProperties(int outputIndex, PagedImage* outputImage);
The virtual function calling calculateOutputImageProperties
has to be removed because there will be no image output. If the line is not removed, a warning will be generated by the compiler. (However, the calculateOutputSubImage
template is necessary.)
Open the file mlSimpleAverage.cpp
.
Note | |
---|---|
In the following code examples, the comment lines already available in the created |
Change the constructor call of the superclass from Module(1,1)
to Module(1,0)
.
SimpleAverage::SimpleAverage () : Module(1, 0)
This leaves our module with one input and no output image.
Add the following code in the method handleNotification(Field* field)
.
// Handle changes of module parameters and input image fields here.
if (field == _updateFld)
{
_numVoxels = 0;
_sumVoxelValues = 0;
processAllPages(-1);
MLdouble result = 0;
if (_numVoxels > 0)
{
result = _sumVoxelValues / static_cast<MLdouble>(_numVoxels);
}
_voxelValueAverageFld->setDoubleValue(result);
}
The code includes the important ML Module
method processAllPages()
. This method can be used in algorithms that only extract information from an image (but do not modify it). As the extraction of information is not driven by demand, the loop over all pages has to be implemented with processAllPages()
.
The provided parameter '-1' causes the input image to be read-only for optimization reasons. For further information, see the ML Guide.
Remove the following lines, as no image will be output by this module.
//------------------------------------------------------------------------------ void SimpleAverage::calculateOutputImageProperties(int /*outputIndex*/, PagedImage* outputImage) { // Change properties of output image outputImage here whose // defaults are inherited from the input image 0 (if there is one). }
In the method calculateOutputSubImage(...)
, remove outputSubImage
and outputIndex
from the method's signature. Result:
template <typename T> void SimpleAverage::calculateOutputSubImage (TSubImage<T>* , int , TSubImage<T>* inputSubImage0 )
outIndex
would reference an output image of the module which we do not have.
Replace the line:
const SubImageBox validOutBox = outputSubImage->getValidRegion()
with the line:
const SubImageBox inBox = inputSubImage0->getValidRegion();
Resulting in:
// Compute subimage of output image outIndex from input subimages.
const SubImageBox inBox = inputSubImage0->getValidRegion();
Remove the line
T *outVoxel = outputSubImage->getImagePointer(p);
Replace all occurrences of validOutBox
with inBox
.
Replace the line
*outVoxel = *inVoxel0;
with the lines:
_sumVoxelValues += static_cast<MLdouble>(*inVoxel0); ++_numVoxels;
Remove the ++outVoxel,
from the inner for-loop over the voxel row.
Resulting in:
// Process all row voxels.
for (; p.x <= rowEnd; ++p.x, ++in0Voxel) {
_sumVoxelValues += static_cast<MLdouble>(*in0Voxel);
++_numVoxels;
}
At last, compile the project. Then restart MeVisLab so that the new module is registered and added to the module database.
In MeVisLab, instantiate the new module, right-click it and open the module's .script file.
In the .script file, enter the following lines before the Window
section:
Description { Field voxelValueAverage { editable = No } }
Setting the editable
of a field to No
(or False
or 0
) has two consequences: firstly, the field is not editable by the user which makes sense, because the field should be set from the C++ code only, and secondly, the value of the field is not saved with the .mlab file which makes sense, because the value needs to be calculated in a live network.
Now you can use the new module in MeVisLab.
Add your new module SimpleAverage
and a LocalImage
module to a new network. Connect them and load an image.
Then double-click SimpleAverage
to open its automatic panel and click the Update button on the module panel. The calculated output of SimpleAverage
is displayed.
A module with a similar functionality is available in MeVisLab, called ImageStatistics
.
Add ImageStatistics
via the quick search and compare its mean value with the displayed value of SimpleAverage
. You will find that the results are almost the same apart from the rounding error in the display.
Tip | |
---|---|
This test network is delivered as the example network for |
© 2024 MeVis Medical Solutions AG