diff --git a/Plugins/org.mitk.gui.qt.bonesegmentationrework/src/internal/BoneSegmentationRework.cpp b/Plugins/org.mitk.gui.qt.bonesegmentationrework/src/internal/BoneSegmentationRework.cpp index b91c9e300a..1e991cb46c 100644 --- a/Plugins/org.mitk.gui.qt.bonesegmentationrework/src/internal/BoneSegmentationRework.cpp +++ b/Plugins/org.mitk.gui.qt.bonesegmentationrework/src/internal/BoneSegmentationRework.cpp @@ -1,247 +1,244 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // Blueberry #include #include // Qmitk #include "BoneSegmentationRework.h" // Qt #include #include #include // mitk image #include #include #include "internal/org_mitk_gui_qt_bonesegmentationrework_Activator.h" #include #include #include #include #include #include #include #include "ImageTransferPython.h" const std::string BoneSegmentationRework::VIEW_ID = "org.mitk.views.bonesegmentationrework"; BoneSegmentationRework::~BoneSegmentationRework() { if (m_ProcessBoneSegmentationPython.isRunning()) { m_ProcessBoneSegmentationPython.quit(); } if (Py_IsInitialized()) { if (PyGILState_Check() == 1) { PyGILState_Release(m_GState); } try { //PyErr_Clear(); Py_FinalizeEx(); } catch (...) { MITK_ERROR << "Something went wrong in finalization"; } } } void BoneSegmentationRework::SetFocus() { m_Controls.buttonPerformImageProcessing->setFocus(); } void BoneSegmentationRework::CreateQtPartControl(QWidget *parent) { + qRegisterMetaType(); m_Controls.setupUi(parent); m_Controls.buttonPerformImageProcessing->setText("Start Bone Segmentation"); m_Controls.buttonPerformImageProcessing->setEnabled(false); m_Controls.m_ImageSelector->SetDataStorage(GetDataStorage()); m_Controls.m_ImageSelector->SetPredicate(GetImagePredicate()); m_Controls.labelLoadTrainedNet->setText("Please load a trained network!"); m_Controls.m_CancelButton->setEnabled(false); // Segmentation Thread m_Worker = new BoneSegmentationWorker; m_Worker->moveToThread(&m_ProcessBoneSegmentationPython); connect(&m_ProcessBoneSegmentationPython, &QThread::finished, m_Worker, &QObject::deleteLater); connect(this, &BoneSegmentationRework::Operate, m_Worker, &BoneSegmentationWorker::doWork); connect( m_Worker, &BoneSegmentationWorker::resultReady, this, &BoneSegmentationRework::DoBoneSegmentationProcessFinished); connect(m_Worker, &BoneSegmentationWorker::segmentationProcessCancelled, this, &BoneSegmentationRework::DoBoneSegmentationProcessFailed); // Connects connect( m_Controls.buttonPerformImageProcessing, &QPushButton::clicked, this, &BoneSegmentationRework::DoImageProcessing); connect(m_Controls.m_ButtonLoadTrainedNet, &QPushButton::clicked, this, &BoneSegmentationRework::DoLoadTrainedNet); connect(this->m_Controls.m_ImageSelector, static_cast(&QComboBox::currentIndexChanged), this, &BoneSegmentationRework::OnImageSelectorChanged); connect(m_Controls.m_CancelButton, &QPushButton::clicked, this, &BoneSegmentationRework::OnCancel); } void BoneSegmentationRework::OnImageSelectorChanged() { auto selectedImageNode = m_Controls.m_ImageSelector->GetSelectedNode(); if (selectedImageNode != m_selectedImageNode) { m_selectedImageNode = selectedImageNode; if (m_selectedImageNode.IsNotNull()) { m_Controls.labelWarning->setVisible(false); if (m_TrainedNet != "") { m_Controls.buttonPerformImageProcessing->setEnabled(true); } return; } m_Controls.labelWarning->setText("Please select an image!"); m_Controls.labelWarning->setVisible(true); m_Controls.buttonPerformImageProcessing->setEnabled(false); } } void BoneSegmentationRework::DoLoadTrainedNet() { QString tempPath = QString::fromStdString(mitk::IOUtil::GetTempPathA()); QString pretrainedNetResourcesPath = QFileDialog::getOpenFileName(nullptr, tr("Open File"), tempPath, tr("Images (*.pth.tar)")); if (pretrainedNetResourcesPath != "") { m_TrainedNet = pretrainedNetResourcesPath.toStdString(); } if (m_TrainedNet != "") { m_Controls.labelLoadTrainedNet->setText("Network loaded!"); if (m_selectedImageNode.IsNotNull()) { m_Controls.buttonPerformImageProcessing->setEnabled(true); } } } void BoneSegmentationRework::DoImageProcessing() { m_Controls.m_CancelButton->setEnabled(true); m_Controls.labelWarning->setVisible(true); m_Controls.labelWarning->setText("This might take a while.\nDepending ob your machine up to 20 minutes or more."); m_Controls.buttonPerformImageProcessing->setEnabled(false); m_Controls.m_ButtonLoadTrainedNet->setEnabled(false); m_Controls.m_ImageSelector->setEnabled(false); this->DoStartBoneSegmentationProcess(); } void BoneSegmentationRework::DoStartBoneSegmentationProcess() { MITK_INFO << "[Start] DoStartBoneSegmentationProcess()"; m_ProcessBoneSegmentationPython.start(); emit Operate(QString::fromStdString(m_PythonFileName), QString::fromStdString(m_TrainedNet), dynamic_cast(m_selectedImageNode->GetData())); MITK_INFO << "[END] DoStartBoneSegmentationProcess()"; } -void BoneSegmentationRework::DoLoadOutputImage(mitk::Image *outputImage) +void BoneSegmentationRework::DoLoadOutputImage(mitk::Image::Pointer outputImage) { try { mitk::DataNode::Pointer outputNode = mitk::DataNode::New(); outputNode->SetName("Bone_seg_" + m_selectedImageNode->GetName()); outputNode->SetData(outputImage); GetDataStorage().GetPointer()->Add(outputNode, m_selectedImageNode); } catch (...) { MITK_WARN << "Error loading output file. Maybe it does not exist."; } } void BoneSegmentationRework::ResetUI() { m_Controls.m_CancelButton->setEnabled(false); m_Controls.buttonPerformImageProcessing->setText("Start Bone Segmentation"); m_Controls.buttonPerformImageProcessing->setEnabled(true); m_Controls.m_ButtonLoadTrainedNet->setEnabled(true); m_Controls.labelWarning->setVisible(false); m_Controls.m_ImageSelector->setEnabled(true); } -void BoneSegmentationRework::DoBoneSegmentationProcessFinished(mitk::Image *outputImage) +void BoneSegmentationRework::DoBoneSegmentationProcessFinished(mitk::Image::Pointer outputImage) { mitk::Image::Pointer image = outputImage; - if (image.IsNotNull()) - image->UnRegister(); - MITK_INFO << "Ended calculation thread."; this->DoLoadOutputImage(image); - this->ResetUI(); } void BoneSegmentationRework::DoBoneSegmentationProcessFailed() { MITK_INFO << "Failed during calculation thread."; QMessageBox::warning(nullptr, "Error in segmentation", "There was an error in the segmentation process. No resulting segmentation can be loaded."); this->ResetUI(); } void BoneSegmentationRework::OnCancel() { if (m_ProcessBoneSegmentationPython.isRunning()) { m_ProcessBoneSegmentationPython.terminate(); m_Controls.m_CancelButton->setEnabled(false); m_Controls.buttonPerformImageProcessing->setText("Start Bone Segmentation"); m_Controls.buttonPerformImageProcessing->setEnabled(true); m_Controls.m_ButtonLoadTrainedNet->setEnabled(true); m_Controls.labelWarning->setVisible(false); m_Controls.m_ImageSelector->setEnabled(true); } } mitk::NodePredicateBase::Pointer BoneSegmentationRework::GetImagePredicate() { auto isImage = mitk::NodePredicateDataType::New("Image"); auto hasBinaryProperty = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); auto isNotBinary = mitk::NodePredicateNot::New(hasBinaryProperty); auto isNotBinaryImage = mitk::NodePredicateAnd::New(isImage, isNotBinary); auto hasHelperObjectProperty = mitk::NodePredicateProperty::New("helper object", nullptr); auto isNoHelperObject = mitk::NodePredicateNot::New(hasHelperObjectProperty); auto isNoHelperObjectPredicate = isNoHelperObject.GetPointer(); auto isImageForImageStatistics = mitk::NodePredicateAnd::New(isNotBinaryImage, isNoHelperObjectPredicate); return isImageForImageStatistics.GetPointer(); } diff --git a/Plugins/org.mitk.gui.qt.bonesegmentationrework/src/internal/BoneSegmentationRework.h b/Plugins/org.mitk.gui.qt.bonesegmentationrework/src/internal/BoneSegmentationRework.h index f8964b8b61..ab618f1993 100644 --- a/Plugins/org.mitk.gui.qt.bonesegmentationrework/src/internal/BoneSegmentationRework.h +++ b/Plugins/org.mitk.gui.qt.bonesegmentationrework/src/internal/BoneSegmentationRework.h @@ -1,88 +1,87 @@ /*============================================================================ 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 BoneSegmentationRework_h #define BoneSegmentationRework_h #include #include #include "BoneSegmentationWorker.h" #include "ui_BoneSegmentationReworkControls.h" #include #include #include #include #include #include #include #include #include #include #include - /** \brief BoneSegmentationRework \warning The BoneSegmentationRework plugin provides an automatic bone segmentation for CT images based on deep learning. At this moment, only CT images can be segmented. The segmentation is done on 2D axial slices. The network was trained using data from the multiple myeloma project. It was trained on a very limited amount of training data and needs to be tested in "real world scenarios". \sa QmitkAbstractView \ingroup ${plugin_target}_internal */ class BoneSegmentationRework : 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) Q_OBJECT public: static const std::string VIEW_ID; void ResetUI(); ~BoneSegmentationRework(); signals: - void Operate(QString pythonFileName, QString trainedNet, mitk::Image *inputImage); + void Operate(QString pythonFileName, QString trainedNet, mitk::Image::Pointer inputImage); protected slots: /// \brief Called when the user clicks the GUI button void OnImageSelectorChanged(); void DoImageProcessing(); void DoStartBoneSegmentationProcess(); - void DoBoneSegmentationProcessFinished(mitk::Image* outputImage); + void DoBoneSegmentationProcessFinished(mitk::Image::Pointer outputImage); void DoBoneSegmentationProcessFailed(); void DoLoadTrainedNet(); - void DoLoadOutputImage(mitk::Image* outputImage); + void DoLoadOutputImage(mitk::Image::Pointer outputImage); void OnCancel(); protected: virtual void CreateQtPartControl(QWidget *parent) override; virtual void SetFocus() override; // Predicate helper mitk::NodePredicateBase::Pointer GetImagePredicate(); Ui::BoneSegmentationReworkControls m_Controls; mitk::DataNode::Pointer m_selectedImageNode = nullptr; std::string m_TrainedNet; const std::string m_PythonFileName="segment.py"; QThread m_ProcessBoneSegmentationPython; PyGILState_STATE m_GState; BoneSegmentationWorker* m_Worker; }; #endif // BoneSegmentationRework_h diff --git a/Plugins/org.mitk.gui.qt.bonesegmentationrework/src/internal/BoneSegmentationWorker.cpp b/Plugins/org.mitk.gui.qt.bonesegmentationrework/src/internal/BoneSegmentationWorker.cpp index 9895a89a5c..f8875f1f3a 100644 --- a/Plugins/org.mitk.gui.qt.bonesegmentationrework/src/internal/BoneSegmentationWorker.cpp +++ b/Plugins/org.mitk.gui.qt.bonesegmentationrework/src/internal/BoneSegmentationWorker.cpp @@ -1,86 +1,85 @@ #include "BoneSegmentationWorker.h" #include "ImageTransferPython.h" #include "internal/org_mitk_gui_qt_bonesegmentationrework_Activator.h" #include #include #include #include #include #include #include -void BoneSegmentationWorker::doWork(QString pythonFileName, QString trainedNet, mitk::Image *pInputImage) +void BoneSegmentationWorker::doWork(QString pythonFileName, QString trainedNet, mitk::Image::Pointer inputImage) { - MITK_INFO << pInputImage->GetReferenceCount(); - mitk::Image::Pointer inputImage = pInputImage; - MITK_INFO << pInputImage->GetReferenceCount(); + MITK_INFO << inputImage->GetReferenceCount(); + //mitk::Image::Pointer inputImage = pInputImage; + //MITK_INFO << pInputImage->GetReferenceCount(); std::string fileName = mitk::StandardFileLocations::GetInstance()->FindFile( pythonFileName.toStdString().c_str(), "Plugins/org.mitk.gui.qt.bonesegmentationrework/resources"); std::replace(fileName.begin(), fileName.end(), '\\', '/'); MITK_INFO << "Python file to execute: " << fileName; QString data; QFile file(QString::fromUtf8(fileName.c_str())); if (!file.open(QIODevice::ReadOnly)) { qDebug() << "filenot opened" << endl; } else { qDebug() << "file opened" << endl; data = file.readAll(); } file.close(); std::string dataString = data.toStdString(); if (!Py_IsInitialized()) { Py_Initialize(); } PyGILState_STATE gState = PyGILState_Ensure(); try { std::string pythonEnv = ImageTransferPython::SetUpPythonEnvironment(); if (PyRun_SimpleString(pythonEnv.c_str()) == -1) { mitkThrow() << "An error occured while setting up the Python environment"; } // Set path for the trained network in python std::string networkPath = "seg_load_network_path=\"" + trainedNet.toStdString() + "\""; if (PyRun_SimpleString(networkPath.c_str()) == -1) { mitkThrow() << "An error occured while setting the network path in Python"; } // Copy image for segmentation in Python std::string copyImage = ImageTransferPython::CopyToPythonAsSimpleItkImage(inputImage, "nrrd_image"); if (PyRun_SimpleString(copyImage.c_str()) == -1) { mitkThrow() << "An error occured while copying the input image path to Python"; } // Execute the python script if (PyRun_SimpleString(dataString.c_str()) == -1) { mitkThrow() << "An error occured while running the Python script"; } // Get the result of the segmentation auto outputImage = ImageTransferPython::CopySimpleItkImageFromPython("image_to_write"); PyGILState_Release(gState); - outputImage->Register(); emit resultReady(outputImage); } catch (const mitk::Exception &e) { MITK_ERROR << e.GetDescription(); PyGILState_Release(gState); emit segmentationProcessCancelled(); return; } catch (...) { MITK_ERROR << "other error"; PyGILState_Release(gState); emit segmentationProcessCancelled(); return; } } \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.bonesegmentationrework/src/internal/BoneSegmentationWorker.h b/Plugins/org.mitk.gui.qt.bonesegmentationrework/src/internal/BoneSegmentationWorker.h index 60eb70aa77..1731b604b6 100644 --- a/Plugins/org.mitk.gui.qt.bonesegmentationrework/src/internal/BoneSegmentationWorker.h +++ b/Plugins/org.mitk.gui.qt.bonesegmentationrework/src/internal/BoneSegmentationWorker.h @@ -1,30 +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 BoneSegmentationWorker_h #define BoneSegmentationWorker_h #include #include +Q_DECLARE_METATYPE(mitk::Image::Pointer) + class BoneSegmentationWorker : public QObject { Q_OBJECT public slots: - void doWork(QString pythonFileName, QString trainedNet, mitk::Image* inputImage); + void doWork(QString pythonFileName, QString trainedNet, mitk::Image::Pointer inputImage); signals: - void resultReady(mitk::Image* outputImage); + void resultReady(mitk::Image::Pointer outputImage); void segmentationProcessCancelled(); }; #endif \ No newline at end of file