Skip to content

Commit

Permalink
Tutorial Step9 is now based on compilable code.
Browse files Browse the repository at this point in the history
  • Loading branch information
saschazelzer committed Feb 26, 2013
1 parent 9b7eeca commit a3ada97
Show file tree
Hide file tree
Showing 15 changed files with 634 additions and 170 deletions.
199 changes: 29 additions & 170 deletions Documentation/Doxygen/Tutorial/Step09.dox
Original file line number Diff line number Diff line change
Expand Up @@ -2,212 +2,71 @@

\page Step09Page MITK Tutorial - Step 9: A plug-in

MITK uses a very modular concept to maximize reusability and portability. You start an application (for example mitkWorkbench, the sample application provided by MITK). An application has several bundles (or plug-ins). A bundle can be a functionality, which in turn can be a view, each of these terms specifying certain behaviour and attributes.
MITK uses a very modular concept to maximize reusability and portability. A MITK application based on the BlueBerry
application framework (for example the MITK Workbench) consists of several bundles (or plug-ins). A bundle can contain
resources and program logic. It can also contribute so-called Views to the main application, which provide a specific
user interface for controlling the bundles functions.

The creation of a MITK plug-in is considerably facilitated by using the MITK BundleGenerator as described in \ref NewPluginPage .
The creation of a MITK plug-in is considerably facilitated by using the MITK PluginGenerator as described in \ref NewPluginPage .

The mentioned tool was used to create a plug-in QmitkRegionGrowing.
Let's first look at what files the BundleGenerator created:
The mentioned tool was used to create a plug-in called org.mitk.example.gui.regiongrowing.
Let's first look at what files the PluginGenerator created:

\verbatim
documentation\doxygen\
modules.dox............................. Doxygen file for documenting your plug-in
modules.dox......................... Doxygen file for documenting your plug-in

resources\
icon.xpm................................ The icon of your plug-in. GIMP or other programs (including your text editor)
can be used to change this
icon.xpm............................ The icon of your plug-in. GIMP or other programs (including your text editor)
can be used to change this

src\internal\
QmitkMITKRegionGrowingView.cpp.......... The most important file, implementing behaviour
QmitkMITKRegionGrowingView.h............ Header file of the functionality
QmitkMITKRegionGrowingViewControls.ui... XML file of the Qt Designer, describes buttons, combo boxes, etc. of your controls
QmitkRegionGrowingView.cpp.......... The most important file, implementing behaviour
QmitkRegionGrowingView.h............ Header file of the functionality
QmitkRegionGrowingViewControls.ui... XML file of the Qt Designer, describes buttons, combo boxes, etc. of your controls

CMakeLists.txt \.......................... Build system related files for CMake
CMakeLists.txt \...................... Build system related files for CMake
files.cmake /
manifest_headers.cmake.................... Information about your plug-in
plugin.xml ............................... BlueBerry integration
manifest_headers.cmake................ Information about your plug-in
plugin.xml ........................... BlueBerry integration
\endverbatim

If you are not familiar with Qt development, please look into
<a href="http://doc.trolltech.com/4.6/designer-manual.html">this Trolltech page describing .ui files</a> (no, forget about the please, DO it!)
<a href="http://doc.qt.digia.com/4.7/designer-manual.html">this Digia page describing .ui files</a> (no, forget about the please, DO it!)

The C++ files implement a subclass of QmitkAbstractView. In this special case of QmitkRegionGrowing, we added the ability to set some seed points and run a region grower. If you are interested in the concrete changes necessary to turn a freshly generated QmitkRegionGrowing into an integrated one:

Since an access to the StdMultiWidget is needed, manifest_headers.cmake has to be edited:
\verbatim
set(Require-Plugin org.mitk.gui.qt.common org.mitk.gui.qt.stdmultiwidgeteditor)
\endverbatim

To add a PointSet for the seed points:
To add a mitk::PointSet for the seed points:
QmitkRegionGrowingView.h

Add includes:
\verbatim
#include "QmitkPointListWidget.h"
#include "QmitkStdMultiWidget.h"
#include "QmitkStdMultiWidgetEditor.h"
\endverbatim
Add includes and forward declarations:
\snippet QmitkRegionGrowingView.h includes

Add the point set as protected object and add Pointers for a QmitkPointListWidget and a QmitkStdMultiWidget:
\verbatim
/// \brief This is the actual seed point data object
mitk::PointSet::Pointer m_PointSet;

QmitkPointListWidget* lstPoints;
QmitkStdMultiWidget* m_MultiWidget;
\endverbatim
Add the point set and a pointer to a QmitkPointListWidget as a private member:
\snippet QmitkRegionGrowingView.h members

QmitkRegionGrowingView.cpp

CreateQtPartControl():
\verbatim
// create a QmitkPointListWidget and add it to the widget created from .ui file
lstPoints = new QmitkPointListWidget();
m_Controls.verticalLayout->addWidget(lstPoints);

// get access to StdMultiWidget by using RenderWindowPart
QmitkStdMultiWidgetEditor* qSMWE = dynamic_cast<QmitkStdMultiWidgetEditor*>(GetRenderWindowPart());
m_MultiWidget = qSMWE->GetStdMultiWidget();

// let the point set widget know about the multi widget (crosshair updates)
lstPoints->SetMultiWidget( m_MultiWidget );

// create a new DataTreeNode containing a PointSet with some interaction
m_PointSet = mitk::PointSet::New();

mitk::DataNode::Pointer pointSetNode = mitk::DataNode::New();
pointSetNode->SetData( m_PointSet );
pointSetNode->SetName("seed points for region growing");
pointSetNode->SetProperty("helper object", mitk::BoolProperty::New(true) );
pointSetNode->SetProperty("layer", mitk::IntProperty::New(1024) );

// add the pointset to the data tree (for rendering and access by other modules)
GetDataStorage()->Add( pointSetNode );

// tell the GUI widget about out point set
lstPoints->SetPointSetNode( pointSetNode );
\endverbatim
\snippet QmitkRegionGrowingView.cpp cpp-createqtpartcontrol

To use the ITK region grower:

QmitkRegionGrowingView.h

Add protected method:
\verbatim
/*!
\brief ITK image processing function
This function is templated like an ITK image. The MITK-Macro AccessByItk determines the actual pixel type and dimensionality of
a given MITK image and calls this function for further processing (in our case region growing)
*/
template < typename TPixel, unsigned int VImageDimension >
void ItkImageProcessing( itk::Image< TPixel, VImageDimension >* itkImage, mitk::Geometry3D* imageGeometry );
\endverbatim
Add the private method:
\snippet QmitkRegionGrowingView.h itkimageprocessing

QmitkRegionGrowingView.cpp

Add includes:
\verbatim
// MITK
#include "mitkImageAccessByItk.h"
#include "mitkITKImageImport.h"
#include "mitkProperties.h"
#include "mitkColorProperty.h"

// ITK
#include <itkConnectedThresholdImageFilter.h>
\snippet QmitkRegionGrowingView.cpp cpp-includes

\endverbatim

DoImageProcessing();
\verbatim
// So we have an image. Let's see if the user has set some seed points already
if ( m_PointSet->GetSize() == 0 )
{
// no points there. Not good for region growing
QMessageBox::information( NULL, "Region growing functionality",
"Please set some seed points inside the image first.\n"
"(hold Shift key and click left mouse button inside the image.)"
);
return;
}

// actually perform region growing. Here we have both an image and some seed points
AccessByItk_1( image, ItkImageProcessing, image->GetGeometry() ); // some magic to call the correctly templated function
\endverbatim
DoImageProcessing():
\snippet QmitkRegionGrowingView.cpp cpp-doimageprocessing

And add the new method:
\verbatim
template < typename TPixel, unsigned int VImageDimension >
void QmitkRegionGrowingView::ItkImageProcessing( itk::Image< TPixel, VImageDimension >* itkImage, mitk::Geometry3D* imageGeometry )
{
typedef itk::Image< TPixel, VImageDimension > InputImageType;
typedef typename InputImageType::IndexType IndexType;

// instantiate an ITK region growing filter, set its parameters
typedef itk::ConnectedThresholdImageFilter<InputImageType, InputImageType> RegionGrowingFilterType;
typename RegionGrowingFilterType::Pointer regionGrower = RegionGrowingFilterType::New();
regionGrower->SetInput( itkImage ); // don't forget this

// determine a thresholding interval
IndexType seedIndex;
TPixel min( std::numeric_limits<TPixel>::max() );
TPixel max( std::numeric_limits<TPixel>::min() );
mitk::PointSet::PointsContainer* points = m_PointSet->GetPointSet()->GetPoints();
for ( mitk::PointSet::PointsConstIterator pointsIterator = points->Begin();
pointsIterator != points->End();
++pointsIterator )
{
// first test if this point is inside the image at all
if ( !imageGeometry->IsInside( pointsIterator.Value()) )
{
continue;
}

// convert world coordinates to image indices
imageGeometry->WorldToIndex( pointsIterator.Value(), seedIndex);

// get the pixel value at this point
TPixel currentPixelValue = itkImage->GetPixel( seedIndex );

// adjust minimum and maximum values
if (currentPixelValue > max)
max = currentPixelValue;

if (currentPixelValue < min)
min = currentPixelValue;

regionGrower->AddSeed( seedIndex );
}

MITK_INFO << "Values between " << min << " and " << max;

min -= 30;
max += 30;

// set thresholds and execute filter
regionGrower->SetLower( min );
regionGrower->SetUpper( max );

regionGrower->Update();

mitk::Image::Pointer resultImage = mitk::ImportItkImage( regionGrower->GetOutput() );
mitk::DataNode::Pointer newNode = mitk::DataNode::New();
newNode->SetData( resultImage );

// set some properties
newNode->SetProperty("binary", mitk::BoolProperty::New(true));
newNode->SetProperty("name", mitk::StringProperty::New("dumb segmentation"));
newNode->SetProperty("color", mitk::ColorProperty::New(1.0,0.0,0.0));
newNode->SetProperty("volumerendering", mitk::BoolProperty::New(true));
newNode->SetProperty("layer", mitk::IntProperty::New(1));
newNode->SetProperty("opacity", mitk::FloatProperty::New(0.5));

// add result to data tree
this->GetDataStorage()->Add( newNode );
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}

\endverbatim
\snippet QmitkRegionGrowingView.cpp cpp-itkimageaccess

Have fun using MITK!

Expand Down
1 change: 1 addition & 0 deletions Examples/Plugins/PluginList.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ set(MITK_EXAMPLE_PLUGINS
org.mitk.example.gui.selectionservicemitk.views:ON
org.mitk.example.gui.extensionpointdefinition:ON
org.mitk.example.gui.extensionpointcontribution:ON
org.mitk.example.gui.regiongrowing:ON
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
project(org_mitk_example_gui_regiongrowing)

MACRO_CREATE_MITK_CTK_PLUGIN(
EXPORT_DIRECTIVE REGIONGROWING_EXPORT
EXPORTED_INCLUDE_SUFFIXES src
MODULE_DEPENDENCIES QmitkExt
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
\page org_mitk_example_gui_regiongrowing Region Grower Example

\image html icon.xpm "Icon of Region Grower Example"

Available sections:
- \ref org_mitk_example_gui_regiongrowingOverview

\section org_mitk_example_gui_regiongrowingOverview
Describe the features of your awesome plugin here
<ul>
<li>Increases productivity
<li>Creates beautiful images
<li>Generates PhD thesis
<li>Brings world peace
</ul>

*/
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/* XPM */
static const char * icon_xpm[] = {
"16 16 2 1",
" c #FF0000",
". c #000000",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" "};
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
\defgroup org_mitk_example_gui_regiongrowing org.mitk.example.gui.regiongrowing
\ingroup MITKPlugins

\brief Describe your plugin here.

*/

/**
\defgroup org_mitk_example_gui_regiongrowing_internal Internal
\ingroup org_mitk_example_gui_regiongrowing

\brief This subcategory includes the internal classes of the org.mitk.example.gui.regiongrowing plugin. Other
plugins must not rely on these classes. They contain implementation details and their interface
may change at any time. We mean it.
*/
42 changes: 42 additions & 0 deletions Examples/Plugins/org.mitk.example.gui.regiongrowing/files.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
set(SRC_CPP_FILES

)

set(INTERNAL_CPP_FILES
org_mitk_example_gui_regiongrowing_Activator.cpp
QmitkRegionGrowingView.cpp
)

set(UI_FILES
src/internal/QmitkRegionGrowingViewControls.ui
)

set(MOC_H_FILES
src/internal/org_mitk_example_gui_regiongrowing_Activator.h
src/internal/QmitkRegionGrowingView.h
)

# list of resource files which can be used by the plug-in
# system without loading the plug-ins shared library,
# for example the icon used in the menu and tabs for the
# plug-in views in the workbench
set(CACHED_RESOURCE_FILES
resources/icon.xpm
plugin.xml
)

# list of Qt .qrc files which contain additional resources
# specific to this plugin
set(QRC_FILES

)

set(CPP_FILES )

foreach(file ${SRC_CPP_FILES})
set(CPP_FILES ${CPP_FILES} src/${file})
endforeach(file ${SRC_CPP_FILES})

foreach(file ${INTERNAL_CPP_FILES})
set(CPP_FILES ${CPP_FILES} src/internal/${file})
endforeach(file ${INTERNAL_CPP_FILES})
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
set(Plugin-Name "Region Grower Example")
set(Plugin-Version "0.1")
set(Plugin-Vendor "DKFZ, Medical and Biological Informatics")
set(Plugin-ContactAddress "")
set(Require-Plugin org.mitk.gui.qt.common)
11 changes: 11 additions & 0 deletions Examples/Plugins/org.mitk.example.gui.regiongrowing/plugin.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<plugin>

<extension point="org.blueberry.ui.views">
<view id="org.mitk.views.example.regiongrowing"
name="Region Growing"
class="QmitkRegionGrowingView"
icon="resources/icon.xpm" />
</extension>

</plugin>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/* XPM */
static const char * icon_xpm[] = {
"16 16 2 1",
" c #FF0000",
". c #000000",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" "};
Loading

0 comments on commit a3ada97

Please sign in to comment.