diff --git a/Modules/Segmentation/Interactions/mitkSegmentAnythingTool.cpp b/Modules/Segmentation/Interactions/mitkSegmentAnythingTool.cpp index 2ef7c6760d..7fc7f8dd1a 100644 --- a/Modules/Segmentation/Interactions/mitkSegmentAnythingTool.cpp +++ b/Modules/Segmentation/Interactions/mitkSegmentAnythingTool.cpp @@ -1,451 +1,431 @@ /*============================================================================ 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 "mitkSegmentAnythingTool.h" #include "mitkProperties.h" #include "mitkToolManager.h" #include "mitkInteractionPositionEvent.h" // us #include #include #include #include #include "mitkIOUtil.h" #include "mitkSegTool2D.h" #include #include #include - +using namespace std::chrono_literals; namespace mitk { MITK_TOOL_MACRO(MITKSEGMENTATION_EXPORT, SegmentAnythingTool, "SegmentAnythingTool"); } mitk::SegmentAnythingTool::SegmentAnythingTool() : SegWithPreviewTool(false, "PressMoveReleaseAndPointSetting") { this->ResetsToEmptyPreviewOn(); this->IsTimePointChangeAwareOff(); } mitk::SegmentAnythingTool::~SegmentAnythingTool() { std::filesystem::remove_all(this->GetMitkTempDir()); } const char **mitk::SegmentAnythingTool::GetXPM() const { return nullptr; } const char *mitk::SegmentAnythingTool::GetName() const { return "SAM"; } us::ModuleResource mitk::SegmentAnythingTool::GetIconResource() const { us::Module *module = us::GetModuleContext()->GetModule(); us::ModuleResource resource = module->GetResource("AI.svg"); return resource; } void mitk::SegmentAnythingTool::Activated() { Superclass::Activated(); m_PointSetPositive = mitk::PointSet::New(); //ensure that the seed points are visible for all timepoints. //dynamic_cast(m_PointSet->GetTimeGeometry())->SetStepDuration(std::numeric_limits::max()); m_PointSetNode = mitk::DataNode::New(); m_PointSetNode->SetData(m_PointSetPositive); m_PointSetNode->SetName(std::string(this->GetName()) + "_PointSetPositive"); m_PointSetNode->SetBoolProperty("helper object", true); m_PointSetNode->SetColor(0.0, 1.0, 0.0); m_PointSetNode->SetVisibility(true); this->GetDataStorage()->Add(m_PointSetNode, this->GetToolManager()->GetWorkingData(0)); m_PointSetNegative = mitk::PointSet::New(); m_PointSetNodeNegative = mitk::DataNode::New(); m_PointSetNodeNegative->SetData(m_PointSetNegative); m_PointSetNodeNegative->SetName(std::string(this->GetName()) + "_PointSetNegative"); m_PointSetNodeNegative->SetBoolProperty("helper object", true); m_PointSetNodeNegative->SetColor(1.0, 0.0, 0.0); m_PointSetNodeNegative->SetVisibility(true); this->GetDataStorage()->Add(m_PointSetNodeNegative, this->GetToolManager()->GetWorkingData(0)); this->SetLabelTransferScope(LabelTransferScope::AllLabels); this->SetLabelTransferMode(LabelTransferMode::AddLabel); } void mitk::SegmentAnythingTool::Deactivated() { this->ClearSeeds(); // remove from data storage and disable interaction GetDataStorage()->Remove(m_PointSetNode); GetDataStorage()->Remove(m_PointSetNodeNegative); m_PointSetNode = nullptr; m_PointSetNodeNegative = nullptr; m_PointSetPositive = nullptr; m_PointSetNegative = nullptr; Superclass::Deactivated(); } void mitk::SegmentAnythingTool::ConnectActionsAndFunctions() { CONNECT_FUNCTION("ShiftSecondaryButtonPressed", OnAddNegativePoint); CONNECT_FUNCTION("ShiftPrimaryButtonPressed", OnAddPoint); CONNECT_FUNCTION("DeletePoint", OnDelete); } void mitk::SegmentAnythingTool::OnAddNegativePoint(StateMachineAction *, InteractionEvent *interactionEvent) { if (!this->GetIsReady() || m_PointSetPositive->GetSize() == 0) { return; } if (!this->IsUpdating() && m_PointSetNegative.IsNotNull()) { const auto positionEvent = dynamic_cast(interactionEvent); if (positionEvent != nullptr) { m_PointSetNegative->InsertPoint(m_PointSetCount, positionEvent->GetPositionInWorld()); m_PointSetCount++; this->UpdatePreview(); } } } void mitk::SegmentAnythingTool::OnAddPoint(StateMachineAction*, InteractionEvent* interactionEvent) { if (!this->GetIsReady()) { return; } m_IsGenerateEmbeddings = false; if ((nullptr == this->GetWorkingPlaneGeometry()) || !mitk::Equal(*(interactionEvent->GetSender()->GetCurrentWorldPlaneGeometry()), *(this->GetWorkingPlaneGeometry()))) { m_IsGenerateEmbeddings = true; this->ClearSeeds(); this->SetWorkingPlaneGeometry(interactionEvent->GetSender()->GetCurrentWorldPlaneGeometry()->Clone()); } if (!this->IsUpdating() && m_PointSetPositive.IsNotNull()) { const auto positionEvent = dynamic_cast(interactionEvent); if (positionEvent != nullptr) { m_PointSetPositive->InsertPoint(m_PointSetCount, positionEvent->GetPositionInWorld()); m_PointSetCount++; this->UpdatePreview(); } } } void mitk::SegmentAnythingTool::OnDelete(StateMachineAction*, InteractionEvent* /*interactionEvent*/) { if (!this->IsUpdating() && m_PointSetPositive.IsNotNull()) { PointSet::Pointer removeSet = m_PointSetPositive; decltype(m_PointSetPositive->GetMaxId().Index()) maxId = 0; if (m_PointSetPositive->GetSize() > 0) { maxId = m_PointSetPositive->GetMaxId().Index(); } if (m_PointSetNegative->GetSize() > 0 && (maxId < m_PointSetNegative->GetMaxId().Index())) { removeSet = m_PointSetNegative; } removeSet->RemovePointAtEnd(0); --m_PointSetCount; this->UpdatePreview(); } } void mitk::SegmentAnythingTool::ClearPicks() { this->ClearSeeds(); this->UpdatePreview(); } bool mitk::SegmentAnythingTool::HasPicks() const { return this->m_PointSetPositive.IsNotNull() && this->m_PointSetPositive->GetSize()>0; } void mitk::SegmentAnythingTool::ClearSeeds() { if (this->m_PointSetPositive.IsNotNull()) { m_PointSetCount -= m_PointSetPositive->GetSize(); this->m_PointSetPositive = mitk::PointSet::New(); // renew pointset //ensure that the seed points are visible for all timepoints. dynamic_cast(m_PointSetPositive->GetTimeGeometry())->SetStepDuration(std::numeric_limits::max()); this->m_PointSetNode->SetData(this->m_PointSetPositive); } if (this->m_PointSetNegative.IsNotNull()) { m_PointSetCount -= m_PointSetNegative->GetSize(); this->m_PointSetNegative = mitk::PointSet::New(); // renew pointset // ensure that the seed points are visible for all timepoints. dynamic_cast(m_PointSetNegative->GetTimeGeometry())->SetStepDuration(std::numeric_limits::max()); this->m_PointSetNodeNegative->SetData(this->m_PointSetNegative); } } void mitk::SegmentAnythingTool::onPythonProcessEvent(itk::Object * /*pCaller*/, const itk::EventObject &e, void *) { std::string testCOUT; std::string testCERR; const auto *pEvent = dynamic_cast(&e); if (pEvent) { testCOUT = testCOUT + pEvent->GetOutput(); MITK_INFO << testCOUT; } const auto *pErrEvent = dynamic_cast(&e); if (pErrEvent) { testCERR = testCERR + pErrEvent->GetOutput(); MITK_ERROR << testCERR; } } void mitk::SegmentAnythingTool::DoUpdatePreview(const Image* inputAtTimeStep, const Image* oldSegAtTimeStep, LabelSetImage* previewImage, TimeStepType timeStep) { if (nullptr != oldSegAtTimeStep && nullptr != previewImage && m_PointSetPositive.IsNotNull()) { if (this->m_MitkTempDir.empty()) { + //this->SetPythonPath("C:\\DKFZ\\SAM_work\\sam_env\\Scripts"); + this->SetPythonPath("C:\\DKFZ\\SAM_work\\sam-embed"); + this->SetModelType("vit_b"); + this->SetCheckpointPath("C:\\DKFZ\\SAM_work\\sam_vit_b_01ec64.pth"); + this->SetMitkTempDir(IOUtil::CreateTemporaryDirectory("mitk-XXXXXX")); m_InDir = IOUtil::CreateTemporaryDirectory("sam-in-XXXXXX", this->GetMitkTempDir()); - std::ofstream tmpStream; - inputImagePath = IOUtil::CreateTemporaryFile(tmpStream, TEMPLATE_FILENAME, m_InDir + IOUtil::GetDirectorySeparator()); - tmpStream.close(); - std::size_t found = inputImagePath.find_last_of(IOUtil::GetDirectorySeparator()); - std::string fileName = inputImagePath.substr(found + 1); - token = fileName.substr(0, fileName.find("_")); m_OutDir = IOUtil::CreateTemporaryDirectory("sam-out-XXXXXX", this->GetMitkTempDir()); + m_Future = std::async(std::launch::async, &mitk::SegmentAnythingTool::start_python_daemon, this); } if (this->HasPicks()) { - ProcessExecutor::Pointer spExec = ProcessExecutor::New(); - itk::CStyleCommand::Pointer spCommand = itk::CStyleCommand::New(); - spCommand->SetCallback(&onPythonProcessEvent); - spExec->AddObserver(ExternalProcessOutputEvent(), spCommand); - - pickleFilePath = m_OutDir + IOUtil::GetDirectorySeparator() + "dump.pkl"; - outputImagePath = m_OutDir + IOUtil::GetDirectorySeparator() + token + "_000.nii.gz"; - - this->SetPythonPath("C:\\DKFZ\\SAM_work\\sam_env\\Scripts"); - this->SetModelType("vit_b"); - this->SetCheckpointPath("C:\\DKFZ\\SAM_work\\sam_vit_b_01ec64.pth"); + std::string uniquePlaneID = GetHashForCurrentPlane(); + std::string inputImagePath = m_InDir + IOUtil::GetDirectorySeparator() + uniquePlaneID + ".nii.gz"; + std::size_t found = inputImagePath.find_last_of(IOUtil::GetDirectorySeparator()); + std::string fileName = inputImagePath.substr(found + 1); + token = fileName.substr(0, fileName.find("_")); - if (m_IsGenerateEmbeddings) - {auto startWrite = std::chrono::system_clock::now(); - IOUtil::Save(inputAtTimeStep, inputImagePath); - auto endWrite = std::chrono::system_clock::now(); - MITK_INFO << "UnLoaded image from MITK. Elapsed: " - << std::chrono::duration_cast(endWrite - startWrite).count(); - this->run_generate_embeddings( - spExec, inputImagePath, m_OutDir, this->GetModelType(), this->GetCheckpointPath(), this->GetGpuId()); - } - auto pointsVec = GetPointsAsCSVString(inputAtTimeStep->GetGeometry()); - std::string pointsCSV; - std::string labelsCSV; - pointsCSV.reserve((m_PointSetPositive->GetSize() + m_PointSetNegative->GetSize()) * 6); - labelsCSV.reserve((m_PointSetPositive->GetSize() + m_PointSetNegative->GetSize()) * 2); - for (const std::pair& pointPair : pointsVec) + outputImagePath = m_OutDir + IOUtil::GetDirectorySeparator() + uniquePlaneID + ".nii.gz"; + IOUtil::Save(inputAtTimeStep, inputImagePath); + auto csvStream = this->GetPointsAsCSVString(inputAtTimeStep->GetGeometry()); + std::string triggerFilePath = m_InDir + IOUtil::GetDirectorySeparator() + m_TRIGGER_FILENAME; + std::ofstream csvfile; + csvfile.open(triggerFilePath, std::ofstream::out | std::ofstream::trunc); + csvfile << csvStream.rdbuf(); + csvfile.close(); + + auto status = m_Future.wait_for(0ms); // check if python daemon has stopped for some reason + if (status == std::future_status::ready) { - auto& p2D = pointPair.first; - pointsCSV.append(std::to_string(static_cast(p2D[0]))); - pointsCSV.append(","); - pointsCSV.append(std::to_string(static_cast(p2D[1]))); - pointsCSV.append(";"); - - auto &label = pointPair.second; - labelsCSV.append(label); - labelsCSV.append(","); + MITK_INFO << "Thread finished... restarting.."; + m_Future = std::async(std::launch::async, &mitk::SegmentAnythingTool::start_python_daemon, this); } - pointsCSV.pop_back(); labelsCSV.pop_back(); - MITK_INFO << " pointsCSV " << pointsCSV; - MITK_INFO << " labelsCSV " << labelsCSV; - auto start = std::chrono::system_clock::now(); - run_segmentation_from_points( - spExec, pickleFilePath, outputImagePath, this->GetModelType(), this->GetCheckpointPath(), pointsCSV, labelsCSV, this->GetGpuId()); - auto endPython = std::chrono::system_clock::now(); - MITK_INFO << "Back in MITK. Elapsed: " - << std::chrono::duration_cast(endPython - start).count(); //outputImagePath = "C:\\DKFZ\\SAM_work\\test_seg_3d.nii.gz"; + while (!std::filesystem::exists(outputImagePath)); Image::Pointer outputImage = IOUtil::Load(outputImagePath); - auto endloading = std::chrono::system_clock::now(); - MITK_INFO << "Loaded image in MITK. Elapsed: " - << std::chrono::duration_cast(endloading- endPython).count(); + //auto endloading = std::chrono::system_clock::now(); + //MITK_INFO << "Loaded image in MITK. Elapsed: " + // << std::chrono::duration_cast(endloading- endPython).count(); //mitk::SegTool2D::WriteSliceToVolume(previewImage, this->GetWorkingPlaneGeometry(), outputImage, timeStep, true); previewImage->InitializeByLabeledImage(outputImage); previewImage->SetGeometry(this->GetWorkingPlaneGeometry()->Clone()); + std::filesystem::remove(outputImagePath); } else { previewImage->SetGeometry(this->GetWorkingPlaneGeometry()->Clone()); this->ResetPreviewContentAtTimeStep(timeStep); } } } -void mitk::SegmentAnythingTool::run_generate_embeddings(ProcessExecutor* spExec, - const std::string& inputImagePath, - const std::string& outputPicklePath, - const std::string& modelType, - const std::string& checkpointPath, - const unsigned int gpuId) +std::string mitk::SegmentAnythingTool::GetHashForCurrentPlane() { - - ProcessExecutor::ArgumentListType args; - std::string command = "python"; - - args.push_back("C:\\DKFZ\\SAM_work\\sam-playground\\endpoints\\generate_embedding.py"); - - args.push_back("--input"); - args.push_back(inputImagePath); - - args.push_back("--output"); - args.push_back(outputPicklePath); - - args.push_back("--model-type"); - args.push_back(modelType); - - args.push_back("--checkpoint"); - args.push_back(checkpointPath); - - try - { - std::string cudaEnv = "CUDA_VISIBLE_DEVICES=" + std::to_string(gpuId); - itksys::SystemTools::PutEnv(cudaEnv.c_str()); - - std::stringstream logStream; - for (const auto &arg : args) - logStream << arg << " "; - logStream << this->GetPythonPath(); - MITK_INFO << logStream.str(); - - spExec->Execute(this->GetPythonPath(), command, args); - } - catch (const mitk::Exception &e) + mitk::Vector3D normal = this->GetWorkingPlaneGeometry()->GetNormal(); + std::stringstream hashstream; + hashstream << normal[0] << normal[1] << normal[2]; + mitk::Point3D point = m_PointSetPositive->GetPoint(0); + for (int i = 0; i < 3; ++i) { - MITK_ERROR << e.GetDescription(); - return; + if (normal[i]!=0) + { + hashstream << point[i]; + } } + size_t hashVal = std::hash{}(hashstream.str()); + return std::to_string(hashVal); } -void mitk::SegmentAnythingTool::run_segmentation_from_points(ProcessExecutor *spExec, - const std::string &pickleFilePath, - const std::string &outputImagePath, - const std::string &modelType, - const std::string &checkpointPath, - const std::string &points, - const std::string &labels, - const unsigned int gpuId) +void mitk::SegmentAnythingTool::start_python_daemon() { ProcessExecutor::ArgumentListType args; std::string command = "python"; + args.push_back("-u"); + + args.push_back("C:\\DKFZ\\SAM_work\\sam-playground\\endpoints\\run_inference_daemon.py"); + - args.push_back("C:\\DKFZ\\SAM_work\\sam-playground\\endpoints\\generate_masks.py"); + args.push_back("--input-folder"); + args.push_back(m_InDir); - args.push_back("--embedding"); - args.push_back(pickleFilePath); + args.push_back("--output-folder"); + args.push_back(m_OutDir); - args.push_back("--output"); - args.push_back(outputImagePath); + args.push_back("--trigger-file"); + args.push_back(m_TRIGGER_FILENAME); args.push_back("--model-type"); - args.push_back(modelType); + args.push_back(this->GetModelType()); args.push_back("--checkpoint"); - args.push_back(checkpointPath); - - args.push_back("--input-points"); - args.push_back(points); + args.push_back(this->GetCheckpointPath()); - args.push_back("--input-labels"); - args.push_back(labels); + ProcessExecutor::Pointer spExec = ProcessExecutor::New(); + itk::CStyleCommand::Pointer spCommand = itk::CStyleCommand::New(); + spCommand->SetCallback(&onPythonProcessEvent); + spExec->AddObserver(ExternalProcessOutputEvent(), spCommand); try { - std::string cudaEnv = "CUDA_VISIBLE_DEVICES=" + std::to_string(gpuId); + std::string cudaEnv = "CUDA_VISIBLE_DEVICES=" + std::to_string(this->GetGpuId()); itksys::SystemTools::PutEnv(cudaEnv.c_str()); std::stringstream logStream; for (const auto &arg : args) logStream << arg << " "; logStream << this->GetPythonPath(); MITK_INFO << logStream.str(); spExec->Execute(this->GetPythonPath(), command, args); } catch (const mitk::Exception &e) { MITK_ERROR << e.GetDescription(); return; } + MITK_INFO << "ending python process....."; } bool mitk::SegmentAnythingTool::run_download_model(std::string targetDir) { MITK_INFO << "model will be downloading to " << targetDir; return true; } -std::vector> mitk::SegmentAnythingTool::GetPointsAsCSVString(const mitk::BaseGeometry *baseGeometry) +std::stringstream mitk::SegmentAnythingTool::GetPointsAsCSVString(const mitk::BaseGeometry* baseGeometry) { MITK_INFO << "No.of points: " << m_PointSetPositive->GetSize(); + std::stringstream pointsAndLabels; + pointsAndLabels << "Point,Label\n"; + mitk::PointSet::PointsIterator pointSetItPos = m_PointSetPositive->Begin(); + mitk::PointSet::PointsIterator pointSetItNeg = m_PointSetNegative->Begin(); + const char SPACE = ' '; + const char newLine = ' '; + while (pointSetItPos != m_PointSetPositive->End() || pointSetItNeg != m_PointSetNegative->End()) + { + if (pointSetItPos != m_PointSetPositive->End()) + { + mitk::Point3D point = pointSetItPos.Value(); + if (baseGeometry->IsInside(point)) + { + Point2D p2D = Get2DIndicesfrom3DWorld(baseGeometry, point); + pointsAndLabels << (int)p2D[0] << SPACE << (int)p2D[1] << ",1" << std::endl; + } + ++pointSetItPos; + } + if (pointSetItNeg != m_PointSetNegative->End()) + { + mitk::Point3D point = pointSetItNeg.Value(); + if (baseGeometry->IsInside(point)) + { + Point2D p2D = Get2DIndicesfrom3DWorld(baseGeometry, point); + pointsAndLabels << (int)p2D[0] << SPACE << (int)p2D[1] << ",0" << std::endl; + } + ++pointSetItNeg; + } + } + return pointsAndLabels; +} + +std::vector> mitk::SegmentAnythingTool::GetPointsAsVector(const mitk::BaseGeometry *baseGeometry) +{ std::vector> clickVec; clickVec.reserve(m_PointSetPositive->GetSize()+m_PointSetNegative->GetSize()); mitk::PointSet::PointsIterator pointSetItPos = m_PointSetPositive->Begin(); mitk::PointSet::PointsIterator pointSetItNeg = m_PointSetNegative->Begin(); while (pointSetItPos != m_PointSetPositive->End() || pointSetItNeg != m_PointSetNegative->End()) { if (pointSetItPos != m_PointSetPositive->End()) { mitk::Point3D point = pointSetItPos.Value(); if (baseGeometry->IsInside(point)) { Point2D p2D = Get2DIndicesfrom3DWorld(baseGeometry, point); clickVec.push_back(std::pair(p2D, "1")); } ++pointSetItPos; } if (pointSetItNeg != m_PointSetNegative->End()) { mitk::Point3D point = pointSetItNeg.Value(); if (baseGeometry->IsInside(point)) { Point2D p2D = Get2DIndicesfrom3DWorld(baseGeometry, point); clickVec.push_back(std::pair(p2D, "0")); } ++pointSetItNeg; } } return clickVec; } mitk::Point2D mitk::SegmentAnythingTool::Get2DIndicesfrom3DWorld(const mitk::BaseGeometry* baseGeometry, mitk::Point3D& point3d) { baseGeometry->WorldToIndex(point3d, point3d); MITK_INFO << point3d[0] << " " << point3d[1] << " " << point3d[2]; // remove Point2D point2D; point2D.SetElement(0, point3d[0]); point2D.SetElement(1, point3d[1]); return point2D; } diff --git a/Modules/Segmentation/Interactions/mitkSegmentAnythingTool.h b/Modules/Segmentation/Interactions/mitkSegmentAnythingTool.h index 0a2e63db18..de95968664 100644 --- a/Modules/Segmentation/Interactions/mitkSegmentAnythingTool.h +++ b/Modules/Segmentation/Interactions/mitkSegmentAnythingTool.h @@ -1,152 +1,164 @@ /*============================================================================ 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 mitkSegmentAnythingTool_h #define mitkSegmentAnythingTool_h #include "mitkSegWithPreviewTool.h" #include "mitkPointSet.h" #include "mitkProcessExecutor.h" #include +#include +#include + namespace us { class ModuleResource; } namespace mitk { /** CHANGE THIS --ashis \brief Segment Anything Model interactive 2D tool. \ingroup ToolManagerEtAl \sa mitk::Tool \sa QmitkInteractiveSegmentation */ class MITKSEGMENTATION_EXPORT SegmentAnythingTool : public SegWithPreviewTool { public: mitkClassMacro(SegmentAnythingTool, SegWithPreviewTool); itkFactorylessNewMacro(Self); itkCloneMacro(Self); const char **GetXPM() const override; const char *GetName() const override; us::ModuleResource GetIconResource() const override; void Activated() override; void Deactivated() override; /** * Clears all picks and updates the preview. */ void ClearPicks(); bool HasPicks() const; itkSetMacro(MitkTempDir, std::string); itkGetConstMacro(MitkTempDir, std::string); itkSetMacro(PythonPath, std::string); itkGetConstMacro(PythonPath, std::string); itkSetMacro(ModelType, std::string); itkGetConstMacro(ModelType, std::string); itkSetMacro(CheckpointPath, std::string); itkGetConstMacro(CheckpointPath, std::string); itkSetMacro(GpuId, unsigned int); itkGetConstMacro(GpuId, unsigned int); itkSetMacro(IsAuto, bool); itkGetConstMacro(IsAuto, bool); itkBooleanMacro(IsAuto); itkSetMacro(IsReady, bool); itkGetConstMacro(IsReady, bool); itkBooleanMacro(IsReady); /** * @brief Static function to print out everything from itk::EventObject. * Used as callback in mitk::ProcessExecutor object. * */ static void onPythonProcessEvent(itk::Object *, const itk::EventObject &e, void *); bool run_download_model(std::string); protected: SegmentAnythingTool(); ~SegmentAnythingTool() override; void ConnectActionsAndFunctions() override; /* * @brief Add point action of StateMachine pattern */ virtual void OnAddPoint(StateMachineAction*, InteractionEvent* interactionEvent); virtual void OnAddNegativePoint(StateMachineAction*, InteractionEvent* interactionEvent); /* * @brief Delete action of StateMachine pattern */ virtual void OnDelete(StateMachineAction*, InteractionEvent* interactionEvent); /* * @brief Clear all seed points and call UpdatePreview to reset the segmentation Preview */ void ClearSeeds(); void DoUpdatePreview(const Image* inputAtTimeStep, const Image* oldSegAtTimeStep, LabelSetImage* previewImage, TimeStepType timeStep) override; - std::vector> GetPointsAsCSVString(const mitk::BaseGeometry*); + std::vector> GetPointsAsVector(const mitk::BaseGeometry*); + std::stringstream GetPointsAsCSVString(const mitk::BaseGeometry *baseGeometry); + std::string GetHashForCurrentPlane(); + + void start_async_process(); + private: /** * @brief Runs SAM python process with desired arguments to generate embeddings for the input image * */ void run_generate_embeddings(ProcessExecutor*, const std::string&, const std::string&, const std::string&, const std::string&, const unsigned int); void run_segmentation_from_points(ProcessExecutor*, const std::string&, const std::string&, const std::string&, const std::string&, const std::string&, const std::string&, const unsigned int); static mitk::Point2D Get2DIndicesfrom3DWorld(const mitk::BaseGeometry*, mitk::Point3D&); + void start_python_daemon(); + std::string m_MitkTempDir; std::string m_PythonPath; std::string m_ModelType; std::string m_CheckpointPath; - std::string m_InDir, m_OutDir, inputImagePath, pickleFilePath, outputImagePath, token; //rename as per standards + std::string m_InDir, m_OutDir, outputImagePath, token; // rename as per standards unsigned int m_GpuId = 0; PointSet::Pointer m_PointSetPositive; PointSet::Pointer m_PointSetNegative; DataNode::Pointer m_PointSetNode; DataNode::Pointer m_PointSetNodeNegative; bool m_IsGenerateEmbeddings = true; bool m_IsAuto = false; bool m_IsReady = false; const std::string TEMPLATE_FILENAME = "XXXXXX_000_0000.nii.gz"; + const std::string m_TRIGGER_FILENAME = "trigger.csv"; int m_PointSetCount = 0; + std::future m_Future; }; } // namespace #endif