diff --git a/Plugins/org.mitk.gui.qt.imagecropper/src/internal/ImageCropperControls.ui b/Plugins/org.mitk.gui.qt.imagecropper/src/internal/ImageCropperControls.ui index 68363c2179..fa309dd488 100644 --- a/Plugins/org.mitk.gui.qt.imagecropper/src/internal/ImageCropperControls.ui +++ b/Plugins/org.mitk.gui.qt.imagecropper/src/internal/ImageCropperControls.ui @@ -1,1304 +1,1157 @@ ImageCropperControls - + 0 0 365 863 0 0 QmitkTemplate 3 0 0 QLabel { color: rgb(255, 0, 0) } - Please select an image! + 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! + Please select a bounding object. false 0 0 0 90 Bounding object 10 20 311 58 0 0 16777215 16777215 0 0 New 0 0 Crop 0 0 Do Cropping Mask 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 - ImageGeometry is rotated, result is not pixel-aligned. Please Reinit! + 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 - - - - false - - - - 0 - 100 - - - - Bounding Shape - - - - - 10 - 20 - 321 - 71 - - - - - - - false - - - - Cuboid - - - - - Cone - - - - - Cylinder - - - - - Ellipsoid - - - - - - - - Reset bounding object - - - - - - - - - - - - 0 - 0 - - - - - 0 - 60 - - - - - 16777215 - 6777215 - - - - Bounding Shape Color - - - - - 20 - 20 - 309 - 31 - - - - - - - 0 - - - 0 - - - - - - - - 0 - 0 - - - - - - - - - - - Deselected - - - - - - - - 0 - 0 - - - - - - - - - - - Selected - - - - - - - - - - - 0 0 0 120 Output image settings 10 30 - 321 + 333 161 10 6 - Outside Pixel Value: + Outside pixel value (masking): false 0 0 16777210 16777215 - Overwrite original image + Overrride original image false - Crop current timestep only (for timeseries) + Only crop current timestep / cut off other timesteps Qt::Vertical 20 40 Qt::Vertical 20 40 QmitkDataStorageComboBox QComboBox
QmitkDataStorageComboBox.h
ctkExpandButton QToolButton
ctkExpandButton.h
diff --git a/Plugins/org.mitk.gui.qt.imagecropper/src/internal/QmitkImageCropper.cpp b/Plugins/org.mitk.gui.qt.imagecropper/src/internal/QmitkImageCropper.cpp index 6cfd19b562..90d835c996 100644 --- a/Plugins/org.mitk.gui.qt.imagecropper/src/internal/QmitkImageCropper.cpp +++ b/Plugins/org.mitk.gui.qt.imagecropper/src/internal/QmitkImageCropper.cpp @@ -1,629 +1,529 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "QmitkImageCropper.h" #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 const std::string QmitkImageCropper::VIEW_ID = "org.mitk.views.qmitkimagecropper"; QmitkImageCropper::QmitkImageCropper(QObject *parent) : m_ParentWidget(0), 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(); - m_Controls.comboBoxBoundingObject->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.buttonDeselectedColor, SIGNAL(clicked()), this, SLOT(OnDeselectedColorChanged())); - connect(m_Controls.buttonSelectedColor, SIGNAL(clicked()), this, SLOT(OnSelectedColorChanged())); connect(m_Controls.spinBox, SIGNAL(valueChanged(int)), this, SLOT(OnSliderValueChanged(int))); m_Controls.spinBox->setValue(-1000); m_Controls.spinBox->setEnabled(false); m_Controls.buttonCreateNewBoundingBox->setEnabled(false); m_Controls.buttonCropping->setEnabled(false); m_Controls.boundingShapeSelector->setEnabled(false); m_Controls.labelWarningRotation->setVisible(false); m_Controls.buttonAdvancedSettings->setEnabled(false); m_Advanced = false; this->OnAdvancedSettingsButtonToggled(); m_ParentWidget = parent; } void QmitkImageCropper::OnDataSelectionChanged(const mitk::DataNode* node) { 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.labelWarningBB->setText(QString::fromStdString("")); m_CroppingObject = dynamic_cast(m_CroppingObjectNode->GetData()); m_Advanced = true; - mitk::ColorProperty::Pointer selcolorProperty = dynamic_cast - (m_CroppingObjectNode->GetProperty("Bounding Shape.Selected Color")); - mitk::ColorProperty::Pointer deselcolorProperty = dynamic_cast - (m_CroppingObjectNode->GetProperty("Bounding Shape.Deselected Color")); - if (selcolorProperty && deselcolorProperty) - { - mitk::Color deselColor = deselcolorProperty->GetColor(); - mitk::Color selColor = selcolorProperty->GetColor(); - - QColor selCurrentColor((int)(selColor.GetRed() * 255), (int)(selColor.GetGreen() * 255), (int)(selColor.GetBlue() * 255)); - m_Controls.buttonSelectedColor->setAutoFillBackground(true); - - auto styleSheet = QString("background-color:rgb(%1,%2,%3)") - .arg(selCurrentColor.red()) - .arg(selCurrentColor.green()) - .arg(selCurrentColor.blue()); - - m_Controls.buttonSelectedColor->setStyleSheet(styleSheet); - - QColor deselCurrentColor((int)(deselColor.GetRed() * 255), (int)(deselColor.GetGreen() * 255), (int)(deselColor.GetBlue() * 255)); - m_Controls.buttonDeselectedColor->setAutoFillBackground(true); - auto styleSheet2 = QString("background-color:rgb(%1,%2,%3)") - .arg(deselCurrentColor.red()) - .arg(deselCurrentColor.green()) - .arg(deselCurrentColor.blue()); - - m_Controls.buttonDeselectedColor->setStyleSheet(styleSheet2); - } mitk::RenderingManager::GetInstance()->InitializeViews(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } else { m_Controls.buttonAdvancedSettings->setEnabled(false); m_CroppingObject = nullptr; m_BoundingShapeInteractor->EnableInteraction(false); m_BoundingShapeInteractor->SetDataNode(nullptr); m_Advanced = false; this->OnAdvancedSettingsButtonToggled(); - QColor defaultColor((int)(255), (int)(255), (int)(255)); - auto styleSheet = QString("background-color:rgb(%1,%2,%3)") - .arg(defaultColor.red()) - .arg(defaultColor.green()) - .arg(defaultColor.blue()); - - m_Controls.buttonSelectedColor->setAutoFillBackground(true); - m_Controls.buttonSelectedColor->setStyleSheet(styleSheet); - m_Controls.buttonDeselectedColor->setAutoFillBackground(true); - m_Controls.buttonDeselectedColor->setStyleSheet(styleSheet); } } void QmitkImageCropper::OnAdvancedSettingsButtonToggled() { - m_Controls.groupBoxShape->setVisible(m_Advanced); - m_Controls.groupBoxColors->setVisible(m_Advanced); 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; } void QmitkImageCropper::DoCreateNewBoundingObject() { if (m_ImageNode.IsNotNull()) { - m_Controls.buttonCropping->setEnabled(true); - m_Controls.buttonMasking->setEnabled(true); - m_Controls.boundingShapeSelector->setEnabled(true); - bool ok = false; QString name = QInputDialog::getText(QApplication::activeWindow() , "Add cropping shape...", "Enter name for the new cropping shape", QLineEdit::Normal, "BoundingShape", &ok); if (!ok || name.isEmpty()) return; + m_Controls.buttonCropping->setEnabled(true); + m_Controls.buttonMasking->setEnabled(true); + m_Controls.boundingShapeSelector->setEnabled(true); + // to do: check whether stdmulti.widget is valid // get current timestep to support 3d+t images //to do: check if stdmultiwidget is valid int timeStep = mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1"))->GetTimeStep(); mitk::BaseGeometry::Pointer imageGeometry = static_cast(m_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, m_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::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/, const QList& nodes) { bool rotationEnabled = false; if (nodes.empty()) { m_Controls.labelWarningImage->setStyleSheet(" QLabel { color: rgb(255, 0, 0) }"); m_Controls.labelWarningImage->setText(QString::fromStdString("Select an image.")); m_Controls.labelWarningBB->setStyleSheet(" QLabel { color: rgb(255, 0, 0) }"); - m_Controls.labelWarningBB->setText(QString::fromStdString("No bounding object available.")); + m_Controls.labelWarningBB->setText(QString::fromStdString("Create a bounding shape below.")); m_Controls.buttonCreateNewBoundingBox->setEnabled(false); m_Controls.buttonCropping->setEnabled(false); m_Controls.buttonMasking->setEnabled(false); - m_Controls.comboBoxBoundingObject->setEnabled(false); m_Controls.labelWarningRotation->setVisible(false); 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.comboBoxBoundingObject->setEnabled(true); m_Controls.labelWarningImage->setStyleSheet(" QLabel { color: rgb(0, 0, 0) }"); m_Controls.labelWarningImage->setText(QString::fromStdString("File name: " + m_ImageNode->GetName())); m_Controls.buttonCreateNewBoundingBox->setEnabled(true); mitk::Image::Pointer image = dynamic_cast(m_ImageNode->GetData()); if (image != nullptr) { 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) { // TODO: ImageStatistics Plugin? Min/Max Value? int minPixelValue = static_cast(image->GetScalarValueMin()); //static_castimage->GetStatistics()->GetScalarValueMinNoRecompute(); int maxPixelValue = static_cast(image->GetScalarValueMax()); //static_castimage->GetStatistics()->GetScalarValueMaxNoRecompute(); m_Controls.spinBox->setEnabled(true); m_Controls.spinBox->setMaximum(maxPixelValue); m_Controls.spinBox->setMinimum(minPixelValue); m_Controls.spinBox->setValue(minPixelValue); } else m_Controls.spinBox->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->setStyleSheet(" QLabel { color: rgb(255, 0, 0) }"); - m_Controls.labelWarningBB->setText(QString::fromStdString("No bounding object available.")); + m_Controls.labelWarningBB->setText(QString::fromStdString("Create a bounding shape below.")); } return; } // iterate all selected objects, adjust warning visibility m_Controls.labelWarningImage->setStyleSheet(" QLabel { color: rgb(255, 0, 0) }"); m_Controls.labelWarningImage->setText(QString::fromStdString("Select an image.")); m_Controls.buttonCropping->setEnabled(false); m_Controls.buttonMasking->setEnabled(false); m_Controls.buttonCreateNewBoundingBox->setEnabled(false); - m_Controls.comboBoxBoundingObject->setEnabled(false); - m_Controls.buttonDeselectedColor->setAutoFillBackground(false); - m_Controls.buttonDeselectedColor->setAutoFillBackground(false); m_Controls.boundingShapeSelector->setEnabled(false); m_ParentWidget->setEnabled(true); m_Controls.labelWarningRotation->setVisible(false); } } } -void QmitkImageCropper::OnSelectedColorChanged() -{ - mitk::ColorProperty::Pointer colorProperty = dynamic_cast(m_CroppingObjectNode->GetProperty("Bounding Shape.Selected Color")); - this->ChangeColor(colorProperty, true); -} - -void QmitkImageCropper::OnDeselectedColorChanged() -{ - mitk::ColorProperty* colorProperty = dynamic_cast(m_CroppingObjectNode->GetProperty("Bounding Shape.Deselected Color")); - this->ChangeColor(colorProperty, false); - -} - -void QmitkImageCropper::ChangeColor(mitk::ColorProperty::Pointer colorProperty, bool selected) -{ - if (m_CroppingObjectNode != nullptr) - { - if (colorProperty) - { - mitk::Color color = colorProperty->GetColor(); - QColor currentColor((int)(color.GetRed() * 255), (int)(color.GetGreen() * 255), (int)(color.GetBlue() * 255)); - QColor result = QColorDialog::getColor(currentColor); - if (result.isValid()) - { - color.SetRed(result.red() / 255.0); - color.SetGreen(result.green() / 255.0); - color.SetBlue(result.blue() / 255.0); - colorProperty->SetColor(color); - - auto styleSheet = QString("background-color:rgb(%1,%2,%3)") - .arg(result.red()) - .arg(result.green()) - .arg(result.blue()); - - if (!selected) - { - m_Controls.buttonDeselectedColor->setAutoFillBackground(true); - m_Controls.buttonDeselectedColor->setStyleSheet(styleSheet); - } - else - { - m_Controls.buttonSelectedColor->setAutoFillBackground(true); - m_Controls.buttonSelectedColor->setStyleSheet(styleSheet); - } - m_BoundingShapeInteractor->SetDataNode(m_CroppingObjectNode); - mitk::RenderingManager::GetInstance()->InitializeViews(); - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); - } - } - } -} - void QmitkImageCropper::OnComboBoxSelectionChanged(const mitk::DataNode* node) { mitk::DataNode* selectedNode = const_cast(node); if (selectedNode != nullptr) { if (m_ImageNode.IsNotNull()) selectedNode->SetDataInteractor(m_ImageNode->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(); // to do: check whether stdmultiwidget is valid int timeStep = mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1"))->GetTimeStep(); 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() + "_masked"); else imageName = QString::fromStdString(node->GetName() + "_cropped"); // 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 (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); } } 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 mitk::TimeGeometry::Pointer 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, 0.0, 0.0)); croppedImageNode->SetProperty("opacity", mitk::FloatProperty::New(0.4)); croppedImageNode->SetProperty("layer", mitk::IntProperty::New(99)); // arbitrary, copied from segmentation functionality if (!this->GetDataStorage()->Exists(croppedImageNode)) { this->GetDataStorage()->Add(croppedImageNode, m_ImageNode); } } 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 mitk::TimeGeometry::Pointer 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 index 127c3fbd0a..72eb0fe5db 100644 --- a/Plugins/org.mitk.gui.qt.imagecropper/src/internal/QmitkImageCropper.h +++ b/Plugins/org.mitk.gui.qt.imagecropper/src/internal/QmitkImageCropper.h @@ -1,179 +1,167 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef QmitkImageCropper_h #define QmitkImageCropper_h #include #ifdef WIN32 #pragma warning( disable : 4250 ) #endif #include #include "QVTKWidget.h" #include "QmitkRegisterClasses.h" #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 = 0); virtual ~QmitkImageCropper(); static const std::string VIEW_ID; virtual void CreateQtPartControl(QWidget *parent); /*! @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 Changes the colors of the bounding object - */ - void OnSelectedColorChanged(); - /*! - * @brief Changes the colors of the bounding object - */ - void OnDeselectedColorChanged(); - /*! * @brief Sets the scalar value for outside pixels in case of masking */ void OnSliderValueChanged(int slidervalue); protected: virtual void SetFocus(); /*! @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 Change color of the selected or deselected bounding shape - */ - void ChangeColor(mitk::ColorProperty::Pointer colorProperty, bool selected); - /*! * @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); // cropping parameter mitk::ScalarType m_CropOutsideValue; bool m_Advanced; bool m_Active; bool m_ScrollEnabled; Ui::ImageCropperControls m_Controls; }; #endif // QmitkImageCropper_h \ No newline at end of file