diff --git a/Modules/Segmentation/Interactions/mitkSegmentAnythingTool.h b/Modules/Segmentation/Interactions/mitkSegmentAnythingTool.h
index a200b2c09b..5385dca185 100644
--- a/Modules/Segmentation/Interactions/mitkSegmentAnythingTool.h
+++ b/Modules/Segmentation/Interactions/mitkSegmentAnythingTool.h
@@ -1,217 +1,216 @@
 /*============================================================================
 
 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 "mitkSegmentAnythingPythonService.h"
 #include <MitkSegmentationExports.h>
 #include <itkImage.h>
 #include <mitkLevelWindow.h>
 
 namespace us
 {
   class ModuleResource;
 }
 
 namespace mitk
 {
   /**
   \brief Segment Anything Model interactive 2D tool class.
 
   \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;
 
     /**
      * @brief  Clears all picks and updates the preview.
      */
     void ClearPicks();
 
     /**
      * @brief Checks if any point exists in the either
      * of the pointsets
      * 
      * @return bool 
      */
     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, int);
     itkGetConstMacro(GpuId, int);
     
     itkSetMacro(TimeOutLimit, long);
     itkGetConstMacro(TimeOutLimit, long);
 
     itkSetMacro(IsReady, bool);
     itkGetConstMacro(IsReady, bool);
     itkBooleanMacro(IsReady);
 
     /**
      * @brief Initializes python service and
      * starts async python daemon of SegmentAnything model.
      * 
      */
     void InitSAMPythonProcess();
 
     /**
      * @brief Checks if Python daemon is ready to accept inputs.
      * 
      * @return bool 
      */
     bool IsPythonReady() const;
 
     Message1<const std::string&> SAMStatusMessageEvent;
 
   protected:
     SegmentAnythingTool();
     ~SegmentAnythingTool() = default;
 
     void ConnectActionsAndFunctions() override;
 
     /*
      * @brief Add positive seed point action of StateMachine pattern
      */
     virtual void OnAddPositivePoint(StateMachineAction*, InteractionEvent *interactionEvent);
     
     /*
      * @brief Add negative seed point action of StateMachine pattern
      */
     virtual void OnAddNegativePoint(StateMachineAction*, InteractionEvent *interactionEvent);
 
     /*
      * @brief Delete action of StateMachine pattern. The function deletes positive or negative points in 
        the reverse order of creation. This is done by finding & deleting the Point having the highest 
        PointIdentifier value from either of the PointSets m_PointSetPositive & m_PointSetNegative.
      */
     virtual void OnDelete(StateMachineAction*, InteractionEvent*);
 
     /*
      * @brief Clear all seed points and call UpdatePreview to reset the segmentation Preview
      */
     void ClearSeeds();
 
     /**
      * @brief Overriden method from the tool manager to execute the segmentation
      * Implementation:
      * 1. Creates Hash for input image from current plane geometry.
      * 2. Transfers image pointer to python service along with the hash code.
      * 3. Creates seed points as CSV string & transfers to python service
      * 3. Retrieves resulting segmentation Image pointer from python service and sets to previewImage.
      *
      * @param inputAtTimeStep
      * @param oldSegAtTimeStep
      * @param previewImage
      * @param timeStep
      */
     void DoUpdatePreview(const Image *inputAtTimeStep, const Image *oldSegAtTimeStep, LabelSetImage *previewImage, TimeStepType timeStep) override;
 
     /**
      * @brief Get the Points from positive and negative pointsets as std::vector.
      * 
-     * @param baseGeometry of Image
      * @return std::vector<std::pair<mitk::Point2D, std::string>> 
      */
     std::vector<std::pair<mitk::Point2D, std::string>> GetPointsAsVector(const mitk::BaseGeometry*);
 
     /**
      * @brief Get the Points from positive and negative pointsets as csv string.
      * 
      * @param baseGeometry 
      * @return std::stringstream 
      */
     std::stringstream GetPointsAsCSVString(const mitk::BaseGeometry *baseGeometry);
 
     /**
      * @brief Get the Hash For Current Plane from current working plane geometry.
      * 
      * @return std::string 
      */
     std::string GetHashForCurrentPlane(const mitk::LevelWindow&);
 
     /**
      * @brief Emits message to connected Listnerers.
      * 
      */
     void EmitSAMStatusMessageEvent(const std::string&);
 
     /**
      * @brief Cleans up segmentation preview and clears all seeds.
      * 
      */
     void ConfirmCleanUp() override;
 
     /**
      * @brief Applies ITK IntensityWindowing Filter to input image;
      *
      */
     template <typename TPixel, unsigned int VImageDimension>
     void ITKWindowing(const itk::Image<TPixel, VImageDimension>*, mitk::Image*, ScalarType, ScalarType);
 
   private:
     /**
      * @brief Convert 3D world coordinates to 2D indices.
      * 
      * @param baseGeometry 
      * @param mitk::Point3D
      * @return mitk::Point2D 
      */
     static mitk::Point2D Get2DIndicesfrom3DWorld(const mitk::BaseGeometry*, const mitk::Point3D&);
 
     std::string m_MitkTempDir;
     std::string m_PythonPath;
     std::string m_ModelType;
     std::string m_CheckpointPath;
     int m_GpuId = 0;
     PointSet::Pointer m_PointSetPositive;
     PointSet::Pointer m_PointSetNegative;
     DataNode::Pointer m_PointSetNodePositive;
     DataNode::Pointer m_PointSetNodeNegative;
     bool m_IsGenerateEmbeddings = true;
     bool m_IsReady = false;
     int m_PointSetCount = 0;
     long m_TimeOutLimit = -1;
     std::unique_ptr<SegmentAnythingPythonService> m_PythonService;
     const Label::PixelType MASK_VALUE = 1;
   };
 } // namespace
 
 #endif
diff --git a/Modules/SegmentationUI/Qmitk/QmitkSetupVirtualEnvUtil.cpp b/Modules/SegmentationUI/Qmitk/QmitkSetupVirtualEnvUtil.cpp
index 326bbc522f..b871e15128 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkSetupVirtualEnvUtil.cpp
+++ b/Modules/SegmentationUI/Qmitk/QmitkSetupVirtualEnvUtil.cpp
@@ -1,274 +1,238 @@
 /*============================================================================
 
 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.s
 
 ============================================================================*/
 
 #include "QmitkSetupVirtualEnvUtil.h"
 
 #include "mitkLog.h"
 #include <QStandardPaths>
 #include <itkCommand.h>
 #include <regex>
-#include <sstream>
 #include <QDir>
 #include <QApplication>
-#include <mutex>
+#include <QProcess>
+#include <QStringDecoder>
 
 QmitkSetupVirtualEnvUtil::QmitkSetupVirtualEnvUtil()
 {
   m_BaseDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QDir::separator() +
               qApp->organizationName() + QDir::separator();
 }
 
 QmitkSetupVirtualEnvUtil::QmitkSetupVirtualEnvUtil(const QString &baseDir)
 {
   m_BaseDir = baseDir;
 }
 
 QString& QmitkSetupVirtualEnvUtil::GetBaseDir()
 {
   return m_BaseDir;
 }
 
 QString QmitkSetupVirtualEnvUtil::GetVirtualEnvPath()
 {
   return m_venvPath;
 }
 
 QString& QmitkSetupVirtualEnvUtil::GetSystemPythonPath()
 {
   return m_SysPythonPath;
 }
 
 QString& QmitkSetupVirtualEnvUtil::GetPythonPath()
 {
   return m_PythonPath;
 }
 
 QString& QmitkSetupVirtualEnvUtil::GetPipPath()
 {
   return m_PipPath;
 }
 
 void QmitkSetupVirtualEnvUtil::SetVirtualEnvPath(const QString &path)
 {
   m_venvPath = path;
 }
 
 void QmitkSetupVirtualEnvUtil::SetPipPath(const QString &path)
 {
   m_PipPath = path;
 }
 
 void QmitkSetupVirtualEnvUtil::SetPythonPath(const QString &path)
 {
   if (this->IsPythonPath(path))
   {
     m_PythonPath = path;
   }
   else
   {
     MITK_INFO << "Python was not detected in " + path.toStdString();
   }
 }
 
 void QmitkSetupVirtualEnvUtil::SetSystemPythonPath(const QString &path)
 {
   if (this->IsPythonPath(path))
   {
     m_SysPythonPath = path;
   }
   else
   {
     MITK_INFO << "Python was not detected in " + path.toStdString();
   }
 }
 
 void QmitkSetupVirtualEnvUtil::PrintProcessEvent(itk::Object * /*pCaller*/, const itk::EventObject &e, void *)
 {
   std::string testCOUT;
   std::string testCERR;
   const auto *pEvent = dynamic_cast<const mitk::ExternalProcessStdOutEvent *>(&e);
   if (pEvent)
   {
     testCOUT = testCOUT + pEvent->GetOutput();
     MITK_INFO << testCOUT;
   }
   const auto *pErrEvent = dynamic_cast<const mitk::ExternalProcessStdErrEvent *>(&e);
   if (pErrEvent)
   {
     testCERR = testCERR + pErrEvent->GetOutput();
     MITK_ERROR << testCERR;
   }
 }
 
 void QmitkSetupVirtualEnvUtil::InstallPytorch(const std::string &workingDir,
                                               void (*callback)(itk::Object *, const itk::EventObject &, void *))
 {
   mitk::ProcessExecutor::ArgumentListType args;
   auto spExec = mitk::ProcessExecutor::New();
   auto spCommand = itk::CStyleCommand::New();
   spCommand->SetCallback(callback);
   spExec->AddObserver(mitk::ExternalProcessOutputEvent(), spCommand);
   args.push_back("-m");
   args.push_back("pip");
   args.push_back("install");
   args.push_back("light-the-torch==0.7.5");
   spExec->Execute(workingDir, "python", args);
   PipInstall("torch==2.0.0", workingDir, callback, "ltt");
   PipInstall("torchvision==0.15.0", workingDir, callback, "ltt");
 }
 
 void QmitkSetupVirtualEnvUtil::InstallPytorch()
 {
   this->InstallPytorch(GetPythonPath().toStdString(), &PrintProcessEvent);
 }
 
 void QmitkSetupVirtualEnvUtil::PipInstall(const std::string &library,
                                           const std::string &workingDir,
                                           void (*callback)(itk::Object *, const itk::EventObject &, void *),
                                           const std::string &command)
 {
   mitk::ProcessExecutor::ArgumentListType args;
   auto spExec = mitk::ProcessExecutor::New();
   auto spCommand = itk::CStyleCommand::New();
   spCommand->SetCallback(callback);
   spExec->AddObserver(mitk::ExternalProcessOutputEvent(), spCommand);
   args.push_back("install");
   args.push_back(library);
   spExec->Execute(workingDir, command, args);
 }
 
 void QmitkSetupVirtualEnvUtil::PipInstall(const std::string &library,
   void (*callback)(itk::Object*, const itk::EventObject&, void*),
   const std::string& command)
 {
   this->PipInstall(library, this->GetPipPath().toStdString(), callback, command);
 }
 
 void QmitkSetupVirtualEnvUtil::ExecutePython(const std::string &pythonCode,
                                              const std::string &workingDir,
                                              void (*callback)(itk::Object *, const itk::EventObject &, void *),
                                              const std::string &command)
 {
   mitk::ProcessExecutor::ArgumentListType args;
   auto spExec = mitk::ProcessExecutor::New();
   auto spCommand = itk::CStyleCommand::New();
   spCommand->SetCallback(callback);
   spExec->AddObserver(mitk::ExternalProcessOutputEvent(), spCommand);
   args.push_back("-c");
   args.push_back(pythonCode);
   spExec->Execute(workingDir, command, args);
 }
 
 void QmitkSetupVirtualEnvUtil::ExecutePython(const std::string &args,
                                              void (*callback)(itk::Object *, const itk::EventObject &, void *),
                                              const std::string &command)
 {
   this->ExecutePython(args, this->GetPythonPath().toStdString(), callback, command);
 }
 
 bool QmitkSetupVirtualEnvUtil::IsPythonPath(const QString &pythonPath)
 {
   QString fullPath = pythonPath;
   bool isExists =
 #ifdef _WIN32
     QFile::exists(fullPath + QDir::separator() + QString("python.exe"));
 #else
     QFile::exists(fullPath + QDir::separator() + QString("python3"));
 #endif
   return isExists;
 }
 
-namespace
-{
-  std::mutex mutex;
-  std::string pyVersionCaptured;
-
-  void CapturePyVersion(itk::Object * /*pCaller*/, const itk::EventObject &e, void *)
-  {
-    std::string testCOUT;
-    const auto *pEvent = dynamic_cast<const mitk::ExternalProcessStdOutEvent *>(&e);
-    if (pEvent)
-    {
-      pyVersionCaptured = pEvent->GetOutput();
-    }
-  }
-
-  std::vector<int> SplitVersionString(const std::string& version)
-  {
-    std::vector<int> splits;
-    std::string part;
-    std::istringstream tokenStream(version);
-    while (std::getline(tokenStream, part, '.'))
-    {
-      splits.push_back(std::stoi(part));
-    }
-    return splits;
-  }
-  
-  bool IsSupported(const std::string& version, const std::string& low, const std::string& high)
-  {
-    std::vector<int> inHandVersion = SplitVersionString(version);
-    std::vector<int> targetLowVersion = SplitVersionString(low);
-    std::vector<int> targetHighVersion = SplitVersionString(high);
-    if (inHandVersion.size() > 1 && targetLowVersion.size() > 1 && targetHighVersion.size() > 1)
-    { // comparing second part of the version 
-      return (inHandVersion[1] > targetLowVersion[1] && inHandVersion[1] < targetHighVersion[1]);
-    }
-    return false; 
-  }
-}
-
 std::pair<QString, QString> QmitkSetupVirtualEnvUtil::GetExactPythonPath(const QString &pyEnv)
 {
   QString fullPath = pyEnv;
   bool pythonDoesExist = false;
   bool isSupportedVersion = false;
 #ifdef _WIN32
   const std::string PYTHON_EXE = "python.exe";
   // check if python exist in given folder.
   pythonDoesExist = QFile::exists(fullPath + QDir::separator() + QString::fromStdString(PYTHON_EXE));
   if (!pythonDoesExist && // check if in Scripts already, if not go there
       !(fullPath.endsWith("Scripts", Qt::CaseInsensitive) || fullPath.endsWith("Scripts/", Qt::CaseInsensitive)))
   {
     fullPath += QDir::separator() + QString("Scripts");
     pythonDoesExist = QFile::exists(fullPath + QDir::separator() + QString("python.exe"));
   }
 #else
   const std::string PYTHON_EXE = "python3";
   pythonDoesExist = QFile::exists(fullPath + QDir::separator() + QString::fromStdString(PYTHON_EXE));
   if (!pythonDoesExist &&
       !(fullPath.endsWith("bin", Qt::CaseInsensitive) || fullPath.endsWith("bin/", Qt::CaseInsensitive)))
   {
     fullPath += QDir::separator() + QString("bin");
     pythonDoesExist = QFile::exists(fullPath + QDir::separator() + QString("python3"));
   }
 #endif
   std::pair<QString, QString> pythonPath;
   if (pythonDoesExist)
   {
-    ::mutex.lock();
-    std::regex sanitizer(R"([^3\.(\d+)])");
-    mitk::ProcessExecutor::ArgumentListType args;
-    auto spExec = mitk::ProcessExecutor::New();
-    auto spCommand = itk::CStyleCommand::New();
-    spCommand->SetCallback(&::CapturePyVersion);
-    spExec->AddObserver(mitk::ExternalProcessOutputEvent(), spCommand);
-    args.push_back("--version");
-    spExec->Execute(fullPath.toStdString(), PYTHON_EXE, args);
-    std::string pyVersionNumber = std::regex_replace(::pyVersionCaptured, sanitizer, "");
-    isSupportedVersion = ::IsSupported(pyVersionNumber, "3.8", "3.13");
-    pythonPath.second = QString::fromStdString(pyVersionNumber);
-    ::mutex.unlock();
+    std::regex sanitizer(R"(3\.(\d+))");
+    QProcess pyProcess;
+    pyProcess.start(fullPath + QDir::separator() + QString::fromStdString(PYTHON_EXE),
+                          QStringList() << "--version",
+                          QProcess::ReadOnly);
+    if (pyProcess.waitForFinished())
+    {
+      auto pyVersionCaptured = QString(QStringDecoder(QStringDecoder::Utf8)(pyProcess.readAllStandardOutput())).toStdString();
+      std::smatch match; // Expecting "Python 3.xx.xx" or "Python 3.xx"
+      if (std::regex_search(pyVersionCaptured, match, sanitizer) && !match.empty())
+      {
+        std::string pyVersionNumber = match[0];
+        int pySubVersion = std::stoi(match[1]);
+        isSupportedVersion = (pySubVersion > 8) ? (pySubVersion < 13) : false;
+        pythonPath.second = QString::fromStdString(pyVersionNumber);
+      }
+    }
   }
   pythonPath.first = pythonDoesExist &&isSupportedVersion ? fullPath : "";
   return pythonPath;
 }