diff --git a/Plugins/org.mitk.gui.qt.imagecropper/files.cmake b/Plugins/org.mitk.gui.qt.imagecropper/files.cmake
index 27552186bb..59435c5859 100644
--- a/Plugins/org.mitk.gui.qt.imagecropper/files.cmake
+++ b/Plugins/org.mitk.gui.qt.imagecropper/files.cmake
@@ -1,36 +1,32 @@
-set(SRC_CPP_FILES
-
-)
-
set(INTERNAL_CPP_FILES
- org_mitk_gui_qt_imagecropper_Activator.cpp
- QmitkImageCropper.cpp
+ mitkPluginActivator.cpp
+ QmitkImageCropperView.cpp
)
set(UI_FILES
- src/internal/ImageCropperControls.ui
+ src/internal/QmitkImageCropperViewControls.ui
)
set(MOC_H_FILES
- src/internal/org_mitk_gui_qt_imagecropper_Activator.h
- src/internal/QmitkImageCropper.h
+ src/internal/mitkPluginActivator.h
+ src/internal/QmitkImageCropperView.h
)
set(CACHED_RESOURCE_FILES
resources/crop.svg
plugin.xml
)
set(QRC_FILES
resources/imagecropper.qrc
)
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})
diff --git a/Plugins/org.mitk.gui.qt.imagecropper/plugin.xml b/Plugins/org.mitk.gui.qt.imagecropper/plugin.xml
index 7b2df1f616..ccc04b49d1 100644
--- a/Plugins/org.mitk.gui.qt.imagecropper/plugin.xml
+++ b/Plugins/org.mitk.gui.qt.imagecropper/plugin.xml
@@ -1,27 +1,27 @@
+ class="QmitkImageCropperView" >
Crop images to a given size
diff --git a/Plugins/org.mitk.gui.qt.imagecropper/src/internal/ImageCropperControls.ui b/Plugins/org.mitk.gui.qt.imagecropper/src/internal/ImageCropperControls.ui
deleted file mode 100644
index 2c0107ebed..0000000000
--- a/Plugins/org.mitk.gui.qt.imagecropper/src/internal/ImageCropperControls.ui
+++ /dev/null
@@ -1,1133 +0,0 @@
-
-
- ImageCropperControls
-
-
-
- 0
- 0
- 329
- 863
-
-
-
-
- 0
- 0
-
-
-
- QmitkTemplate
-
-
- -
-
-
- 3
-
-
-
-
-
-
- 0
- 0
-
-
-
- QLabel { color: rgb(255, 0, 0) }
-
-
- Please select an image.
-
-
-
- -
-
-
-
-
-
-
-
- 255
- 0
- 0
-
-
-
-
-
-
- 255
- 0
- 0
-
-
-
-
-
-
- 255
- 127
- 127
-
-
-
-
-
-
- 255
- 63
- 63
-
-
-
-
-
-
- 127
- 0
- 0
-
-
-
-
-
-
- 170
- 0
- 0
-
-
-
-
-
-
- 0
- 0
- 0
-
-
-
-
-
-
- 255
- 255
- 255
-
-
-
-
-
-
- 0
- 0
- 0
-
-
-
-
-
-
- 255
- 255
- 255
-
-
-
-
-
-
- 255
- 0
- 0
-
-
-
-
-
-
- 0
- 0
- 0
-
-
-
-
-
-
- 255
- 127
- 127
-
-
-
-
-
-
- 255
- 255
- 220
-
-
-
-
-
-
- 0
- 0
- 0
-
-
-
-
-
-
-
-
- 255
- 0
- 0
-
-
-
-
-
-
- 255
- 0
- 0
-
-
-
-
-
-
- 255
- 127
- 127
-
-
-
-
-
-
- 255
- 63
- 63
-
-
-
-
-
-
- 127
- 0
- 0
-
-
-
-
-
-
- 170
- 0
- 0
-
-
-
-
-
-
- 0
- 0
- 0
-
-
-
-
-
-
- 255
- 255
- 255
-
-
-
-
-
-
- 0
- 0
- 0
-
-
-
-
-
-
- 255
- 255
- 255
-
-
-
-
-
-
- 255
- 0
- 0
-
-
-
-
-
-
- 0
- 0
- 0
-
-
-
-
-
-
- 255
- 127
- 127
-
-
-
-
-
-
- 255
- 255
- 220
-
-
-
-
-
-
- 0
- 0
- 0
-
-
-
-
-
-
-
-
- 120
- 120
- 120
-
-
-
-
-
-
- 255
- 0
- 0
-
-
-
-
-
-
- 255
- 127
- 127
-
-
-
-
-
-
- 255
- 63
- 63
-
-
-
-
-
-
- 127
- 0
- 0
-
-
-
-
-
-
- 170
- 0
- 0
-
-
-
-
-
-
- 127
- 0
- 0
-
-
-
-
-
-
- 255
- 255
- 255
-
-
-
-
-
-
- 127
- 0
- 0
-
-
-
-
-
-
- 255
- 0
- 0
-
-
-
-
-
-
- 255
- 0
- 0
-
-
-
-
-
-
- 0
- 0
- 0
-
-
-
-
-
-
- 255
- 0
- 0
-
-
-
-
-
-
- 255
- 255
- 220
-
-
-
-
-
-
- 0
- 0
- 0
-
-
-
-
-
-
-
- Please select a bounding object.
-
-
-
-
-
- -
-
-
- false
-
-
-
- 0
- 0
-
-
-
-
- 0
- 90
-
-
-
- Bounding object
-
-
-
-
-
-
-
-
-
-
- 0
- 0
-
-
-
-
- 16777215
- 16777215
-
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- New
-
-
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Do Cropping
-
-
- Mask
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Crop
-
-
-
-
-
-
- -
-
-
- true
-
-
-
-
-
-
-
- 255
- 0
- 0
-
-
-
-
-
-
- 255
- 0
- 0
-
-
-
-
-
-
- 255
- 127
- 127
-
-
-
-
-
-
- 255
- 63
- 63
-
-
-
-
-
-
- 127
- 0
- 0
-
-
-
-
-
-
- 170
- 0
- 0
-
-
-
-
-
-
- 255
- 0
- 0
-
-
-
-
-
-
- 255
- 255
- 255
-
-
-
-
-
-
- 0
- 0
- 0
-
-
-
-
-
-
- 255
- 255
- 255
-
-
-
-
-
-
- 255
- 0
- 0
-
-
-
-
-
-
- 0
- 0
- 0
-
-
-
-
-
-
- 255
- 127
- 127
-
-
-
-
-
-
- 255
- 255
- 220
-
-
-
-
-
-
- 0
- 0
- 0
-
-
-
-
-
-
-
-
- 255
- 0
- 0
-
-
-
-
-
-
- 255
- 0
- 0
-
-
-
-
-
-
- 255
- 127
- 127
-
-
-
-
-
-
- 255
- 63
- 63
-
-
-
-
-
-
- 127
- 0
- 0
-
-
-
-
-
-
- 170
- 0
- 0
-
-
-
-
-
-
- 255
- 0
- 0
-
-
-
-
-
-
- 255
- 255
- 255
-
-
-
-
-
-
- 0
- 0
- 0
-
-
-
-
-
-
- 255
- 255
- 255
-
-
-
-
-
-
- 255
- 0
- 0
-
-
-
-
-
-
- 0
- 0
- 0
-
-
-
-
-
-
- 255
- 127
- 127
-
-
-
-
-
-
- 255
- 255
- 220
-
-
-
-
-
-
- 0
- 0
- 0
-
-
-
-
-
-
-
-
- 127
- 0
- 0
-
-
-
-
-
-
- 255
- 0
- 0
-
-
-
-
-
-
- 255
- 127
- 127
-
-
-
-
-
-
- 255
- 63
- 63
-
-
-
-
-
-
- 127
- 0
- 0
-
-
-
-
-
-
- 170
- 0
- 0
-
-
-
-
-
-
- 127
- 0
- 0
-
-
-
-
-
-
- 255
- 255
- 255
-
-
-
-
-
-
- 127
- 0
- 0
-
-
-
-
-
-
- 255
- 0
- 0
-
-
-
-
-
-
- 255
- 0
- 0
-
-
-
-
-
-
- 0
- 0
- 0
-
-
-
-
-
-
- 255
- 0
- 0
-
-
-
-
-
-
- 255
- 255
- 220
-
-
-
-
-
-
- 0
- 0
- 0
-
-
-
-
-
-
-
- Image geometry is rotated, result won't be pixel-aligned. You can reinit your image to get a pixel-aligned result, though.
-
-
- Qt::PlainText
-
-
- true
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 25
-
-
-
- Advanced settings
-
-
- false
-
-
- 100
-
-
- Qt::ToolButtonTextBesideIcon
-
-
- false
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 120
-
-
-
- Output image settings
-
-
-
-
-
-
-
-
-
-
- 0
- 0
-
-
-
- Outside pixel value (masking):
-
-
-
- -
-
-
- false
-
-
-
- 0
- 0
-
-
-
-
- 16777210
- 16777215
-
-
-
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Overrride original image
-
-
- false
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Only crop current timestep
- / cut off other timesteps
-
-
-
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
-
-
-
-
-
- QmitkDataStorageComboBox
- QComboBox
- QmitkDataStorageComboBox.h
-
-
- ctkExpandButton
- QToolButton
-
-
-
-
-
-
diff --git a/Plugins/org.mitk.gui.qt.imagecropper/src/internal/QmitkImageCropper.cpp b/Plugins/org.mitk.gui.qt.imagecropper/src/internal/QmitkImageCropper.cpp
deleted file mode 100644
index 6b4c50132b..0000000000
--- a/Plugins/org.mitk.gui.qt.imagecropper/src/internal/QmitkImageCropper.cpp
+++ /dev/null
@@ -1,574 +0,0 @@
-/*============================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center (DKFZ)
-All rights reserved.
-
-Use of this source code is governed by a 3-clause BSD license that can be
-found in the LICENSE file.
-
-============================================================================*/
-
-#include "QmitkImageCropper.h"
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include // Includes for image casting between ITK and MITK: added after using Plugin Generator
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-
-#include
-#include
-
-const std::string QmitkImageCropper::VIEW_ID = "org.mitk.views.qmitkimagecropper";
-
-QmitkImageCropper::QmitkImageCropper(QObject *)
- : m_ParentWidget(nullptr),
- m_ImageNode(nullptr),
- m_CroppingObject(nullptr),
- m_CroppingObjectNode(nullptr),
- m_BoundingShapeInteractor(nullptr),
- m_CropOutsideValue(0),
- m_Advanced(0),
- m_Active(0),
- m_ScrollEnabled(true)
-{
- CreateBoundingShapeInteractor(false);
-}
-
-QmitkImageCropper::~QmitkImageCropper()
-{
- //delete pointer objects
- m_CroppingObjectNode = nullptr;
- m_CroppingObject = nullptr;
-
- //disable interactor
- if (m_BoundingShapeInteractor != nullptr)
- {
- m_BoundingShapeInteractor->SetDataNode(nullptr);
- m_BoundingShapeInteractor->EnableInteraction(false);
- }
-}
-
-void QmitkImageCropper::SetFocus()
-{
- m_Controls.buttonCreateNewBoundingBox->setFocus();
-}
-
-void QmitkImageCropper::CreateQtPartControl(QWidget *parent)
-{
- // create GUI widgets from the Qt Designer's .ui file
- m_Controls.setupUi(parent);
-
- m_Controls.boundingShapeSelector->SetDataStorage(this->GetDataStorage());
- m_Controls.boundingShapeSelector->SetPredicate(mitk::NodePredicateAnd::New(
- mitk::TNodePredicateDataType::New(),
- mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object"))));
- m_CroppingObjectNode = m_Controls.boundingShapeSelector->GetSelectedNode();
-
- connect(m_Controls.buttonCropping, SIGNAL(clicked()), this, SLOT(DoCropping()));
- connect(m_Controls.buttonMasking, SIGNAL(clicked()), this, SLOT(DoMasking()));
- connect(m_Controls.boundingShapeSelector, SIGNAL(OnSelectionChanged(const mitk::DataNode*)),
- this, SLOT(OnDataSelectionChanged(const mitk::DataNode*)));
- connect(m_Controls.buttonCreateNewBoundingBox, SIGNAL(clicked()), this, SLOT(DoCreateNewBoundingObject()));
- connect(m_Controls.buttonAdvancedSettings, SIGNAL(clicked()), this, SLOT(OnAdvancedSettingsButtonToggled()));
- connect(m_Controls.spinBoxOutsidePixelValue, SIGNAL(valueChanged(int)), this, SLOT(OnSliderValueChanged(int)));
-
- setDefaultGUI();
- m_Controls.labelWarningRotation->setVisible(false);
-
- m_Advanced = false;
- this->OnAdvancedSettingsButtonToggled();
- m_ParentWidget = parent;
-}
-
-void QmitkImageCropper::OnDataSelectionChanged(const mitk::DataNode*)
-{
- m_Controls.boundingShapeSelector->setEnabled(true);
- m_CroppingObjectNode = m_Controls.boundingShapeSelector->GetSelectedNode();
-
- if (m_CroppingObjectNode.IsNotNull() && dynamic_cast(this->m_CroppingObjectNode->GetData()))
- {
- m_Controls.buttonAdvancedSettings->setEnabled(true);
- m_Controls.groupImageSettings->setEnabled(true);
- m_Controls.labelWarningBB->setVisible(false);
- m_CroppingObject = dynamic_cast(m_CroppingObjectNode->GetData());
- m_Advanced = true;
-
- m_BoundingShapeInteractor->EnableInteraction(true);
- m_BoundingShapeInteractor->SetDataNode(m_CroppingObjectNode);
-
- mitk::RenderingManager::GetInstance()->InitializeViews();
- mitk::RenderingManager::GetInstance()->RequestUpdateAll();
- }
- else
- {
- setDefaultGUI();
- m_CroppingObject = nullptr;
- m_BoundingShapeInteractor->EnableInteraction(false);
- m_BoundingShapeInteractor->SetDataNode(nullptr);
- m_Advanced = false;
- this->OnAdvancedSettingsButtonToggled();
- }
-}
-
-void QmitkImageCropper::OnAdvancedSettingsButtonToggled()
-{
- m_Controls.groupImageSettings->setVisible(m_Advanced);
- m_Advanced = !m_Advanced;
-}
-
-void QmitkImageCropper::CreateBoundingShapeInteractor(bool rotationEnabled)
-{
- if (m_BoundingShapeInteractor.IsNull())
- {
- m_BoundingShapeInteractor = mitk::BoundingShapeInteractor::New();
- m_BoundingShapeInteractor->LoadStateMachine("BoundingShapeInteraction.xml", us::ModuleRegistry::GetModule("MitkBoundingShape"));
- m_BoundingShapeInteractor->SetEventConfig("BoundingShapeMouseConfig.xml", us::ModuleRegistry::GetModule("MitkBoundingShape"));
- }
- m_BoundingShapeInteractor->SetRotationEnabled(rotationEnabled);
-}
-
-mitk::Geometry3D::Pointer QmitkImageCropper::InitializeWithImageGeometry(mitk::BaseGeometry::Pointer geometry)
-{
- // convert a basegeometry into a Geometry3D (otherwise IO is not working properly)
- if (geometry == nullptr)
- mitkThrow() << "Geometry is not valid.";
-
- auto boundingGeometry = mitk::Geometry3D::New();
- boundingGeometry->SetBounds(geometry->GetBounds());
- boundingGeometry->SetImageGeometry(geometry->GetImageGeometry());
- boundingGeometry->SetOrigin(geometry->GetOrigin());
- boundingGeometry->SetSpacing(geometry->GetSpacing());
- boundingGeometry->SetIndexToWorldTransform(geometry->GetIndexToWorldTransform());
- boundingGeometry->Modified();
- return boundingGeometry;
-}
-
-QString QmitkImageCropper::AdaptBoundingObjectName(const QString& name) const
-{
- unsigned int counter = 2;
- QString newName = QString("%1 %2").arg(name).arg(counter);
-
- while (nullptr != this->GetDataStorage()->GetNode(mitk::NodePredicateFunction::New([&newName](const mitk::DataNode *node)
- {
- return 0 == node->GetName().compare(newName.toStdString());
- })))
- {
- newName = QString("%1 %2").arg(name).arg(++counter);
- }
-
- return newName;
-}
-
-void QmitkImageCropper::DoCreateNewBoundingObject()
-{
- if (!m_ImageNode.IsExpired())
- {
- auto imageNode = m_ImageNode.Lock();
- QString name = QString::fromStdString(imageNode->GetName() + " Bounding Shape");
-
- auto boundingShape = this->GetDataStorage()->GetNode(mitk::NodePredicateFunction::New([&name](const mitk::DataNode *node)
- {
- return 0 == node->GetName().compare(name.toStdString());
- }));
-
- if (nullptr != boundingShape)
- name = this->AdaptBoundingObjectName(name);
-
- m_Controls.buttonCropping->setEnabled(true);
- m_Controls.buttonMasking->setEnabled(true);
- m_Controls.boundingShapeSelector->setEnabled(true);
- m_Controls.groupImageSettings->setEnabled(true);
-
- // get current timestep to support 3d+t images
- auto renderWindowPart = this->GetRenderWindowPart(mitk::WorkbenchUtil::IRenderWindowPartStrategy::OPEN);
- int timeStep = renderWindowPart->GetTimeNavigationController()->GetTime()->GetPos();
- mitk::BaseGeometry::Pointer imageGeometry = static_cast(imageNode->GetData()->GetGeometry(timeStep));
-
- m_CroppingObject = mitk::GeometryData::New();
- m_CroppingObject->SetGeometry(static_cast(this->InitializeWithImageGeometry(imageGeometry)));
- m_CroppingObjectNode = mitk::DataNode::New();
- m_CroppingObjectNode->SetData(m_CroppingObject);
- m_CroppingObjectNode->SetProperty("name", mitk::StringProperty::New(name.toStdString()));
- m_CroppingObjectNode->SetProperty("color", mitk::ColorProperty::New(1.0, 1.0, 1.0));
- m_CroppingObjectNode->SetProperty("opacity", mitk::FloatProperty::New(0.6));
- m_CroppingObjectNode->SetProperty("layer", mitk::IntProperty::New(99));
- m_CroppingObjectNode->AddProperty("handle size factor", mitk::DoubleProperty::New(1.0 / 40.0));
- m_CroppingObjectNode->SetBoolProperty("pickable", true);
-
- if (!this->GetDataStorage()->Exists(m_CroppingObjectNode))
- {
- GetDataStorage()->Add(m_CroppingObjectNode, imageNode);
- m_Controls.boundingShapeSelector->SetSelectedNode(m_CroppingObjectNode);
- m_CroppingObjectNode->SetVisibility(true);
- m_BoundingShapeInteractor->EnableInteraction(true);
- m_BoundingShapeInteractor->SetDataNode(this->m_CroppingObjectNode);
- this->OnDataSelectionChanged(m_CroppingObjectNode);
- }
- }
- // Adjust coordinate system by doing a reinit on
- auto tempDataStorage = mitk::DataStorage::SetOfObjects::New();
- tempDataStorage->InsertElement(0, m_CroppingObjectNode);
-
- //// initialize the views to the bounding geometry
- //mitk::TimeGeometry::Pointer bounds = this->GetDataStorage()->ComputeBoundingGeometry3D(tempDataStorage);
- //mitk::RenderingManager::GetInstance()->InitializeViews(bounds);
- //mitk::RenderingManager::GetInstance()->RequestUpdateAll();
-}
-void QmitkImageCropper::setDefaultGUI()
-{
- m_Controls.labelWarningImage->setStyleSheet(" QLabel { color: rgb(255, 0, 0) }");
- m_Controls.labelWarningImage->setText(QString::fromStdString("Select an image."));
- m_Controls.labelWarningImage->setVisible(true);
- m_Controls.labelWarningBB->setStyleSheet(" QLabel { color: rgb(255, 0, 0) }");
- m_Controls.labelWarningBB->setText(QString::fromStdString("Create a bounding shape below."));
- m_Controls.labelWarningBB->setVisible(true);
- m_Controls.buttonCreateNewBoundingBox->setEnabled(false);
- m_Controls.labelWarningRotation->setVisible(false);
- m_Controls.buttonCropping->setEnabled(false);
- m_Controls.buttonMasking->setEnabled(false);
- m_Controls.boundingShapeSelector->setEnabled(false);
- m_Controls.buttonAdvancedSettings->setEnabled(false);
- m_Controls.groupImageSettings->setEnabled(false);
- m_Controls.checkOverwriteImage->setChecked(false);
- m_Controls.checkBoxCropTimeStepOnly->setChecked(false);
-}
-
-void QmitkImageCropper::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/,
- const QList& nodes)
-{
- bool rotationEnabled = false;
- if (nodes.empty())
- {
- setDefaultGUI();
- return;
- }
- m_ParentWidget->setEnabled(true);
-
- foreach(mitk::DataNode::Pointer node, nodes)
- {
- if (node.IsNotNull() && dynamic_cast(node->GetData()))
- {
- m_ImageNode = nodes[0];
- m_Controls.groupBoundingObject->setEnabled(true);
- m_Controls.labelWarningImage->setStyleSheet("");
- m_Controls.labelWarningImage->setText(QString::fromStdString("Selected image: " + nodes[0]->GetName()));
- m_Controls.buttonCreateNewBoundingBox->setEnabled(true);
-
- mitk::Image::Pointer image = dynamic_cast(nodes[0]->GetData());
- if (image != nullptr)
- {
- if (image->GetDimension() < 3) {
- QMessageBox::warning(nullptr,
- tr("Invalid image selected"),
- tr("ImageCropper only works with 3 or more dimensions."),
- QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton);
- setDefaultGUI();
- return;
- }
-
- vtkSmartPointer imageMat = image->GetGeometry()->GetVtkMatrix();
- // check whether the image geometry is rotated, if so, no pixel aligned cropping or masking can be performed
- if ((imageMat->GetElement(1, 0) == 0.0) && (imageMat->GetElement(0, 1) == 0.0) &&
- (imageMat->GetElement(1, 2) == 0.0) && (imageMat->GetElement(2, 1) == 0.0) &&
- (imageMat->GetElement(2, 0) == 0.0) && (imageMat->GetElement(0, 2) == 0.0))
- {
- rotationEnabled = false;
- m_Controls.labelWarningRotation->setVisible(false);
- }
- else
- {
- rotationEnabled = true;
- m_Controls.labelWarningRotation->setStyleSheet(" QLabel { color: rgb(255, 0, 0) }");
- m_Controls.labelWarningRotation->setVisible(true);
- }
-
- this->CreateBoundingShapeInteractor(rotationEnabled);
- m_CroppingObjectNode = m_Controls.boundingShapeSelector->GetSelectedNode();
- if (m_CroppingObjectNode != nullptr)
- {
- this->OnDataSelectionChanged(m_CroppingObjectNode);
- m_BoundingShapeInteractor->EnableInteraction(true);
- m_BoundingShapeInteractor->SetDataNode(this->m_CroppingObjectNode);
- m_Controls.boundingShapeSelector->setEnabled(true);
- }
-
- if (image->GetPixelType().GetPixelType() == itk::ImageIOBase::SCALAR)
- {
- // Might be changed with the upcoming new image statistics plugin
- //(recomputation might be very expensive for large images ;) )
- auto statistics = image->GetStatistics();
- auto minPixelValue = statistics->GetScalarValueMin();
- auto maxPixelValue = statistics->GetScalarValueMax();
-
- if (minPixelValue < std::numeric_limits::min()) {
- minPixelValue = std::numeric_limits::min();
- }
- if (maxPixelValue > std::numeric_limits::max()) {
- maxPixelValue = std::numeric_limits::max();
- }
-
- m_Controls.spinBoxOutsidePixelValue->setEnabled(true);
- m_Controls.spinBoxOutsidePixelValue->setMaximum(static_cast(maxPixelValue));
- m_Controls.spinBoxOutsidePixelValue->setMinimum(static_cast(minPixelValue));
- m_Controls.spinBoxOutsidePixelValue->setValue(static_cast(minPixelValue));
- }
- else
- {
- m_Controls.spinBoxOutsidePixelValue->setEnabled(false);
- }
-
- unsigned int dim = image->GetDimension();
- if (dim < 2 || dim > 4)
- {
- m_Controls.labelWarningImage->setStyleSheet(" QLabel { color: rgb(255, 0, 0) }");
- m_Controls.labelWarningImage->setText(QString::fromStdString("Select an image."));
- m_ParentWidget->setEnabled(false);
- }
- if (m_CroppingObjectNode != nullptr)
- {
- m_Controls.buttonCropping->setEnabled(true);
- m_Controls.buttonMasking->setEnabled(true);
- m_Controls.boundingShapeSelector->setEnabled(true);
- m_Controls.labelWarningBB->setVisible(false);
- }
- else
- {
- m_Controls.buttonCropping->setEnabled(false);
- m_Controls.buttonMasking->setEnabled(false);
- m_Controls.boundingShapeSelector->setEnabled(false);
- m_Controls.labelWarningBB->setVisible(true);
- }
- return;
- }
- // iterate all selected objects, adjust warning visibility
- setDefaultGUI();
- m_ParentWidget->setEnabled(true);
- m_Controls.labelWarningRotation->setVisible(false);
- }
- }
-}
-
-void QmitkImageCropper::OnComboBoxSelectionChanged(const mitk::DataNode* node)
-{
- mitk::DataNode* selectedNode = const_cast(node);
- if (selectedNode != nullptr)
- {
- if (!m_ImageNode.IsExpired())
- selectedNode->SetDataInteractor(m_ImageNode.Lock()->GetDataInteractor());
- // m_ImageNode->GetDataInteractor()->SetDataNode(selectedNode);
- m_ImageNode = selectedNode;
- }
-}
-
-void QmitkImageCropper::OnSliderValueChanged(int slidervalue)
-{
- m_CropOutsideValue = slidervalue;
-}
-
-void QmitkImageCropper::DoMasking()
-{
- this->ProcessImage(true);
-}
-
-void QmitkImageCropper::DoCropping()
-{
- this->ProcessImage(false);
-}
-
-void QmitkImageCropper::ProcessImage(bool mask)
-{
- // cropping only possible if valid bounding shape as well as a valid image are loaded
- QList nodes = this->GetDataManagerSelection();
-
- auto renderWindowPart = this->GetRenderWindowPart(mitk::WorkbenchUtil::IRenderWindowPartStrategy::OPEN);
- int timeStep = renderWindowPart->GetTimeNavigationController()->GetTime()->GetPos();
-
- if (nodes.empty()) return;
-
- mitk::DataNode* node = nodes[0];
-
- if (node == nullptr)
- {
- QMessageBox::information(nullptr, "Warning", "Please load and select an image before starting image processing.");
- return;
- }
- if (m_CroppingObject == nullptr)
- {
- QMessageBox::information(nullptr, "Warning", "Please load and select a cropping object before starting image processing.");
- return;
- }
-
- mitk::BaseData* data = node->GetData(); //get data from node
- if (data != nullptr)
- {
- QString imageName;
- if (mask)
- {
- imageName = QString::fromStdString(node->GetName() + "_" + m_CroppingObjectNode->GetName() + "_masked");
- }
- else
- {
- imageName = QString::fromStdString(node->GetName() + "_" + m_CroppingObjectNode->GetName() + "_cropped");
- }
-
- if (m_Controls.checkBoxCropTimeStepOnly->isChecked())
- {
- imageName = imageName + "_T" + QString::number(timeStep);
- }
-
- // image and bounding shape ok, set as input
- auto croppedImageNode = mitk::DataNode::New();
- auto cutter = mitk::BoundingShapeCropper::New();
- cutter->SetGeometry(m_CroppingObject);
-
- // adjustable in advanced settings
- cutter->SetUseWholeInputRegion(mask); //either mask (mask=true) or crop (mask=false)
- cutter->SetOutsideValue(m_CropOutsideValue);
- cutter->SetUseCropTimeStepOnly(m_Controls.checkBoxCropTimeStepOnly->isChecked());
- cutter->SetCurrentTimeStep(timeStep);
-
- // TODO: Add support for MultiLayer (right now only Mulitlabel support)
- mitk::LabelSetImage* labelsetImageInput = dynamic_cast(data);
- if (labelsetImageInput != nullptr)
- {
- cutter->SetInput(labelsetImageInput);
- // do the actual cutting
- try
- {
- cutter->Update();
- }
- catch (const itk::ExceptionObject& e)
- {
- std::string message = std::string("The Cropping filter could not process because of: \n ") + e.GetDescription();
- QMessageBox::warning(nullptr,
- tr("Cropping not possible!"),
- tr(message.c_str()),
- QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton);
- return;
- }
-
- auto labelSetImage = mitk::LabelSetImage::New();
- labelSetImage->InitializeByLabeledImage(cutter->GetOutput());
-
- for (unsigned int i = 0; i < labelsetImageInput->GetNumberOfLayers(); i++)
- {
- labelSetImage->AddLabelSetToLayer(i, labelsetImageInput->GetLabelSet(i));
- }
-
- croppedImageNode->SetData(labelSetImage);
- croppedImageNode->SetProperty("name", mitk::StringProperty::New(imageName.toStdString()));
-
- //add cropping result to the current data storage as child node to the image node
- if (!m_Controls.checkOverwriteImage->isChecked())
- {
- if (!this->GetDataStorage()->Exists(croppedImageNode))
- {
- this->GetDataStorage()->Add(croppedImageNode, m_ImageNode.Lock());
- }
- }
- else // original image will be overwritten by the result image and the bounding box of the result is adjusted
- {
- node->SetData(labelSetImage);
- node->Modified();
- // Adjust coordinate system by doing a reinit on
- auto tempDataStorage = mitk::DataStorage::SetOfObjects::New();
- tempDataStorage->InsertElement(0, node);
-
- // initialize the views to the bounding geometry
- auto bounds = this->GetDataStorage()->ComputeBoundingGeometry3D(tempDataStorage);
- mitk::RenderingManager::GetInstance()->InitializeViews(bounds);
- mitk::RenderingManager::GetInstance()->RequestUpdateAll();
- }
- }
- else
- {
- mitk::Image::Pointer imageInput = dynamic_cast(data);
- if (imageInput != nullptr)
- {
- cutter->SetInput(imageInput);
- // do the actual cutting
- try
- {
- cutter->Update();
- }
- catch (const itk::ExceptionObject& e)
- {
- std::string message = std::string("The Cropping filter could not process because of: \n ") + e.GetDescription();
-
- QMessageBox::warning(nullptr,
- tr("Cropping not possible!"),
- tr(message.c_str()),
- QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton);
- return;
- }
-
- //add cropping result to the current data storage as child node to the image node
- if (!m_Controls.checkOverwriteImage->isChecked())
- {
- croppedImageNode->SetData(cutter->GetOutput());
- croppedImageNode->SetProperty("name", mitk::StringProperty::New(imageName.toStdString()));
- croppedImageNode->SetProperty("color", mitk::ColorProperty::New(1.0, 1.0, 1.0));
- croppedImageNode->SetProperty("layer", mitk::IntProperty::New(99)); // arbitrary, copied from segmentation functionality
- if (!this->GetDataStorage()->Exists(croppedImageNode))
- {
- this->GetDataStorage()->Add(croppedImageNode, m_ImageNode.Lock());
- }
- }
- else // original image will be overwritten by the result image and the bounding box of the result is adjusted
- {
- node->SetData(cutter->GetOutput());
- node->Modified();
- // Adjust coordinate system by doing a reinit on
- auto tempDataStorage = mitk::DataStorage::SetOfObjects::New();
- tempDataStorage->InsertElement(0, node);
-
- // initialize the views to the bounding geometry
- auto bounds = this->GetDataStorage()->ComputeBoundingGeometry3D(tempDataStorage);
- mitk::RenderingManager::GetInstance()->InitializeViews(bounds);
- mitk::RenderingManager::GetInstance()->RequestUpdateAll();
- }
- }
- }
- }
- else
- {
- QMessageBox::information(nullptr, "Warning", "Please load and select an image before starting image processing.");
- }
-}
diff --git a/Plugins/org.mitk.gui.qt.imagecropper/src/internal/QmitkImageCropper.h b/Plugins/org.mitk.gui.qt.imagecropper/src/internal/QmitkImageCropper.h
deleted file mode 100644
index e08159b841..0000000000
--- a/Plugins/org.mitk.gui.qt.imagecropper/src/internal/QmitkImageCropper.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/*============================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center (DKFZ)
-All rights reserved.
-
-Use of this source code is governed by a 3-clause BSD license that can be
-found in the LICENSE file.
-
-============================================================================*/
-
-#ifndef QmitkImageCropper_h
-#define QmitkImageCropper_h
-
-#include
-
-#ifdef WIN32
-#pragma warning( disable : 4250 )
-#endif
-
-#include
-#include "QmitkRegisterClasses.h"
-#include
-
-#include "itkCommand.h"
-#include
-#include
-
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "ui_ImageCropperControls.h"
-
-#include "usServiceRegistration.h"
-
-/*!
-@brief QmitkImageCropperView
-\warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation.
-
-\sa QmitkFunctionality
-\ingroup ${plugin_target}_internal
-*/
-class QmitkImageCropper : public QmitkAbstractView
-{
- // this is needed for all Qt objects that should have a Qt meta-object
- // (everything that derives from QObject and wants to have signal/slots)
-private:
-
- Q_OBJECT
-
-public:
- /*!
- @brief Constructor. Called by SampleApp (or other apps that use functionalities)
- */
- QmitkImageCropper(QObject *parent = nullptr);
-
- ~QmitkImageCropper() override;
-
- static const std::string VIEW_ID;
-
- void CreateQtPartControl(QWidget *parent) override;
-
- void SetFocus() override;
-
- /*!
- @brief Creates the Qt connections needed
- */
-
- QWidget* GetControls();
-
- /// @brief Called when the user clicks the GUI button
- protected slots:
- /*!
- * @brief Creates a new bounding object
- */
- virtual void DoCreateNewBoundingObject();
- /*!
- * @brief Whenever Crop button is pressed, issue a cropping action
- */
- void DoCropping();
- /*!
- * @brief Whenever Mask button is pressed, issue a masking action
- */
- void DoMasking();
- /*!
- * @brief Dis- or enable the advanced setting section
- */
- void OnAdvancedSettingsButtonToggled();
- /*!
- * @brief Updates current selection of the bounding object
- */
- void OnDataSelectionChanged(const mitk::DataNode* node);
- /*!
- * @brief Sets the scalar value for outside pixels in case of masking
- */
- void OnSliderValueChanged(int slidervalue);
-
-protected:
-
- /*!
- @brief called by QmitkFunctionality when DataManager's selection has changed
- */
- void OnSelectionChanged(berry::IWorkbenchPart::Pointer part, const QList& nodes) override;
- /*!
- @brief Sets the selected bounding object as current bounding object and set up interactor
- */
- void OnComboBoxSelectionChanged(const mitk::DataNode* node);
- /*!
- * @brief Initializes a new bounding shape using the selected image geometry.
- */
- mitk::Geometry3D::Pointer InitializeWithImageGeometry(mitk::BaseGeometry::Pointer geometry);
-
- void CreateBoundingShapeInteractor(bool rotationEnabled);
-
-private:
-
- /*!
- * The parent QWidget
- */
- QWidget* m_ParentWidget;
- /*!
- * @brief A pointer to the node of the image to be cropped.
- */
- mitk::WeakPointer m_ImageNode;
- /*!
- * @brief The cuboid used for cropping.
- */
- mitk::GeometryData::Pointer m_CroppingObject;
-
- /*!
- * @brief Tree node of the cuboid used for cropping.
- */
- mitk::DataNode::Pointer m_CroppingObjectNode;
-
- /*!
- * @brief Interactor for moving and scaling the cuboid
- */
- mitk::BoundingShapeInteractor::Pointer m_BoundingShapeInteractor;
-
- void ProcessImage(bool crop);
-
- /*!
- * @brief Resets GUI to default
- */
- void setDefaultGUI();
-
- QString AdaptBoundingObjectName(const QString& name) const;
-
- // cropping parameter
- mitk::ScalarType m_CropOutsideValue;
- bool m_Advanced;
- bool m_Active;
- bool m_ScrollEnabled;
-
- Ui::ImageCropperControls m_Controls;
-};
-
-#endif // QmitkImageCropper_h
diff --git a/Plugins/org.mitk.gui.qt.imagecropper/src/internal/QmitkImageCropperView.cpp b/Plugins/org.mitk.gui.qt.imagecropper/src/internal/QmitkImageCropperView.cpp
new file mode 100644
index 0000000000..22e9fb3954
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.imagecropper/src/internal/QmitkImageCropperView.cpp
@@ -0,0 +1,484 @@
+/*============================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center (DKFZ)
+All rights reserved.
+
+Use of this source code is governed by a 3-clause BSD license that can be
+found in the LICENSE file.
+
+============================================================================*/
+
+#include "QmitkImageCropperView.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include
+
+const std::string QmitkImageCropperView::VIEW_ID = "org.mitk.views.qmitkimagecropper";
+
+QmitkImageCropperView::QmitkImageCropperView(QObject *)
+ : m_ParentWidget(nullptr)
+ , m_BoundingShapeInteractor(nullptr)
+ , m_CropOutsideValue(0)
+{
+ CreateBoundingShapeInteractor(false);
+}
+
+QmitkImageCropperView::~QmitkImageCropperView()
+{
+ //disable interactor
+ if (m_BoundingShapeInteractor != nullptr)
+ {
+ m_BoundingShapeInteractor->SetDataNode(nullptr);
+ m_BoundingShapeInteractor->EnableInteraction(false);
+ }
+}
+
+void QmitkImageCropperView::CreateQtPartControl(QWidget *parent)
+{
+ // create GUI widgets from the Qt Designer's .ui file
+ m_Controls.setupUi(parent);
+
+ m_Controls.imageSelectionWidget->SetDataStorage(GetDataStorage());
+ m_Controls.imageSelectionWidget->SetNodePredicate(mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object")));
+ m_Controls.imageSelectionWidget->SetSelectionIsOptional(true);
+ m_Controls.imageSelectionWidget->SetEmptyInfo(QString("Please select an image node"));
+ m_Controls.imageSelectionWidget->SetPopUpTitel(QString("Select image node"));
+
+ connect(m_Controls.imageSelectionWidget, &QmitkSingleNodeSelectionWidget::CurrentSelectionChanged,
+ this, &QmitkImageCropperView::OnImageSelectionChanged);
+
+ m_Controls.boundingBoxSelectionWidget->SetDataStorage(GetDataStorage());
+ m_Controls.boundingBoxSelectionWidget->SetNodePredicate(mitk::NodePredicateAnd::New(
+ mitk::TNodePredicateDataType::New(),
+ mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object"))));
+ m_Controls.boundingBoxSelectionWidget->SetSelectionIsOptional(true);
+ m_Controls.boundingBoxSelectionWidget->SetEmptyInfo(QString("Please select a bounding box"));
+ m_Controls.boundingBoxSelectionWidget->SetPopUpTitel(QString("Select bounding box node"));
+
+ connect(m_Controls.boundingBoxSelectionWidget, &QmitkSingleNodeSelectionWidget::CurrentSelectionChanged,
+ this, &QmitkImageCropperView::OnBoundingBoxSelectionChanged);
+
+ connect(m_Controls.buttonCreateNewBoundingBox, SIGNAL(clicked()), this, SLOT(OnCreateNewBoundingBox()));
+ connect(m_Controls.buttonCropping, SIGNAL(clicked()), this, SLOT(OnCropping()));
+ connect(m_Controls.buttonMasking, SIGNAL(clicked()), this, SLOT(OnMasking()));
+ auto lambda = [this]()
+ {
+ m_Controls.groupImageSettings->setVisible(!m_Controls.groupImageSettings->isVisible());
+ };
+
+ connect(m_Controls.buttonAdvancedSettings, &ctkExpandButton::clicked, this, lambda);
+
+ connect(m_Controls.spinBoxOutsidePixelValue, SIGNAL(valueChanged(int)), this, SLOT(OnSliderValueChanged(int)));
+
+ SetDefaultGUI();
+
+ m_ParentWidget = parent;
+}
+
+void QmitkImageCropperView::OnImageSelectionChanged(QList)
+{
+ bool rotationEnabled = false;
+ auto imageNode = m_Controls.imageSelectionWidget->GetSelectedNode();
+ if (imageNode.IsNull())
+ {
+ SetDefaultGUI();
+ return;
+ }
+
+ auto image = dynamic_cast(imageNode->GetData());
+ if (nullptr != image)
+ {
+ if (image->GetDimension() < 3)
+ {
+ QMessageBox::warning(nullptr,
+ tr("Invalid image selected"),
+ tr("ImageCropper only works with 3 or more dimensions."),
+ QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton);
+ SetDefaultGUI();
+ return;
+ }
+
+ m_ParentWidget->setEnabled(true);
+ m_Controls.buttonCreateNewBoundingBox->setEnabled(true);
+
+ vtkSmartPointer imageMat = image->GetGeometry()->GetVtkMatrix();
+ // check whether the image geometry is rotated; if so, no pixel aligned cropping or masking can be performed
+ if ((imageMat->GetElement(1, 0) == 0.0) && (imageMat->GetElement(0, 1) == 0.0) &&
+ (imageMat->GetElement(1, 2) == 0.0) && (imageMat->GetElement(2, 1) == 0.0) &&
+ (imageMat->GetElement(2, 0) == 0.0) && (imageMat->GetElement(0, 2) == 0.0))
+ {
+ rotationEnabled = false;
+ m_Controls.labelWarningRotation->setVisible(false);
+ }
+ else
+ {
+ rotationEnabled = true;
+ m_Controls.labelWarningRotation->setStyleSheet(" QLabel { color: rgb(255, 0, 0) }");
+ m_Controls.labelWarningRotation->setVisible(true);
+ }
+
+ this->CreateBoundingShapeInteractor(rotationEnabled);
+
+ if (itk::ImageIOBase::SCALAR == image->GetPixelType().GetPixelType())
+ {
+ // Might be changed with the upcoming new image statistics plugin
+ //(recomputation might be very expensive for large images ;) )
+ auto statistics = image->GetStatistics();
+ auto minPixelValue = statistics->GetScalarValueMin();
+ auto maxPixelValue = statistics->GetScalarValueMax();
+
+ if (minPixelValue < std::numeric_limits::min())
+ {
+ minPixelValue = std::numeric_limits::min();
+ }
+ if (maxPixelValue > std::numeric_limits::max())
+ {
+ maxPixelValue = std::numeric_limits::max();
+ }
+
+ m_Controls.spinBoxOutsidePixelValue->setEnabled(true);
+ m_Controls.spinBoxOutsidePixelValue->setMaximum(static_cast(maxPixelValue));
+ m_Controls.spinBoxOutsidePixelValue->setMinimum(static_cast(minPixelValue));
+ m_Controls.spinBoxOutsidePixelValue->setValue(static_cast(minPixelValue));
+ }
+ else
+ {
+ m_Controls.spinBoxOutsidePixelValue->setEnabled(false);
+ }
+
+ unsigned int dim = image->GetDimension();
+ if (dim < 2 || dim > 4)
+ {
+ m_ParentWidget->setEnabled(false);
+ }
+
+ if (m_Controls.boundingBoxSelectionWidget->GetSelectedNode().IsNotNull())
+ {
+ m_Controls.buttonCropping->setEnabled(true);
+ m_Controls.buttonMasking->setEnabled(true);
+ m_Controls.buttonAdvancedSettings->setEnabled(true);
+ m_Controls.groupImageSettings->setEnabled(true);
+ }
+ }
+}
+
+void QmitkImageCropperView::OnBoundingBoxSelectionChanged(QList)
+{
+ auto boundingBoxNode = m_Controls.boundingBoxSelectionWidget->GetSelectedNode();
+ if (boundingBoxNode.IsNull())
+ {
+ SetDefaultGUI();
+
+ m_BoundingShapeInteractor->EnableInteraction(false);
+ m_BoundingShapeInteractor->SetDataNode(nullptr);
+
+ if (m_Controls.imageSelectionWidget->GetSelectedNode().IsNotNull())
+ {
+ m_Controls.buttonCreateNewBoundingBox->setEnabled(true);
+ }
+
+ return;
+ }
+
+ auto boundingBox = dynamic_cast(boundingBoxNode->GetData());
+ if (nullptr != boundingBox)
+ {
+ // node newly selected
+ boundingBoxNode->SetVisibility(true);
+
+ m_BoundingShapeInteractor->EnableInteraction(true);
+ m_BoundingShapeInteractor->SetDataNode(boundingBoxNode);
+
+ mitk::RenderingManager::GetInstance()->InitializeViews();
+ mitk::RenderingManager::GetInstance()->RequestUpdateAll();
+
+ if (m_Controls.imageSelectionWidget->GetSelectedNode().IsNotNull())
+ {
+ m_Controls.buttonCropping->setEnabled(true);
+ m_Controls.buttonMasking->setEnabled(true);
+ m_Controls.buttonAdvancedSettings->setEnabled(true);
+ m_Controls.groupImageSettings->setEnabled(true);
+ }
+ }
+}
+
+void QmitkImageCropperView::OnCreateNewBoundingBox()
+{
+ auto imageNode = m_Controls.imageSelectionWidget->GetSelectedNode();
+ if (imageNode.IsNull())
+ {
+ return;
+ }
+
+
+ QString name = QString::fromStdString(imageNode->GetName() + " Bounding Shape");
+
+ auto boundingShape = this->GetDataStorage()->GetNode(mitk::NodePredicateFunction::New([&name](const mitk::DataNode *node)
+ {
+ return 0 == node->GetName().compare(name.toStdString());
+ }));
+
+ if (nullptr != boundingShape)
+ {
+ name = this->AdaptBoundingObjectName(name);
+ }
+
+ // get current timestep to support 3d+t images
+ auto renderWindowPart = this->GetRenderWindowPart(mitk::WorkbenchUtil::IRenderWindowPartStrategy::OPEN);
+ int timeStep = renderWindowPart->GetTimeNavigationController()->GetTime()->GetPos();
+ auto imageGeometry = static_cast(imageNode->GetData()->GetGeometry(timeStep));
+
+ auto boundingBox = mitk::GeometryData::New();
+ boundingBox->SetGeometry(static_cast(this->InitializeWithImageGeometry(imageGeometry)));
+ auto boundingBoxNode = mitk::DataNode::New();
+ boundingBoxNode->SetData(boundingBox);
+ boundingBoxNode->SetProperty("name", mitk::StringProperty::New(name.toStdString()));
+ boundingBoxNode->SetProperty("color", mitk::ColorProperty::New(1.0, 1.0, 1.0));
+ boundingBoxNode->SetProperty("opacity", mitk::FloatProperty::New(0.6));
+ boundingBoxNode->SetProperty("layer", mitk::IntProperty::New(99));
+ boundingBoxNode->AddProperty("handle size factor", mitk::DoubleProperty::New(1.0 / 40.0));
+ boundingBoxNode->SetBoolProperty("pickable", true);
+
+ if (!this->GetDataStorage()->Exists(boundingBoxNode))
+ {
+ GetDataStorage()->Add(boundingBoxNode, imageNode);
+ }
+
+ m_Controls.boundingBoxSelectionWidget->SetCurrentSelectedNode(boundingBoxNode);
+}
+
+void QmitkImageCropperView::OnCropping()
+{
+ this->ProcessImage(false);
+}
+
+void QmitkImageCropperView::OnMasking()
+{
+ this->ProcessImage(true);
+}
+
+void QmitkImageCropperView::OnSliderValueChanged(int slidervalue)
+{
+ m_CropOutsideValue = slidervalue;
+}
+
+void QmitkImageCropperView::CreateBoundingShapeInteractor(bool rotationEnabled)
+{
+ if (m_BoundingShapeInteractor.IsNull())
+ {
+ m_BoundingShapeInteractor = mitk::BoundingShapeInteractor::New();
+ m_BoundingShapeInteractor->LoadStateMachine("BoundingShapeInteraction.xml", us::ModuleRegistry::GetModule("MitkBoundingShape"));
+ m_BoundingShapeInteractor->SetEventConfig("BoundingShapeMouseConfig.xml", us::ModuleRegistry::GetModule("MitkBoundingShape"));
+ }
+ m_BoundingShapeInteractor->SetRotationEnabled(rotationEnabled);
+}
+
+mitk::Geometry3D::Pointer QmitkImageCropperView::InitializeWithImageGeometry(mitk::BaseGeometry::Pointer geometry)
+{
+ // convert a BaseGeometry into a Geometry3D (otherwise IO is not working properly)
+ if (geometry == nullptr)
+ mitkThrow() << "Geometry is not valid.";
+
+ auto boundingGeometry = mitk::Geometry3D::New();
+ boundingGeometry->SetBounds(geometry->GetBounds());
+ boundingGeometry->SetImageGeometry(geometry->GetImageGeometry());
+ boundingGeometry->SetOrigin(geometry->GetOrigin());
+ boundingGeometry->SetSpacing(geometry->GetSpacing());
+ boundingGeometry->SetIndexToWorldTransform(geometry->GetIndexToWorldTransform());
+ boundingGeometry->Modified();
+ return boundingGeometry;
+}
+
+void QmitkImageCropperView::ProcessImage(bool mask)
+{
+ auto renderWindowPart = this->GetRenderWindowPart(mitk::WorkbenchUtil::IRenderWindowPartStrategy::OPEN);
+ int timeStep = renderWindowPart->GetTimeNavigationController()->GetTime()->GetPos();
+
+ auto imageNode = m_Controls.imageSelectionWidget->GetSelectedNode();
+ if (imageNode.IsNull())
+ {
+ QMessageBox::information(nullptr, "Warning", "Please load and select an image before starting image processing.");
+ return;
+ }
+
+ auto boundingBoxNode = m_Controls.boundingBoxSelectionWidget->GetSelectedNode();
+ if (boundingBoxNode.IsNull())
+ {
+ QMessageBox::information(nullptr, "Warning", "Please load and select a cropping object before starting image processing.");
+ return;
+ }
+
+ auto image = dynamic_cast(imageNode->GetData());
+ auto boundingBox = dynamic_cast(boundingBoxNode->GetData());
+ if (nullptr != image && nullptr != boundingBox)
+ {
+ QString imageName;
+ if (mask)
+ {
+ imageName = QString::fromStdString(imageNode->GetName() + "_" + boundingBoxNode->GetName() + "_masked");
+ }
+ else
+ {
+ imageName = QString::fromStdString(imageNode->GetName() + "_" + boundingBoxNode->GetName() + "_cropped");
+ }
+
+ if (m_Controls.checkBoxCropTimeStepOnly->isChecked())
+ {
+ imageName = imageName + "_T" + QString::number(timeStep);
+ }
+
+ // image and bounding shape ok, set as input
+ auto croppedImageNode = mitk::DataNode::New();
+ auto cutter = mitk::BoundingShapeCropper::New();
+ cutter->SetGeometry(boundingBox);
+
+ // adjustable in advanced settings
+ cutter->SetUseWholeInputRegion(mask); //either mask (mask=true) or crop (mask=false)
+ cutter->SetOutsideValue(m_CropOutsideValue);
+ cutter->SetUseCropTimeStepOnly(m_Controls.checkBoxCropTimeStepOnly->isChecked());
+ cutter->SetCurrentTimeStep(timeStep);
+
+ // TODO: Add support for MultiLayer (right now only Mulitlabel support)
+ auto labelsetImageInput = dynamic_cast(image);
+ if (nullptr != labelsetImageInput)
+ {
+ cutter->SetInput(labelsetImageInput);
+ // do the actual cutting
+ try
+ {
+ cutter->Update();
+ }
+ catch (const itk::ExceptionObject& e)
+ {
+ std::string message = std::string("The Cropping filter could not process because of: \n ") + e.GetDescription();
+ QMessageBox::warning(nullptr, tr("Cropping not possible!"), tr(message.c_str()),
+ QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton);
+ return;
+ }
+
+ auto labelSetImage = mitk::LabelSetImage::New();
+ labelSetImage->InitializeByLabeledImage(cutter->GetOutput());
+
+ for (unsigned int i = 0; i < labelsetImageInput->GetNumberOfLayers(); i++)
+ {
+ labelSetImage->AddLabelSetToLayer(i, labelsetImageInput->GetLabelSet(i));
+ }
+
+ croppedImageNode->SetData(labelSetImage);
+ croppedImageNode->SetProperty("name", mitk::StringProperty::New(imageName.toStdString()));
+
+ //add cropping result to the current data storage as child node to the image node
+ if (!m_Controls.checkOverwriteImage->isChecked())
+ {
+ if (!this->GetDataStorage()->Exists(croppedImageNode))
+ {
+ this->GetDataStorage()->Add(croppedImageNode, imageNode);
+ }
+ }
+ else // original image will be overwritten by the result image and the bounding box of the result is adjusted
+ {
+ imageNode->SetData(labelSetImage);
+ imageNode->Modified();
+ // Adjust coordinate system by doing a reinit on
+ auto tempDataStorage = mitk::DataStorage::SetOfObjects::New();
+ tempDataStorage->InsertElement(0, imageNode);
+
+ // initialize the views to the bounding geometry
+ auto bounds = this->GetDataStorage()->ComputeBoundingGeometry3D(tempDataStorage);
+ mitk::RenderingManager::GetInstance()->InitializeViews(bounds);
+ mitk::RenderingManager::GetInstance()->RequestUpdateAll();
+ }
+ }
+ else
+ {
+ cutter->SetInput(image);
+ // do the actual cutting
+ try
+ {
+ cutter->Update();
+ }
+ catch (const itk::ExceptionObject& e)
+ {
+ std::string message = std::string("The Cropping filter could not process because of: \n ") + e.GetDescription();
+ QMessageBox::warning(nullptr, tr("Cropping not possible!"), tr(message.c_str()),
+ QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton);
+ return;
+ }
+
+ //add cropping result to the current data storage as child node to the image node
+ if (!m_Controls.checkOverwriteImage->isChecked())
+ {
+ croppedImageNode->SetData(cutter->GetOutput());
+ croppedImageNode->SetProperty("name", mitk::StringProperty::New(imageName.toStdString()));
+ croppedImageNode->SetProperty("color", mitk::ColorProperty::New(1.0, 1.0, 1.0));
+ croppedImageNode->SetProperty("layer", mitk::IntProperty::New(99)); // arbitrary, copied from segmentation functionality
+ if (!this->GetDataStorage()->Exists(croppedImageNode))
+ {
+ this->GetDataStorage()->Add(croppedImageNode, imageNode);
+ }
+ }
+ else // original image will be overwritten by the result image and the bounding box of the result is adjusted
+ {
+ imageNode->SetData(cutter->GetOutput());
+ imageNode->Modified();
+ // Adjust coordinate system by doing a reinit on
+ auto tempDataStorage = mitk::DataStorage::SetOfObjects::New();
+ tempDataStorage->InsertElement(0, imageNode);
+
+ // initialize the views to the bounding geometry
+ auto bounds = this->GetDataStorage()->ComputeBoundingGeometry3D(tempDataStorage);
+ mitk::RenderingManager::GetInstance()->InitializeViews(bounds);
+ mitk::RenderingManager::GetInstance()->RequestUpdateAll();
+ }
+ }
+ }
+ else
+ {
+ QMessageBox::information(nullptr, "Warning", "Please load and select an image before starting image processing.");
+ }
+}
+
+void QmitkImageCropperView::SetDefaultGUI()
+{
+ m_Controls.labelWarningRotation->setVisible(false);
+ m_Controls.buttonCreateNewBoundingBox->setEnabled(false);
+ m_Controls.buttonCropping->setEnabled(false);
+ m_Controls.buttonMasking->setEnabled(false);
+ m_Controls.buttonAdvancedSettings->setEnabled(false);
+ m_Controls.groupImageSettings->setEnabled(false);
+ m_Controls.groupImageSettings->setVisible(false);
+ m_Controls.checkOverwriteImage->setChecked(false);
+ m_Controls.checkBoxCropTimeStepOnly->setChecked(false);
+}
+
+QString QmitkImageCropperView::AdaptBoundingObjectName(const QString& name) const
+{
+ unsigned int counter = 2;
+ QString newName = QString("%1 %2").arg(name).arg(counter);
+
+ while (nullptr != this->GetDataStorage()->GetNode(mitk::NodePredicateFunction::New([&newName](const mitk::DataNode *node)
+ {
+ return 0 == node->GetName().compare(newName.toStdString());
+ })))
+ {
+ newName = QString("%1 %2").arg(name).arg(++counter);
+ }
+
+ return newName;
+}
diff --git a/Plugins/org.mitk.gui.qt.imagecropper/src/internal/QmitkImageCropperView.h b/Plugins/org.mitk.gui.qt.imagecropper/src/internal/QmitkImageCropperView.h
new file mode 100644
index 0000000000..7bd77de7de
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.imagecropper/src/internal/QmitkImageCropperView.h
@@ -0,0 +1,90 @@
+/*============================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center (DKFZ)
+All rights reserved.
+
+Use of this source code is governed by a 3-clause BSD license that can be
+found in the LICENSE file.
+
+============================================================================*/
+
+#ifndef QmitkImageCropperView_h
+#define QmitkImageCropperView_h
+
+#include
+
+#include
+
+#include "ui_QmitkImageCropperViewControls.h"
+
+class QmitkImageCropperView : public QmitkAbstractView
+{
+
+ Q_OBJECT
+
+public:
+
+ static const std::string VIEW_ID;
+
+ QmitkImageCropperView(QObject *parent = nullptr);
+
+ ~QmitkImageCropperView() override;
+
+ void CreateQtPartControl(QWidget *parent) override;
+
+ void SetFocus() override { };
+
+protected Q_SLOTS:
+
+ /*!
+ * @brief Updates current selection of the image to crop
+ */
+ void OnImageSelectionChanged(QList nodes);
+ /*!
+ * @brief Updates current selection of the bounding object
+ */
+ void OnBoundingBoxSelectionChanged(QList nodes);
+ /*!
+ * @brief Creates a new bounding object
+ */
+ void OnCreateNewBoundingBox();
+ /*!
+ * @brief Whenever Crop button is pressed, issue a cropping action
+ */
+ void OnCropping();
+ /*!
+ * @brief Whenever Mask button is pressed, issue a masking action
+ */
+ void OnMasking();
+ /*!
+ * @brief Sets the scalar value for outside pixels in case of masking
+ */
+ void OnSliderValueChanged(int slidervalue);
+
+private:
+
+ void CreateBoundingShapeInteractor(bool rotationEnabled);
+
+ // initializes a new bounding shape using the selected image geometry.
+ mitk::Geometry3D::Pointer InitializeWithImageGeometry(mitk::BaseGeometry::Pointer geometry);
+
+ void ProcessImage(bool crop);
+
+ void SetDefaultGUI();
+
+ QString AdaptBoundingObjectName(const QString& name) const;
+
+ QWidget* m_ParentWidget;
+
+ // interactor for moving and scaling the cuboid
+ mitk::BoundingShapeInteractor::Pointer m_BoundingShapeInteractor;
+
+ // cropping parameter
+ mitk::ScalarType m_CropOutsideValue;
+
+ Ui::QmitkImageCropperViewControls m_Controls;
+};
+
+#endif // QmitkImageCropperView_h
diff --git a/Plugins/org.mitk.gui.qt.imagecropper/src/internal/QmitkImageCropperViewControls.ui b/Plugins/org.mitk.gui.qt.imagecropper/src/internal/QmitkImageCropperViewControls.ui
new file mode 100644
index 0000000000..d7e2d78d35
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.imagecropper/src/internal/QmitkImageCropperViewControls.ui
@@ -0,0 +1,311 @@
+
+
+ QmitkImageCropperViewControls
+
+
+
+ 0
+ 0
+ 300
+ 600
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Data Selection
+
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Image
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 40
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Bounding Box
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 40
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 40
+
+
+
+ New
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 90
+
+
+
+ Processing
+
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Mask
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Crop
+
+
+
+
+
+
+ -
+
+
+ true
+
+
+ Image geometry is rotated, result won't be pixel-aligned. You can reinit your image to get a pixel-aligned result, though.
+
+
+ Qt::PlainText
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 25
+
+
+
+ Advanced settings
+
+
+ false
+
+
+ 100
+
+
+ Qt::ToolButtonTextBesideIcon
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 120
+
+
+
+ Output image settings
+
+
+
-
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Outside pixel value (masking):
+
+
+
+ -
+
+
+ false
+
+
+
+ 0
+ 0
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Overrride original image
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Only crop current timestep
+/ cut off other timesteps
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+
+ QmitkSingleNodeSelectionWidget
+ QWidget
+ QmitkSingleNodeSelectionWidget.h
+
+
+ ctkExpandButton
+ QToolButton
+
+
+
+
+
+
diff --git a/Plugins/org.mitk.gui.qt.imagecropper/src/internal/org_mitk_gui_qt_imagecropper_Activator.cpp b/Plugins/org.mitk.gui.qt.imagecropper/src/internal/mitkPluginActivator.cpp
similarity index 61%
rename from Plugins/org.mitk.gui.qt.imagecropper/src/internal/org_mitk_gui_qt_imagecropper_Activator.cpp
rename to Plugins/org.mitk.gui.qt.imagecropper/src/internal/mitkPluginActivator.cpp
index 962f14838f..0902061f1c 100644
--- a/Plugins/org.mitk.gui.qt.imagecropper/src/internal/org_mitk_gui_qt_imagecropper_Activator.cpp
+++ b/Plugins/org.mitk.gui.qt.imagecropper/src/internal/mitkPluginActivator.cpp
@@ -1,26 +1,26 @@
/*============================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center (DKFZ)
All rights reserved.
Use of this source code is governed by a 3-clause BSD license that can be
found in the LICENSE file.
============================================================================*/
#include
-#include "org_mitk_gui_qt_imagecropper_Activator.h"
-#include "QmitkImageCropper.h"
+#include "mitkPluginActivator.h"
+#include "QmitkImageCropperView.h"
-void mitk::org_mitk_gui_qt_imagecropper_Activator::start(ctkPluginContext* context)
+void mitk::mitkPluginActivator::start(ctkPluginContext* context)
{
RegisterBoundingShapeObjectFactory();
- BERRY_REGISTER_EXTENSION_CLASS(QmitkImageCropper, context)
+ BERRY_REGISTER_EXTENSION_CLASS(QmitkImageCropperView, context)
}
-void mitk::org_mitk_gui_qt_imagecropper_Activator::stop(ctkPluginContext*)
+void mitk::mitkPluginActivator::stop(ctkPluginContext*)
{
}
diff --git a/Plugins/org.mitk.gui.qt.imagecropper/src/internal/org_mitk_gui_qt_imagecropper_Activator.h b/Plugins/org.mitk.gui.qt.imagecropper/src/internal/mitkPluginActivator.h
similarity index 89%
rename from Plugins/org.mitk.gui.qt.imagecropper/src/internal/org_mitk_gui_qt_imagecropper_Activator.h
rename to Plugins/org.mitk.gui.qt.imagecropper/src/internal/mitkPluginActivator.h
index 565f56e693..d2be4791a3 100644
--- a/Plugins/org.mitk.gui.qt.imagecropper/src/internal/org_mitk_gui_qt_imagecropper_Activator.h
+++ b/Plugins/org.mitk.gui.qt.imagecropper/src/internal/mitkPluginActivator.h
@@ -1,32 +1,32 @@
/*============================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center (DKFZ)
All rights reserved.
Use of this source code is governed by a 3-clause BSD license that can be
found in the LICENSE file.
============================================================================*/
#ifndef org_mitk_gui_qt_imagecropper_Activator_h
#define org_mitk_gui_qt_imagecropper_Activator_h
#include
namespace mitk
{
- class org_mitk_gui_qt_imagecropper_Activator : public QObject, public ctkPluginActivator
+ class mitkPluginActivator : public QObject, public ctkPluginActivator
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_imagecropper")
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context) override;
void stop(ctkPluginContext* context) override;
};
}
#endif