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.
documentation\doxygen\
modules.dox......................... Doxygen file for documenting your plug-in
resources\
icon.png............................ The icon of your plug-in. GIMP or other programs (including your text editor)
can be used to change this
src\internal\
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
files.cmake /
manifest_headers.cmake................ Information about your plug-in
plugin.xml ........................... BlueBerry integration
If you are not familiar with Qt development, please look into this Qt company page describing .ui files
The C++ files implement a subclass of QmitkAbstractView. In this special case of QmitkRegionGrowing, we added the option 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:
The plug-in will be build as part of MITK Workbench. Do use it start MITK Workbench an select the region growing view in the view menu.
To add a mitk::PointSet for the seed points: QmitkRegionGrowingView.h
Add includes and forward declarations:
Add the point set and a pointer to a QmitkPointListWidget as a private member:
mitk::PointSet::Pointer m_PointSet;
QmitkRegionGrowingView.cpp
CreateQtPartControl():
m_Controls->verticalLayout->addWidget(m_PointListWidget, 1);
{
RenderWindowPartActivated(renderWindowPart);
}
pointSetNode->SetData(m_PointSet);
pointSetNode->SetName("seed points for region growing");
GetDataStorage()->Add(pointSetNode);
m_PointListWidget->SetPointSetNode(pointSetNode);
Interface for a MITK Workbench Part providing a render window.
To use the ITK region grower:
QmitkRegionGrowingView.h
Add the private method:
template <typename TPixel, unsigned int VImageDimension>
void ItkImageProcessing(itk::Image<TPixel, VImageDimension> *itkImage,
mitk::BaseGeometry *imageGeometry);
BaseGeometry Describes the geometry of a data object.
QmitkRegionGrowingView.cpp
Add includes:
#include <itkConnectedThresholdImageFilter.h>
DoImageProcessing():
if (m_PointSet->GetSize() == 0)
{
QMessageBox::information(nullptr,
"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;
}
image, ItkImageProcessing, image->GetGeometry())
#define AccessByItk_1(mitkImage, itkImageTypeFunction, arg1)
And add the new method:
template <typename TPixel, unsigned int VImageDimension>
void QmitkRegionGrowingView::ItkImageProcessing(itk::Image<TPixel, VImageDimension> *itkImage,
{
typedef typename InputImageType::IndexType IndexType;
typedef itk::ConnectedThresholdImageFilter<InputImageType, InputImageType> RegionGrowingFilterType;
typename RegionGrowingFilterType::Pointer regionGrower = RegionGrowingFilterType::New();
regionGrower->SetInput(itkImage);
IndexType seedIndex;
TPixel min(std::numeric_limits<TPixel>::max());
TPixel max(std::numeric_limits<TPixel>::min());
++pointsIterator)
{
if (!imageGeometry->
IsInside(pointsIterator.Value()))
{
continue;
}
imageGeometry->
WorldToIndex(pointsIterator.Value(), seedIndex);
TPixel currentPixelValue = itkImage->GetPixel(seedIndex);
if (currentPixelValue > max)
max = currentPixelValue;
if (currentPixelValue < min)
min = currentPixelValue;
regionGrower->AddSeed(seedIndex);
}
MITK_INFO <<
"Values between " << min <<
" and " << max;
min -= 30;
max += 30;
regionGrower->SetLower(min);
regionGrower->SetUpper(max);
regionGrower->Update();
newNode->SetData(resultImage);
this->GetDataStorage()->Add(newNode);
}
bool IsInside(const mitk::Point3D &p) const
Test whether the point p (world coordinates in mm) is inside the bounding box.
void WorldToIndex(const mitk::Point3D &pt_mm, mitk::Point3D &pt_units) const
Convert world coordinates (in mm) of a point to (continuous!) index coordinates.
DataType::PointsContainer::ConstIterator PointsConstIterator
DataType::PointsContainer PointsContainer
static RenderingManager * GetInstance()
void RequestUpdateAll(RequestType type=REQUEST_UPDATE_ALL)
void CastToMitkImage(const itk::SmartPointer< ItkOutputImageType > &itkimage, itk::SmartPointer< mitk::Image > &mitkoutputimage)
Cast an itk::Image (with a specific type) to an mitk::Image.
::mitk::Image InputImageType
Have fun using MITK!
If you meet any difficulties during your first steps, don't hesitate to ask on the MITK mailing list mitk-.nosp@m.user.nosp@m.s@lis.nosp@m.ts.s.nosp@m.ource.nosp@m.forg.nosp@m.e.net! People there are kind and will try to help you.
[Previous step] [Next Step] [Main tutorial page]