diff --git a/Modules/PythonService/mitkPythonService.cpp b/Modules/PythonService/mitkPythonService.cpp index 337acec529..e2f31c5199 100644 --- a/Modules/PythonService/mitkPythonService.cpp +++ b/Modules/PythonService/mitkPythonService.cpp @@ -1,626 +1,626 @@ /*============================================================================ 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 "mitkPythonService.h" #include #ifdef _DEBUG #undef _DEBUG - #include + #include #define _DEBUG #else - #include + #include #endif #include "PythonPath.h" #include #include #include #include #include #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION #include #include #ifndef WIN32 #include #endif -#include"swigpyrun.h" +#include "swigpyrun.h" typedef itksys::SystemTools ist; mitk::PythonService::PythonService() : m_ItkWrappingAvailable(true), m_ErrorOccured(false) { // Initialize Python interpreter and ensure global interpreter lock in order to execute python code safely if (!Py_IsInitialized()) { Py_Initialize(); } - PyGILState_STATE gState = PyGILState_Ensure(); + PyGILState_Ensure(); std::string programPath = mitk::IOUtil::GetProgramPath(); std::replace(programPath.begin(), programPath.end(), '\\', '/'); programPath.append("/"); MITK_INFO << programPath; std::string pythonCommand; // execute a string which imports packages that are needed and sets paths to directories pythonCommand.append("import SimpleITK as sitk\n"); pythonCommand.append("import SimpleITK._SimpleITK as _SimpleITK\n"); pythonCommand.append("import numpy\n"); pythonCommand.append("import site, sys\n"); pythonCommand.append("import os\n"); pythonCommand.append("sys.path.append('')\n"); pythonCommand.append("sys.path.append('" + programPath + "')\n"); pythonCommand.append("sys.path.append('" + std::string(SWIG_MITK_WRAPPING) + "')\n"); pythonCommand.append("sys.path.append('" +std::string(EXTERNAL_DIST_PACKAGES) + "')\n"); pythonCommand.append("\nsite.addsitedir('"+std::string(EXTERNAL_SITE_PACKAGES)+"')\n"); // in python 3.8 onwards, the path system variable is not longer used to find dlls // that's why the dlls that are needed for swig wrapping need to be searched manually std::string searchForDll = "if sys.version_info[1] > 7:\n" " for root, dirs, files in os.walk('" + std::string(SWIG_PYTHON_BUILD_OUTPUT) +"'):\n" " for file in files:\n" " if file.endswith('.dll'):\n" " os.add_dll_directory(root)\n" " break\n"; pythonCommand.append(searchForDll); if (PyRun_SimpleString(pythonCommand.c_str()) == -1) { MITK_ERROR << "Something went wrong in setting the path in Python"; } PyObject *main = PyImport_AddModule("__main__"); m_GlobalDictionary = PyModule_GetDict(main); m_LocalDictionary = m_GlobalDictionary; m_ThreadState = PyEval_SaveThread(); } mitk::PythonService::~PythonService() { } void mitk::PythonService::AddRelativeSearchDirs(std::vector< std::string > dirs) { for (auto dir : dirs) { try { std::string path = std::string(MITK_ROOT) + dir; // sys.path.append enables to call scripts which are located in the given path std::string pythonCommand = "import sys\nsys.path.append('" + path + "')\n"; this->Execute(pythonCommand.c_str()); } - catch (const mitk::Exception) + catch (const mitk::Exception&) { mitkThrow() << "An error occured setting the relative project path"; } } } void mitk::PythonService::AddAbsoluteSearchDirs(std::vector< std::string > dirs) { for (auto dir : dirs) { try { // sys.path.append enables to call scripts which are located in the given path std::string pythonCommand = "import sys\nsys.path.append('" + dir + "')\n"; this->Execute(pythonCommand.c_str()); } - catch (const mitk::Exception) + catch (const mitk::Exception&) { mitkThrow() << "An error occured setting the absolute project path"; } } } std::string mitk::PythonService::Execute(const std::string &stdpythonCommand, int commandType) { if (!Py_IsInitialized()) { Py_Initialize(); } std::string result = ""; - PyGILState_STATE gState = PyGILState_Ensure(); + PyGILState_Ensure(); try { // command type is start symbol for python interpreter switch (commandType) { case IPythonService::SINGLE_LINE_COMMAND: commandType = Py_single_input; break; case IPythonService::MULTI_LINE_COMMAND: commandType = Py_file_input; break; case IPythonService::EVAL_COMMAND: commandType = Py_eval_input; break; default: commandType = Py_file_input; } // executes python code given as string // if result is NULL, an error occured PyObject* executionResult = PyRun_String(stdpythonCommand.c_str(), commandType, m_GlobalDictionary, m_LocalDictionary); // notifies registered observers that command has been executed this->NotifyObserver(stdpythonCommand); // if no error occured, the result is represented as string which is returned if (executionResult) { PyObject *objectsRepresentation = PyObject_Repr(executionResult); const char *resultChar = PyUnicode_AsUTF8(objectsRepresentation); result = std::string(resultChar); m_ThreadState = PyEval_SaveThread(); m_ErrorOccured = false; } else { m_ErrorOccured = true; mitkThrow() << "An error occured while running the Python code"; } } - catch (const mitk::Exception) + catch (const mitk::Exception& ) { PyErr_Print(); m_ThreadState = PyEval_SaveThread(); throw; } return result; } void mitk::PythonService::ExecuteScript(const std::string &pythonScript) { // read given file as string std::ifstream t(pythonScript.c_str()); std::string str((std::istreambuf_iterator(t)), std::istreambuf_iterator()); t.close(); // pass the file as string to the Execute() function try { this->Execute(str.c_str(), MULTI_LINE_COMMAND); } - catch (const mitk::Exception) + catch (const mitk::Exception&) { throw; } } std::vector mitk::PythonService::GetVariableStack() { // variables are returned as a list of type mitk::PythonVariable std::vector list; - PyGILState_STATE gState = PyGILState_Ensure(); - try + PyGILState_Ensure(); { // vaiables are taken from the main module // get dictionary where these variables are stored PyObject *dict = PyImport_GetModuleDict(); PyObject *object = PyDict_GetItemString(dict, "__main__"); if (!object) { mitkThrow() << "An error occured getting the Dictionary"; } PyObject *dirMain = PyObject_Dir(object); PyObject *tempObject = nullptr; if (dirMain) { std::string name, attrValue, attrType; //iterate over python list of variables to get desired representation and store in returned variable list for (int i = 0; i < PyList_Size(dirMain); i++) { // get variable at current index tempObject = PyList_GetItem(dirMain, i); if (!tempObject) { mitkThrow() << "An error occured getting an item from the dictionary"; } // get variable name as string PyObject *objectsRepresentation = PyObject_Repr(tempObject); const char *objectChar = PyUnicode_AsUTF8(objectsRepresentation); std::string name = std::string(objectChar); name = name.substr(1, name.size() - 2); // get variable type as string tempObject = PyObject_GetAttrString(object, name.c_str()); if (!tempObject) { mitkThrow() << "Could not get the attribute to determine type"; } attrType = tempObject->ob_type->tp_name; // get variable value as string PyObject *valueStringRepresentation = PyObject_Repr(tempObject); const char *valueChar = PyUnicode_AsUTF8(valueStringRepresentation); std::string attrValue = std::string(valueChar); // build variable type to store mitk::PythonVariable var; var.m_Name = name; var.m_Value = attrValue; var.m_Type = attrType; list.push_back(var); } } m_ThreadState = PyEval_SaveThread(); } - catch (const mitk::Exception) + catch (const mitk::Exception&) { m_ThreadState = PyEval_SaveThread(); throw; } return list; } std::string mitk::PythonService::GetVariable(const std::string& name) { // get all variables from python context std::vector allVars; try { allVars = this->GetVariableStack(); } - catch (const mitk::Exception) + catch (const mitk::Exception&) { mitkThrow() << "Error getting the variable stack"; } // search for variable with given name for (unsigned int i = 0; i < allVars.size(); i++) { if (allVars.at(i).m_Name == name) return allVars.at(i).m_Value; } return ""; } bool mitk::PythonService::DoesVariableExist(const std::string& name) { bool varExists = false; // get all variables from python context std::vector allVars; try { allVars = this->GetVariableStack(); } - catch (const mitk::Exception) + catch (const mitk::Exception&) { mitkThrow() << "Error getting the variable stack"; } // check if variable with given name exists in context for (unsigned int i = 0; i < allVars.size(); i++) { if (allVars.at(i).m_Name == name) { varExists = true; break; } } return varExists; } void mitk::PythonService::AddPythonCommandObserver(mitk::PythonCommandObserver *observer) { //only add observer if it isn't already in list of observers if (!(std::find(m_Observer.begin(), m_Observer.end(), observer) != m_Observer.end())) { m_Observer.push_back(observer); } } void mitk::PythonService::RemovePythonCommandObserver(mitk::PythonCommandObserver *observer) { // iterate over all registered observers and remove the passed observer for (std::vector::iterator iter = m_Observer.begin(); iter != m_Observer.end(); ++iter) { if (*iter == observer) { m_Observer.erase(iter); break; } } } void mitk::PythonService::NotifyObserver(const std::string &command) { // call CommandExecuted() from observer interface in order to inform observers that command has been executed - for (int i = 0; i < m_Observer.size(); ++i) + int observerSize = static_cast m_Observer.size(); + for (int i = 0; i < observerSize; ++i) { m_Observer.at(i)->CommandExecuted(command); } } int mitk::PythonService::GetNumberOfObserver() { return m_Observer.size(); } bool mitk::PythonService::IsSimpleItkPythonWrappingAvailable() { return m_ItkWrappingAvailable; } bool mitk::PythonService::CopyToPythonAsSimpleItkImage(mitk::Image::Pointer image, const std::string &stdvarName) { // this string is a python command which consists of two functions // setup() is called in order to create an image variable on python side. At this point this is a MITK image // convert_to_sitk() converts the MITK image from the previous step into a SimpleITK image. Spacing and Origin need to be set manually // as these informations get lost when converting the image to an numpy array and back (only contains pixel information) std::string transferToPython = "import pyMITK\n" "import SimpleITK as sitk\n" "mitk_image = None\n" "geometry = None\n" +stdvarName+" = None\n" "\n" "def setup(image_from_cxx):\n" " print ('setup called with', image_from_cxx)\n" " global mitk_image\n" " mitk_image = image_from_cxx\n" "\n" "def convert_to_sitk(spacing, origin):\n" " np = pyMITK.GetArrayViewFromImage(mitk_image)\n" " global "+stdvarName+"\n" " "+stdvarName+" = sitk.GetImageFromArray(np)\n" " npSpacingArray = numpy.array(spacing , dtype=float)\n" " "+stdvarName+".SetSpacing(npSpacingArray)\n" " npOriginArray = numpy.array(origin , dtype=float)\n" " " +stdvarName +".SetOrigin(npOriginArray)\n"; // execute code to make the implemented functions available in the Python context (function is not executed, only definition loaded in Python) this->Execute(transferToPython); mitk::Image::Pointer *img = ℑ - PyGILState_STATE gState = PyGILState_Ensure(); + PyGILState_Ensure();//PyGILState_STATE gState = PyGILState_Ensure(); //necessary for transfer array from C++ to Python import_array(); PyObject *main = PyImport_ImportModule("__main__"); if (main == NULL) { mitkThrow() << "Something went wrong getting the main module"; } // create new pyobject from given image using SWIG swig_type_info *pTypeInfo = nullptr; pTypeInfo = SWIG_TypeQuery("_p_itk__SmartPointerT_mitk__Image_t"); int owned = 0; PyObject *pInstance = SWIG_NewPointerObj(reinterpret_cast(img), pTypeInfo, owned); if (pInstance == NULL) { mitkThrow() << "Something went wrong creating the Python instance of the image"; } // get image spacing and convert it to Python array int numberOfImageDimension = image->GetDimension(); auto spacing = image->GetGeometry()->GetSpacing(); auto *spacingptr = &spacing; - int nd = 1; + npy_intp dims[] = {numberOfImageDimension}; PyObject *spacingArray = PyArray_SimpleNewFromData(1, dims, NPY_DOUBLE, (void *)spacingptr); // get image origin and convert it to Python array auto origin = image->GetGeometry()->GetOrigin(); auto *originptr = &origin; PyObject *originArray = PyArray_SimpleNewFromData(1, dims, NPY_DOUBLE, (void *)originptr); // transfer image to python context by calling setup() function which was defined in Python string above PyObject *setup = PyObject_GetAttrString(main, "setup"); PyObject *result = PyObject_CallFunctionObjArgs(setup, pInstance, NULL); if (result == NULL) { mitkThrow() << "Something went wrong setting the MITK image in Python"; } // convert MITK image in Python context to SimpleITK image and tranfer correct origin and spacing calling convert_to_sitk() from above PyObject *convert = PyObject_GetAttrString(main, "convert_to_sitk"); result = PyObject_CallFunctionObjArgs(convert,spacingArray, originArray, NULL); if (result == NULL) { mitkThrow() << "Something went wrong converting the MITK image to a SimpleITK image"; } m_ThreadState = PyEval_SaveThread(); return true; } mitk::Image::Pointer mitk::PythonService::CopySimpleItkImageFromPython(const std::string &stdvarName) { mitk::Image::Pointer mitkImage; // Python code to convert SimpleITK image to MITK image std::string convertToMITKImage = "import SimpleITK as sitk\n" "import pyMITK\n" "numpy_array = sitk.GetArrayViewFromImage("+stdvarName+")\n" "mitk_image = pyMITK.GetImageFromArray(numpy_array)\n" "spacing = "+stdvarName+".GetSpacing()\n" "origin = "+stdvarName +".GetOrigin()\n"; // after executing this, the desired mitk image is available in the Python context with the variable name mitk_image this->Execute(convertToMITKImage); - PyGILState_STATE gState = PyGILState_Ensure(); + PyGILState_Ensure();//PyGILState_STATE gState = PyGILState_Ensure(); // get dictionary with variables from main context PyObject *main = PyImport_AddModule("__main__"); PyObject *globals = PyModule_GetDict(main); // get mitk_image from Python context PyObject *pyImage = PyDict_GetItemString(globals, "mitk_image"); if (pyImage==NULL) { mitkThrow() << "Could not get image from Python"; } // res is status variable to check if result when getting the image from Python context is OK int res = 0; void *voidImage; swig_type_info *pTypeInfo = nullptr; pTypeInfo = SWIG_TypeQuery("_p_itk__SmartPointerT_mitk__Image_t"); // get image from Python context as C++ void pointer res = SWIG_ConvertPtr(pyImage, &voidImage, pTypeInfo, 0); if (!SWIG_IsOK(res)) { mitkThrow() << "Could not cast image to C++ type"; } // cast C++ void pointer to mitk::Image::Pointer mitkImage = *(reinterpret_cast(voidImage)); // as spacing and origin again got lost when transferring between SimpleITK and MITK (see CopyToPythonAsSimpleItkImage()) we need to set them manually // get spacing from Python context PyObject *spacing = PyDict_GetItemString(globals, "spacing"); mitk::Vector3D spacingMITK; // convert Python Array to C++ vector for (int i = 0; i < PyTuple_GET_SIZE(spacing); i++) { PyObject *spacingPy = PyTuple_GetItem(spacing, i); double elem = PyFloat_AsDouble(spacingPy); spacingMITK[i] = elem; } // get origin from Python context PyObject *origin = PyDict_GetItemString(globals, "origin"); mitk::Point3D originMITK; // convert Python Array to Point3D for (int i = 0; i < PyTuple_GET_SIZE(origin); i++) { PyObject *originPy = PyTuple_GetItem(origin, i); double elem = PyFloat_AsDouble(originPy); originMITK[i] = elem; } m_ThreadState = PyEval_SaveThread(); // set origin and spacing correctly mitkImage->GetGeometry()->SetSpacing(spacingMITK); mitkImage->GetGeometry()->SetOrigin(originMITK); return mitkImage; } bool mitk::PythonService::CopyMITKImageToPython(mitk::Image::Pointer &image, const std::string &stdvarName) { // this string is a python command which consists one functions // setup() is called in order to create an image variable on python side. This is the MITK image which is passed std::string transferToPython = "import pyMITK\n" + stdvarName +" = None\n" "\n" "def setup(image_from_cxx):\n" " print ('setup called with', image_from_cxx)\n" " global "+stdvarName+"\n" " "+stdvarName+" = image_from_cxx\n"; // execute code to make the implemented functions available in the Python context (function is not executed, only // definition loaded in Python) this->Execute(transferToPython); mitk::Image::Pointer *img = ℑ // load main context to have access to defined function from above - PyGILState_STATE gState = PyGILState_Ensure(); + PyGILState_Ensure();//PyGILState_STATE gState = PyGILState_Ensure(); PyObject *main = PyImport_ImportModule("__main__"); if (main == NULL) { mitkThrow() << "Something went wrong getting the main module"; } // create new pyobject from given image using SWIG swig_type_info *pTypeInfo = nullptr; pTypeInfo = SWIG_TypeQuery("_p_itk__SmartPointerT_mitk__Image_t"); int owned = 0; PyObject *pInstance = SWIG_NewPointerObj(reinterpret_cast(img), pTypeInfo, owned); if (pInstance == NULL) { mitkThrow() << "Something went wrong creating the Python instance of the image"; } // call setup() function in Python with created PyObject of image PyObject *setup = PyObject_GetAttrString(main, "setup"); PyObject *result = PyObject_CallFunctionObjArgs(setup, pInstance, NULL); if (result == NULL) { mitkThrow() << "Something went wrong setting the MITK image in Python"; } m_ThreadState = PyEval_SaveThread(); return true; } mitk::Image::Pointer GetImageFromPyObject(PyObject *pyImage) { // helper function to get a MITK image from a PyObject mitk::Image::Pointer mitkImage; // res is status variable to check if result when getting the image from Python context is OK int res = 0; void *voidImage; swig_type_info *pTypeInfo = nullptr; pTypeInfo = SWIG_TypeQuery("_p_itk__SmartPointerT_mitk__Image_t"); // get image from Python context as C++ void pointer res = SWIG_ConvertPtr(pyImage, &voidImage, pTypeInfo, 0); if (!SWIG_IsOK(res)) { mitkThrow() << "Could not cast image to C++ type"; } // cast C++ void pointer to mitk::Image::Pointer mitkImage = *(reinterpret_cast(voidImage)); return mitkImage; } mitk::Image::Pointer mitk::PythonService::CopyMITKImageFromPython(const std::string &stdvarName) { mitk::Image::Pointer mitkImage; - PyGILState_STATE gState = PyGILState_Ensure(); + PyGILState_Ensure(); // get image from Python context as PyObject PyObject *main = PyImport_AddModule("__main__"); PyObject *globals = PyModule_GetDict(main); PyObject *pyImage = PyDict_GetItemString(globals, stdvarName.c_str()); if (pyImage==NULL) { mitkThrow() << "Could not get image from Python"; } // convert PyObject to mitk::Image mitkImage = GetImageFromPyObject(pyImage); m_ThreadState = PyEval_SaveThread(); return mitkImage; } std::vector mitk::PythonService::CopyListOfMITKImagesFromPython(const std::string &listVarName) { std::vector mitkImages; - PyGILState_STATE gState = PyGILState_Ensure(); + PyGILState_Ensure();//PyGILState_STATE gState = PyGILState_Ensure(); // get the list of the variable name as python list PyObject *main = PyImport_AddModule("__main__"); PyObject *globals = PyModule_GetDict(main); PyObject *pyImageList = PyDict_GetItemString(globals, listVarName.c_str()); if (pyImageList == NULL) { mitkThrow() << "Could not get image list from Python"; } // iterate over python list of images and convert them to C++ mitk::Image for (int i = 0; i < PyList_GET_SIZE(pyImageList);i++) { PyObject *pyImage = PyList_GetItem(pyImageList, i); mitk::Image::Pointer img = GetImageFromPyObject(pyImage); mitkImages.push_back(img); } m_ThreadState = PyEval_SaveThread(); return mitkImages; } bool mitk::PythonService::PythonErrorOccured() const { return m_ErrorOccured; } diff --git a/Modules/PythonService/mitkPythonService.h b/Modules/PythonService/mitkPythonService.h index 1f878fe79b..6b0bcb17a3 100644 --- a/Modules/PythonService/mitkPythonService.h +++ b/Modules/PythonService/mitkPythonService.h @@ -1,109 +1,109 @@ /*============================================================================ 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 mitkPythonService_h #define mitkPythonService_h #include "mitkIPythonService.h" #include #include "mitkSurface.h" #ifdef _DEBUG #undef _DEBUG - #include + #include #define _DEBUG #else - #include + #include #endif namespace mitk { /// /// implementation of the IPythonService using ctkabstractpythonmanager /// \see IPythonService class PythonService: public itk::LightObject, public mitk::IPythonService { public: /// /// instantiate python manager here PythonService(); /// /// empty implementation... ~PythonService() override; /// /// \see IPythonService::Execute() std::string Execute(const std::string &pythonCommand, int commandType = Py_file_input) override; /// /// \see IPythonService::ExecuteScript() void ExecuteScript(const std::string &pathToPythonScript) override; /// /// \see IPythonService::PythonErrorOccured() bool PythonErrorOccured() const override; /// /// \see IPythonService::GetVariableStack() std::vector GetVariableStack() override; /// /// \see IPythonService::DoesVariableExist() bool DoesVariableExist(const std::string& name) override; /// /// \see IPythonService::GetVariable() std::string GetVariable(const std::string& name) override; /// /// \see IPythonService::AddPythonCommandObserver() void AddPythonCommandObserver( PythonCommandObserver* observer ) override; /// /// \see IPythonService::RemovePythonCommandObserver() void RemovePythonCommandObserver( PythonCommandObserver* observer ) override; /// /// \see IPythonService::NotifyObserver() void NotifyObserver( const std::string& command ) override; /// /// \see IPythonService::GetNumberOfObserver() int GetNumberOfObserver() override; /// /// \see IPythonService::IsItkPythonWrappingAvailable() bool IsSimpleItkPythonWrappingAvailable() override; /// /// \see IPythonService::CopyToPythonAsItkImage() bool CopyToPythonAsSimpleItkImage( mitk::Image::Pointer image, const std::string& varName ) override; /// /// \see IPythonService::CopyItkImageFromPython() mitk::Image::Pointer CopySimpleItkImageFromPython( const std::string& varName ) override; /// /// \see IPythonService::CopyMITKImageToPython() bool CopyMITKImageToPython(mitk::Image::Pointer &image, const std::string &varName) override; /// /// \see IPythonService::CopyMITKImageFromPython() mitk::Image::Pointer CopyMITKImageFromPython(const std::string &varName) override; /// /// \see IPythonService::CopyListOfMITKImagesFromPython() std::vector CopyListOfMITKImagesFromPython(const std::string &listVarName) override; /// /// \see IPythonService::AddRelativeSearchDirs() void AddRelativeSearchDirs(std::vector< std::string > dirs) override; /// /// \see IPythonService::AddAbsoluteSearchDirs() void AddAbsoluteSearchDirs(std::vector< std::string > dirs) override; protected: private: std::vector m_Observer; PyThreadState *m_ThreadState; PyObject *m_GlobalDictionary; PyObject *m_LocalDictionary; bool m_ItkWrappingAvailable; bool m_ErrorOccured; }; } #endif diff --git a/Plugins/org.mitk.deeplearningsegmentation/src/internal/DeepLearningSegmentationGUI.cpp b/Plugins/org.mitk.deeplearningsegmentation/src/internal/DeepLearningSegmentationGUI.cpp index a3f097f99e..f00c719774 100644 --- a/Plugins/org.mitk.deeplearningsegmentation/src/internal/DeepLearningSegmentationGUI.cpp +++ b/Plugins/org.mitk.deeplearningsegmentation/src/internal/DeepLearningSegmentationGUI.cpp @@ -1,123 +1,123 @@ /*============================================================================ 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 "DeepLearningSegmentationGUI.h" #include #include #include"SegmentationResultHandler.h" DeepLearningSegmentationGUI::DeepLearningSegmentationGUI() : m_Ui(new Ui::DeepLearningSegmentationGUI) { //register Meta types which is necessary for the qt signals/slots with those classes as parameter qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType>(); qRegisterMetaType>(); //set up the ui m_Ui->setupUi(this); //connect the UI elements in signals/slots connect(m_Ui->buttonPerformImageProcessing, &QPushButton::clicked, this, &DeepLearningSegmentationGUI::OnDoSegmentation); connect(m_Ui->buttonLoadTrainedNetwork, &QPushButton::clicked, this, &DeepLearningSegmentationGUI::DoLoadTrainedNet); m_Ui->buttonPerformImageProcessing->setEnabled(false); //create a new worker thread to execute some functions in a seperate thread m_SegmentationThread = new QThread; m_Worker = new SegmentationWorker; m_Worker->moveToThread(m_SegmentationThread); // Signal/Slot connects between worker thread and GUI connect(this, &DeepLearningSegmentationGUI::Operate, m_Worker, &SegmentationWorker::DoWork); connect(this, &DeepLearningSegmentationGUI::Wait, m_Worker, &SegmentationWorker::WaitForSegmentationToFinish); connect(m_Worker, &SegmentationWorker::Finished, this, &DeepLearningSegmentationGUI::DoSegmentationProcessFinished); connect(m_Worker, &SegmentationWorker::FinishedMultilabel, this, &DeepLearningSegmentationGUI::DoSegmentationProcessFinished); connect(m_Worker, &SegmentationWorker::Failed, this, &DeepLearningSegmentationGUI::DoSegmentationProcessFinished); connect(m_Worker, &SegmentationWorker::PreviousSegmentationFinished, this, &DeepLearningSegmentationGUI::DoSegmentationProcessFinished); connect(this, SIGNAL(NewToolAssociated(mitk::Tool *)), this, SLOT(OnNewToolAssociated(mitk::Tool *))); connect(this, SIGNAL(NewToolAssociated(mitk::Tool *)), this, SLOT(SetUpUI())); } DeepLearningSegmentationGUI::~DeepLearningSegmentationGUI() { } void DeepLearningSegmentationGUI::SetUpUI() { // Disable buttons if a segmentation is already running if (m_SegTool->IsSegmentationRunning()) { this->SegmentationRunning(); m_SegmentationThread->start(); emit Wait(m_SegTool); } } void DeepLearningSegmentationGUI::DoLoadTrainedNet() { //Open a file dialog to select a trained network - QString tempPath = QString::fromStdString(mitk::IOUtil::GetTempPathA()); + QString tempPath = QString::fromStdString(mitk::IOUtil::GetTempPath()); QString pretrainedNetResourcesPath = QFileDialog::getOpenFileName(nullptr, tr("Open File"), tempPath, tr("Images (*.pth.tar)")); //set the trained network m_TrainedNet = pretrainedNetResourcesPath; //enable segmentation if (m_TrainedNet != "") { m_Ui->labelWarning->setVisible(false); m_Ui->buttonPerformImageProcessing->setEnabled(true); } } void DeepLearningSegmentationGUI::OnDoSegmentation() { MITK_INFO << "[Start] Segmentation"; //adapt gui to show that segmentation is running this->SegmentationRunning(); SegmentationResultHandler *resultSetter = new SegmentationResultHandler; if (!m_SegmentationThread->isRunning()) { m_SegmentationThread->start(); } //start segmentation in worker thread emit Operate(m_SegTool, resultSetter, m_TrainedNet); } void DeepLearningSegmentationGUI::SegmentationRunning() { m_Ui->labelWarning->setText("Segmentation running. This might take a while."); m_Ui->labelWarning->setVisible(true); m_Ui->buttonLoadTrainedNetwork->setEnabled(false); m_Ui->buttonPerformImageProcessing->setEnabled(false); } void DeepLearningSegmentationGUI::DoSegmentationProcessFinished() { m_Ui->buttonLoadTrainedNetwork->setEnabled(true); if (m_TrainedNet == "") { m_Ui->labelWarning->setText("Please load a network!"); m_Ui->labelWarning->setVisible(true); m_Ui->buttonPerformImageProcessing->setEnabled(false); } else { m_Ui->labelWarning->setVisible(false); m_Ui->buttonPerformImageProcessing->setEnabled(true); } } diff --git a/Plugins/org.mitk.deeplearningsegmentation/src/internal/SegmentationResultHandler.cpp b/Plugins/org.mitk.deeplearningsegmentation/src/internal/SegmentationResultHandler.cpp index d235090bbf..349450edfe 100644 --- a/Plugins/org.mitk.deeplearningsegmentation/src/internal/SegmentationResultHandler.cpp +++ b/Plugins/org.mitk.deeplearningsegmentation/src/internal/SegmentationResultHandler.cpp @@ -1,68 +1,68 @@ /*============================================================================ 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"SegmentationResultHandler.h" #include SegmentationResultHandler::SegmentationResultHandler() { } SegmentationResultHandler::~SegmentationResultHandler(){ } void SegmentationResultHandler::SetResult(mitk::LabelSetImage::Pointer resultSegmentation, mitk::DeepLearningSegmentationTool *segTool) { try { //create new data node with the segmentation output as data mitk::DataNode::Pointer outputNode = mitk::DataNode::New(); outputNode->SetName(segTool->GetName()); outputNode->SetData(resultSegmentation); //add data node to data storage and update GUI segTool->GetDataStorage()->Add(outputNode, segTool->GetReferenceData()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } catch (const mitk::Exception &e) { MITK_INFO << e.GetDescription(); } } void SegmentationResultHandler::SetMultilabelResult(std::vector resultSegmentation, mitk::DeepLearningSegmentationTool *segTool) { try - { - for (int i = 0; iresultSegmentation.size(); + for (int i = 0; iGetName()+std::to_string(i); outputNode->SetName(name); outputNode->SetData(resultSegmentation[i]); // add data node to data storage and update GUI segTool->GetDataStorage()->Add(outputNode, segTool->GetReferenceData()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } catch (const mitk::Exception &e) { MITK_INFO << e.GetDescription(); } } void SegmentationResultHandler::SegmentationProcessFailed() { QMessageBox::warning(nullptr, "Error in segmentation", "There was an error in the segmentation process. No resulting segmentation can be loaded."); } diff --git a/Plugins/org.mitk.deeplearningsegmentation/src/internal/org_mitk_deeplearningsegmentation_Activator.cpp b/Plugins/org.mitk.deeplearningsegmentation/src/internal/org_mitk_deeplearningsegmentation_Activator.cpp index c5dcecd06f..e9b45aadf1 100644 --- a/Plugins/org.mitk.deeplearningsegmentation/src/internal/org_mitk_deeplearningsegmentation_Activator.cpp +++ b/Plugins/org.mitk.deeplearningsegmentation/src/internal/org_mitk_deeplearningsegmentation_Activator.cpp @@ -1,23 +1,27 @@ /*============================================================================ 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 "org_mitk_deeplearningsegmentation_Activator.h" namespace mitk { void org_mitk_deeplearningsegmentation_Activator::start(ctkPluginContext *context) - { + { + Q_UNUSED(context) } - void org_mitk_deeplearningsegmentation_Activator::stop(ctkPluginContext *context) { Q_UNUSED(context) } + void org_mitk_deeplearningsegmentation_Activator::stop(ctkPluginContext *context) + { + Q_UNUSED(context) + } } diff --git a/Wrapping/CMakeLists.txt b/Wrapping/CMakeLists.txt index fe199678ec..9bf8ad48e2 100644 --- a/Wrapping/CMakeLists.txt +++ b/Wrapping/CMakeLists.txt @@ -1,20 +1,20 @@ if(MITK_WRAP_PYTHON_ENABLED) include(UseSWIG) include(mitkSwigPrepareFiles) # Path to common files set(MITK_WRAPPING_COMMON_DIR "${MITK_SOURCE_DIR}/Wrapping/Common") # Make a manual list of dependencies for the Swig.i files list(APPEND SWIG_EXTRA_DEPS - "${MITK_WRAPPING_COMMON_DIR}/MITK_Common.i" + "${MITK_WRAPPING_COMMON_DIR}/mitk_swig_common.i" ) # A general packaging target, not built by default, to build packages for each # language. This should depend on all language specific targets. add_custom_target(dist ${CMAKE_COMMAND} -E echo "Finished generating wrapped packages for distribution...") set_property(TARGET dist PROPERTY FOLDER "${MITK_ROOT_FOLDER}/Wrapping") add_subdirectory(Python) endif() diff --git a/Wrapping/Common/mitk_swig_classes.i b/Wrapping/Common/mitk_swig_classes.i index 064f03910c..686e07481b 100644 --- a/Wrapping/Common/mitk_swig_classes.i +++ b/Wrapping/Common/mitk_swig_classes.i @@ -1,214 +1,214 @@ // // Defining some Macros that make problems with SWIG as the // corresponding definitions are not included by default. // Luckely, these includes are not necessary for SWIG. // #define ITK_NOEXCEPT #define ITKCommon_EXPORT #define ITK_OVERRIDE #define MITKCORE_EXPORT #define MITKCLCORE_EXPORT #define MITKCLUTILITIES_EXPORT #define ITKCommon_EXPORT #define MITKMATCHPOINTREGISTRATION_EXPORT #define MAPDeployment_EXPORT #define MAPAlgorithms_EXPORT #define MITKSEGMENTATION_EXPORT #define MITKMULTILABEL_EXPORT #define MITKBASICIMAGEPROCESSING_EXPORT #define VCL_TEMPLATE_EXPORT #define ITKCommon_EXPORT #define ITK_FORWARD_EXPORT #define ITK_OVERRIDE #define ITK_NOEXCEPT %include %include %include %include %include %include %include #define DEPRECATED(func) func #undef ITK_DISALLOW_COPY_AND_ASSIGN #define ITK_DISALLOW_COPY_AND_ASSIGN(TypeName) typedef double ScalarType; typedef Vector3D mitk::Vector3D; %pythoncode %{ convertion_list = {} %} SWIG_ADD_NONOBJECT_CLASS(Indent, itkIndent.h, itk) SWIG_ADD_MITK_CLASS(LightObject, itkLightObject.h, itk) SWIG_ADD_MITK_CLASS(Object, itkObject.h, itk) SWIG_ADD_MITK_CLASS(DataObject, itkDataObject.h, itk) SWIG_ADD_MITK_CLASS(TimeGeometry, mitkTimeGeometry.h, mitk) SWIG_ADD_MITK_CLASS(ArbitraryTimeGeometry, mitkArbitraryTimeGeometry.h, mitk) SWIG_ADD_MITK_CLASS(ProportionalTimeGeometry, mitkProportionalTimeGeometry.h, mitk) SWIG_ADD_MITK_CLASS(BaseGeometry, mitkBaseGeometry.h, mitk) SWIG_ADD_MITK_CLASS(Geometry3D, mitkGeometry3D.h, mitk) SWIG_ADD_MITK_CLASS(SlicedGeometry3D, mitkSlicedGeometry3D.h, mitk) SWIG_ADD_MITK_CLASS(PlaneGeometry , mitkPlaneGeometry.h, mitk) %rename(itk_BoundingBox) itk::BoundingBox; %include %{ -#include < mitkBaseGeometry.h > +#include typedef mitk::BoundingBox BoundingBox; %} %template(VectorBoundingBoxPointer) std::vector< mitk::BoundingBox * >; //SWIG_ADD_NONOBJECT_NOVECTOR_CLASS(BoundingBox, mitkBaseGeometry.h, mitk) SWIG_ADD_NONOBJECT_CLASS(TimeBounds, mitkBaseGeometry.h, mitk) SWIG_ADD_NONOBJECT_CLASS(FixedArrayType, mitkBaseGeometry.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Point2D, mitkPoint.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Point3D, mitkPoint.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Point4D, mitkPoint.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Point2I, mitkPoint.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Point3I, mitkPoint.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Point4I, mitkPoint.h, mitk) SWIG_ADD_NONOBJECT_CLASS(VnlVector, mitkVector.h, mitk) %ignore rBegin() const; %ignore rEnd() const; %ignore rBegin(); %ignore rEnd(); %ignore itk::Vector::GetVnlVector; %ignore itk::Vector::Get_vnl_vector; %ignore itk::Vector::Get_vnl_vector const; %{ #include #include #include typedef vnl_vector_ref VnlVectorRef; %} //%include //MITKSWIG_ADD_CLASS(VnlVectorRef, mitkVector.h,) //typedef ::VnlVectorRef VnlVectorRef; class VnlVectorRef; %template(VectorVnlVectorRefPointer) std::vector<::VnlVectorRef * >; //SWIG_ADD_NONOBJECT_NOVECTOR_CLASS(VnlVectorRef, mitkVector.h, ) %include %include class itk::FixedArray::ReverseIterator; //%template(VnlVectorRef) vnl_vector_ref; %template(itkFixedArray2D) itk::FixedArray; %template(itkFixedArray3D) itk::FixedArray; %template(itkFixedArray3UD) itk::FixedArray; %template(itkFixedArray4D) itk::FixedArray; %template(itkVector2D) itk::Vector; %template(itkVector3D) itk::Vector; %template(itkVector3UD) itk::Vector; %template(itkVector4D) itk::Vector; SWIG_ADD_NONOBJECT_TEMPLATE_CLASS(Vector2D, mitkVector.h, mitk) %template(Vector2D) mitk::Vector; SWIG_ADD_NONOBJECT_TEMPLATE_CLASS(Vector3D, mitkVector.h, mitk) %template(Vector3D) mitk::Vector; SWIG_ADD_NONOBJECT_TEMPLATE_CLASS(Vector4D, mitkVector.h, mitk) %template(Vector4D) mitk::Vector; SWIG_ADD_MITK_CLASS(BaseData, mitkBaseData.h, mitk) SWIG_ADD_MITK_CLASS(SlicedData, mitkSlicedData.h, mitk) SWIG_ADD_MITK_CLASS(Image, mitkImage.h, mitk) SWIG_ADD_MITK_CLASS(LabelSetImage, mitkLabelSetImage.h, mitk) SWIG_ADD_MITK_CLASS(PointSet, mitkPointSet.h, mitk) %{ using mitk::Message; %} // // Phenotyping Related Classes // SWIG_ADD_MITK_CLASS(AbstractGlobalImageFeature, mitkAbstractGlobalImageFeature.h, mitk) SWIG_ADD_MITK_CLASS(GIFImageDescriptionFeatures, mitkGIFImageDescriptionFeatures.h, mitk) SWIG_ADD_MITK_CLASS(GIFFirstOrderStatistics, mitkGIFFirstOrderStatistics.h, mitk) SWIG_ADD_MITK_CLASS(GIFFirstOrderHistogramStatistics, mitkGIFFirstOrderHistogramStatistics.h, mitk) SWIG_ADD_MITK_CLASS(GIFFirstOrderNumericStatistics, mitkGIFFirstOrderNumericStatistics.h, mitk) SWIG_ADD_MITK_CLASS(GIFVolumetricStatistics, mitkGIFVolumetricStatistics.h, mitk) SWIG_ADD_MITK_CLASS(GIFVolumetricDensityStatistics, mitkGIFVolumetricDensityStatistics.h, mitk) SWIG_ADD_MITK_CLASS(GIFCooccurenceMatrix2, mitkGIFCooccurenceMatrix2.h, mitk) SWIG_ADD_MITK_CLASS(GIFNeighbouringGreyLevelDependenceFeature, mitkGIFNeighbouringGreyLevelDependenceFeatures.h, mitk) SWIG_ADD_MITK_CLASS(GIFGreyLevelRunLength, mitkGIFGreyLevelRunLength.h, mitk) SWIG_ADD_MITK_CLASS(GIFGreyLevelSizeZone, mitkGIFGreyLevelSizeZone.h, mitk) SWIG_ADD_MITK_CLASS(GIFGreyLevelDistanceZone, mitkGIFGreyLevelDistanceZone.h, mitk) SWIG_ADD_MITK_CLASS(GIFLocalIntensity, mitkGIFLocalIntensity.h, mitk) SWIG_ADD_MITK_CLASS(GIFIntensityVolumeHistogramFeatures, mitkGIFIntensityVolumeHistogramFeatures.h, mitk) SWIG_ADD_MITK_CLASS(GIFNeighbourhoodGreyToneDifferenceFeatures, mitkGIFNeighbourhoodGreyToneDifferenceFeatures.h, mitk) SWIG_ADD_MITK_CLASS(GIFCurvatureStatistic, mitkGIFCurvatureStatistic.h, mitk) // // Conversion and Segmentation based Classes // SWIG_ADD_MITK_CLASS(ContourModelSetToImageFilter, mitkContourModelSetToImageFilter.h, mitk) SWIG_ADD_NONOBJECT_NOVECTOR_CLASS(BooleanOperation, mitkBooleanOperation.h, mitk) SWIG_ADD_NONOBJECT_NOVECTOR_CLASS(MorphologicalOperations, mitkMorphologicalOperations.h, mitk) //SWIG_ADD_NONOBJECT_NOVECTOR_CLASS(MaskCleaningOperation, mitkMaskCleaningOperation.h, mitk) //SWIG_ADD_NONOBJECT_NOVECTOR_CLASS(TransformationOperation, mitkTransformationOperation.h, mitk) //SWIG_ADD_NONOBJECT_NOVECTOR_CLASS(ArithmeticOperation, mitkArithmeticOperation.h, mitk) %{ #include typedef itk::DataObject::DataObjectIdentifierType DataObjectIdentifierType; typedef itk::ProcessObject::DataObjectPointerArraySizeType DataObjectPointerArraySizeType; %} #ifdef MITK_USE_MatchPoint // // MatchPoint Related Classes // %ignore DLLHandle::LibraryHandleType; %{ #include namespace core { typedef std::string String; } typedef map::deployment::DLLHandle::LibraryHandleType LibraryHandleType; typedef map::deployment::DLLHandle DLLHandle; %} namespace core { typedef std::string String; } %nodefaultctor LibraryHandleType; struct LibraryHandleType {}; %include SWIG_ADD_MITK_CLASS(UID,mapUID.h, map::algorithm) SWIG_ADD_MITK_CLASS(DLLInfo, mapDeploymentDLLInfo.h, map::deployment) //SWIG_ADD_MITK_CLASS_VECTORFREE(DLLHandle, mapDeploymentDLLHandle.h, map::deployment) SWIG_ADD_MITK_CLASS_VECTORFREE(DLLDirectoryBrowser, mapDeploymentDLLDirectoryBrowser.h, ::map::deployment) MITKSWIG_ADD_HEADERFILE(mapDeploymentDLLAccess.h) %{ DLLHandle const * ConvertDLLHandleSmartPointerToPointer(itk::SmartPointer p) { return p.GetPointer(); } %} DLLHandle const * ConvertDLLHandleSmartPointerToPointer(DLLHandle::Pointer p); MITKSWIG_ADD_CLASS(MAPAlgorithmHelper, mitkMAPAlgorithmHelper.h, mitk) MITKSWIG_ADD_CLASS(RegistrationType, mitkImageMappingHelper.h, mitk::ImageMappingHelper) MITKSWIG_ADD_CLASS(MITKRegistrationType, mitkImageMappingHelper.h, mitk::ImageMappingHelper) #endif // SWIG_ADD_MITK_CLASS(FastSymmetricForcesDemonsMultiResDefaultRegistrationAlgorithm, mitkFastSymmetricForcesDemonsMultiResDefaultRegistrationAlgorithm.h, mitk) // SWIG_ADD_MITK_CLASS(LevelSetMotionMultiResDefaultRegistrationAlgorithm, mitkLevelSetMotionMultiResDefaultRegistrationAlgorithm.h, mitk) // SWIG_ADD_MITK_CLASS(MultiModalAffineDefaultRegistrationAlgorithm, mitkMultiModalAffineDefaultRegistrationAlgorithm.h, mitk) // SWIG_ADD_MITK_CLASS(MultiModalRigidDefaultRegistrationAlgorithm, mitkMultiModalRigidDefaultRegistrationAlgorithm.h, mitk) // SWIG_ADD_MITK_CLASS(MultiModalTransDefaultRegistrationAlgorithm, mitkMultiModalTransDefaultRegistrationAlgorithm.h, mitk) // SWIG_ADD_MITK_CLASS(RigidClosedFormPointsDefaultRegistrationAlgorithm, mitkRigidClosedFormPointsDefaultRegistrationAlgorithm.h, mitk) // SWIG_ADD_MITK_CLASS(RigidICPDefaultRegistrationAlgorithm, mitkRigidICPDefaultRegistrationAlgorithm.h, mitk) \ No newline at end of file