Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkPythonService.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #include "mitkPythonService.h"
18 #include <Python.h>
19 #include <mitkIOUtil.h>
20 #include <QFile>
21 #include <QDir>
22 #include <PythonQt.h>
23 #include "PythonPath.h"
24 #include <vtkPolyData.h>
25 #include <mitkRenderingManager.h>
26 #include <mitkImageReadAccessor.h>
27 #include <mitkImageWriteAccessor.h>
28 #include <numpy/arrayobject.h>
29 #include <mitkExceptionMacro.h>
30 
31 #ifndef WIN32
32 #include <dlfcn.h>
33 #endif
34 
35 const QString mitk::PythonService::m_TmpDataFileName("temp_mitk_data_file");
36 #ifdef USE_MITK_BUILTIN_PYTHON
37 static char* pHome = NULL;
38 #endif
39 
41 : m_ItkWrappingAvailable( true ), m_OpenCVWrappingAvailable( true ), m_VtkWrappingAvailable( true ), m_ErrorOccured( false )
42 {
43  {
44  MITK_DEBUG << "will init python if necessary";
45  }
46  bool pythonInitialized = static_cast<bool>( Py_IsInitialized() ); //m_PythonManager.isPythonInitialized() );
47  {
48  MITK_DEBUG << "pythonInitialized " << pythonInitialized;
49  MITK_DEBUG << "m_PythonManager.isPythonInitialized() " << m_PythonManager.isPythonInitialized();
50  }
51 
52  // due to strange static var behaviour on windows Py_IsInitialized() returns correct value while
53  // m_PythonManager.isPythonInitialized() does not because it has been constructed and destructed again
54  if( !m_PythonManager.isPythonInitialized() )
55  {
56  try
57  {
58  //TODO a better way to do this
59 #ifndef WIN32
60 #if defined (__APPLE__) || defined(MACOSX)
61  const char* library = "libpython2.7.dylib";
62 #else
63  const char* library = "libpython2.7.so";
64 #endif
65  dlerror();
66  if(dlopen(library, RTLD_NOW | RTLD_GLOBAL) == 0 )
67  {
68  mitkThrow() << "Python runtime could not be loaded: " << dlerror();
69  }
70 #endif
71 
72  std::string programPath = mitk::IOUtil::GetProgramPath();
73  QDir programmDir( QString( programPath.c_str() ).append("/Python") );
74  QString pythonCommand;
75 
76  // TODO: Check this in the modernization branch with an installer
77  // Set the pythonpath variable depending if
78  // we have an installer or development environment
79  if ( programmDir.exists() ) {
80  // runtime directory used in installers
81  pythonCommand.append( QString("import site, sys\n") );
82  pythonCommand.append( QString("sys.path.append('')\n") );
83  pythonCommand.append( QString("sys.path.append('%1')\n").arg(programPath.c_str()) );
84  pythonCommand.append( QString("sys.path.append('%1/Python')").arg(programPath.c_str()) );
85  //pythonCommand.append( QString("\nsite.addsitedir('%1/Python/python2.7/site-packages')").arg(programPath.c_str()) );
86  //pythonCommand.append( QString("\nsite.addsitedir('%1/Python/python2.7/dist-packages')").arg(programPath.c_str()) );
87  // development
88  } else {
89  pythonCommand.append( QString("import site, sys\n") );
90  pythonCommand.append( QString("sys.path.append('')\n") );
91  pythonCommand.append( QString("sys.path.append('%1')\n").arg(EXTERNAL_DIST_PACKAGES) );
92  pythonCommand.append( QString("\nsite.addsitedir('%1')").arg(EXTERNAL_SITE_PACKAGES) );
93  }
94 
95  if( pythonInitialized )
96  m_PythonManager.setInitializationFlags(PythonQt::RedirectStdOut|PythonQt::PythonAlreadyInitialized);
97  else
98  m_PythonManager.setInitializationFlags(PythonQt::RedirectStdOut);
99 
100  // set python home if own runtime is used
101 #ifdef USE_MITK_BUILTIN_PYTHON
102  QString pythonHome;
103  if ( programmDir.exists() )
104  pythonHome.append(QString("%1/Python").arg(programPath.c_str()));
105  else
106  pythonHome.append(PYTHONHOME);
107 
108  if(pHome) delete[] pHome;
109  pHome = new char[pythonHome.toStdString().length() + 1];
110 
111  strcpy(pHome,pythonHome.toStdString().c_str());
112  Py_SetPythonHome(pHome);
113  MITK_DEBUG("PythonService") << "PythonHome: " << pHome;
114 #endif
115 
116  MITK_DEBUG("PythonService") << "initalizing python";
117 
118  m_PythonManager.initialize();
119 
120 #ifdef USE_MITK_BUILTIN_PYTHON
121  PyObject* dict = PyDict_New();
122  // Import builtin modules
123  if (PyDict_GetItemString(dict, "__builtins__") == NULL)
124  {
125  PyObject* builtinMod = PyImport_ImportModule("__builtin__");
126  if (builtinMod == NULL ||
127  PyDict_SetItemString(dict, "__builtins__", builtinMod) != 0)
128  {
129  Py_DECREF(dict);
130  Py_XDECREF(dict);
131  return;
132  }
133  Py_DECREF(builtinMod);
134  }
135 #endif
136 
137  MITK_DEBUG("PythonService")<< "Python Search paths: " << Py_GetPath();
138  MITK_DEBUG("PythonService") << "python initalized";
139 
140  //MITK_DEBUG("PythonService") << "registering python paths" << PYTHONPATH_COMMAND;
141  m_PythonManager.executeString( pythonCommand, ctkAbstractPythonManager::FileInput );
142  }
143  catch (...)
144  {
145  MITK_DEBUG("PythonService") << "exception initalizing python";
146  }
147  }
148 }
149 
151 {
152  MITK_DEBUG("mitk::PythonService") << "destructing PythonService";
153 
154 #ifdef USE_MITK_BUILTIN_PYTHON
155  if(pHome)
156  delete[] pHome;
157 #endif
158 }
159 
160 std::string mitk::PythonService::Execute(const std::string &stdpythonCommand, int commandType)
161 {
162  QString pythonCommand = QString::fromStdString(stdpythonCommand);
163  {
164  MITK_DEBUG("mitk::PythonService") << "pythonCommand = " << pythonCommand.toStdString();
165  MITK_DEBUG("mitk::PythonService") << "commandType = " << commandType;
166  }
167 
168  QVariant result;
169  bool commandIssued = true;
170 
171  if(commandType == IPythonService::SINGLE_LINE_COMMAND )
172  result = m_PythonManager.executeString(pythonCommand, ctkAbstractPythonManager::SingleInput );
173  else if(commandType == IPythonService::MULTI_LINE_COMMAND )
174  result = m_PythonManager.executeString(pythonCommand, ctkAbstractPythonManager::FileInput );
175  else if(commandType == IPythonService::EVAL_COMMAND )
176  result = m_PythonManager.executeString(pythonCommand, ctkAbstractPythonManager::EvalInput );
177  else
178  commandIssued = false;
179 
180  if(commandIssued)
181  {
182  this->NotifyObserver(pythonCommand.toStdString());
183  m_ErrorOccured = PythonQt::self()->hadError();
184  }
185 
186  return result.toString().toStdString();
187 }
188 
189 void mitk::PythonService::ExecuteScript( const std::string& pythonScript )
190 {
191  m_PythonManager.executeFile(QString::fromStdString(pythonScript));
192 }
193 
194 std::vector<mitk::PythonVariable> mitk::PythonService::GetVariableStack() const
195 {
196  std::vector<mitk::PythonVariable> list;
197 
198  PyObject* dict = PyImport_GetModuleDict();
199  PyObject* object = PyDict_GetItemString(dict, "__main__");
200  PyObject* dirMain = PyObject_Dir(object);
201  PyObject* tempObject = 0;
202  PyObject* strTempObject = 0;
203 
204  if(dirMain)
205  {
206  std::string name, attrValue, attrType;
207 
208  for(int i = 0; i<PyList_Size(dirMain); i++)
209  {
210  tempObject = PyList_GetItem(dirMain, i);
211  name = PyString_AsString(tempObject);
212  tempObject = PyObject_GetAttrString( object, name.c_str() );
213  attrType = tempObject->ob_type->tp_name;
214 
215  strTempObject = PyObject_Repr(tempObject);
216  if(strTempObject && ( PyUnicode_Check(strTempObject) || PyString_Check(strTempObject) ) )
217  attrValue = PyString_AsString(strTempObject);
218  else
219  attrValue = "";
220 
222  var.m_Name = name;
223  var.m_Value = attrValue;
224  var.m_Type = attrType;
225  list.push_back(var);
226  }
227  }
228 
229  return list;
230 }
231 
232 bool mitk::PythonService::DoesVariableExist(const std::string& name) const
233 {
234  bool varExists = false;
235 
236  std::vector<mitk::PythonVariable> allVars = this->GetVariableStack();
237  for(unsigned int i = 0; i< allVars.size(); i++)
238  {
239  if( allVars.at(i).m_Name == name )
240  {
241  varExists = true;
242  break;
243  }
244  }
245 
246  return varExists;
247 }
248 
250 {
251  if(!m_Observer.contains(observer))
252  m_Observer.append(observer);
253 }
254 
256 {
257  m_Observer.removeOne(observer);
258 }
259 
260 void mitk::PythonService::NotifyObserver(const std::string &command)
261 {
262  MITK_DEBUG("mitk::PythonService") << "number of observer " << m_Observer.size();
263  for( int i=0; i< m_Observer.size(); ++i )
264  {
265  m_Observer.at(i)->CommandExecuted(command);
266  }
267 }
268 
269 QString mitk::PythonService::GetTempDataFileName(const std::string& ext) const
270 {
271  QString tmpFolder = QDir::tempPath();
272  QString fileName = tmpFolder + QDir::separator() + m_TmpDataFileName + QString::fromStdString(ext);
273  return fileName;
274 }
275 
276 bool mitk::PythonService::CopyToPythonAsSimpleItkImage(mitk::Image *image, const std::string &stdvarName)
277 {
278  QString varName = QString::fromStdString( stdvarName );
279  QString command;
280  unsigned int* imgDim = image->GetDimensions();
281  int npy_nd = 1;
282 
283  // access python module
284  PyObject *pyMod = PyImport_AddModule((char*)"__main__");
285  // global dictionary
286  PyObject *pyDict = PyModule_GetDict(pyMod);
287  const mitk::Vector3D spacing = image->GetGeometry()->GetSpacing();
288  const mitk::Point3D origin = image->GetGeometry()->GetOrigin();
289  mitk::PixelType pixelType = image->GetPixelType();
290  itk::ImageIOBase::IOPixelType ioPixelType = image->GetPixelType().GetPixelType();
291  PyObject* npyArray = NULL;
292  mitk::ImageReadAccessor racc(image);
293  void* array = (void*) racc.GetData();
294 
295  mitk::Vector3D xDirection;
296  mitk::Vector3D yDirection;
297  mitk::Vector3D zDirection;
298  const vnl_matrix_fixed<ScalarType, 3, 3> &transform =
299  image->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix();
300 
301  // ToDo: Check if this is a collumn or row vector from the matrix.
302  // right now it works but not sure for rotated geometries
303  mitk::FillVector3D(xDirection, transform[0][0], transform[0][1], transform[0][2]);
304  mitk::FillVector3D(yDirection, transform[1][0], transform[1][1], transform[1][2]);
305  mitk::FillVector3D(zDirection, transform[2][0], transform[2][1], transform[2][2]);
306 
307  xDirection.Normalize();
308  yDirection.Normalize();
309  zDirection.Normalize();
310 
311  // save the total number of elements here (since the numpy array is one dimensional)
312  npy_intp* npy_dims = new npy_intp[1];
313  npy_dims[0] = imgDim[0];
314 
320  QString dimensionString;
321  dimensionString.append(QString("["));
322  dimensionString.append(QString::number(imgDim[0]));
323  for (unsigned i = 1; i < 3; ++i)
324  // always three because otherwise the 3d-geometry gets destroyed
325  // (relevant for backtransformation of simple itk image to mitk.
326  {
327  dimensionString.append(QString(","));
328  dimensionString.append(QString::number(imgDim[i]));
329  npy_dims[0] *= imgDim[i];
330  }
331  dimensionString.append("]");
332 
333 
334  // the next line is necessary for vectorimages
335  npy_dims[0] *= pixelType.GetNumberOfComponents();
336 
337  // default pixeltype: unsigned short
338  NPY_TYPES npy_type = NPY_USHORT;
339  std::string sitk_type = "sitkUInt8";
340  if( ioPixelType == itk::ImageIOBase::SCALAR )
341  {
342  if( pixelType.GetComponentType() == itk::ImageIOBase::DOUBLE ) {
343  npy_type = NPY_DOUBLE;
344  sitk_type = "sitkFloat64";
345  } else if( pixelType.GetComponentType() == itk::ImageIOBase::FLOAT ) {
346  npy_type = NPY_FLOAT;
347  sitk_type = "sitkFloat32";
348  } else if( pixelType.GetComponentType() == itk::ImageIOBase::SHORT) {
349  npy_type = NPY_SHORT;
350  sitk_type = "sitkInt16";
351  } else if( pixelType.GetComponentType() == itk::ImageIOBase::CHAR ) {
352  npy_type = NPY_BYTE;
353  sitk_type = "sitkInt8";
354  } else if( pixelType.GetComponentType() == itk::ImageIOBase::INT ) {
355  npy_type = NPY_INT;
356  sitk_type = "sitkInt32";
357  } else if( pixelType.GetComponentType() == itk::ImageIOBase::LONG ) {
358  npy_type = NPY_LONG;
359  sitk_type = "sitkInt64";
360  } else if( pixelType.GetComponentType() == itk::ImageIOBase::UCHAR ) {
361  npy_type = NPY_UBYTE;
362  sitk_type = "sitkUInt8";
363  } else if( pixelType.GetComponentType() == itk::ImageIOBase::UINT ) {
364  npy_type = NPY_UINT;
365  sitk_type = "sitkUInt32";
366  } else if( pixelType.GetComponentType() == itk::ImageIOBase::ULONG ) {
367  npy_type = NPY_LONG;
368  sitk_type = "sitkUInt64";
369  } else if( pixelType.GetComponentType() == itk::ImageIOBase::USHORT ) {
370  npy_type = NPY_USHORT;
371  sitk_type = "sitkUInt16";
372  }
373  }
374  else if ( ioPixelType == itk::ImageIOBase::VECTOR ||
375  ioPixelType == itk::ImageIOBase::RGB ||
376  ioPixelType == itk::ImageIOBase::RGBA
377  )
378  {
379  if( pixelType.GetComponentType() == itk::ImageIOBase::DOUBLE ) {
380  npy_type = NPY_DOUBLE;
381  sitk_type = "sitkVectorFloat64";
382  } else if( pixelType.GetComponentType() == itk::ImageIOBase::FLOAT ) {
383  npy_type = NPY_FLOAT;
384  sitk_type = "sitkVectorFloat32";
385  } else if( pixelType.GetComponentType() == itk::ImageIOBase::SHORT) {
386  npy_type = NPY_SHORT;
387  sitk_type = "sitkVectorInt16";
388  } else if( pixelType.GetComponentType() == itk::ImageIOBase::CHAR ) {
389  npy_type = NPY_BYTE;
390  sitk_type = "sitkVectorInt8";
391  } else if( pixelType.GetComponentType() == itk::ImageIOBase::INT ) {
392  npy_type = NPY_INT;
393  sitk_type = "sitkVectorInt32";
394  } else if( pixelType.GetComponentType() == itk::ImageIOBase::LONG ) {
395  npy_type = NPY_LONG;
396  sitk_type = "sitkVectorInt64";
397  } else if( pixelType.GetComponentType() == itk::ImageIOBase::UCHAR ) {
398  npy_type = NPY_UBYTE;
399  sitk_type = "sitkVectorUInt8";
400  } else if( pixelType.GetComponentType() == itk::ImageIOBase::UINT ) {
401  npy_type = NPY_UINT;
402  sitk_type = "sitkVectorUInt32";
403  } else if( pixelType.GetComponentType() == itk::ImageIOBase::ULONG ) {
404  npy_type = NPY_LONG;
405  sitk_type = "sitkVectorUInt64";
406  } else if( pixelType.GetComponentType() == itk::ImageIOBase::USHORT ) {
407  npy_type = NPY_USHORT;
408  sitk_type = "sitkVectorUInt16";
409  }
410  }
411  else {
412  MITK_WARN << "not a recognized pixeltype";
413  return false;
414  }
415 
416  // creating numpy array
417  import_array1 (true);
418  npyArray = PyArray_SimpleNewFromData(npy_nd,npy_dims,npy_type,array);
419 
420  // add temp array it to the python dictionary to access it in python code
421  const int status = PyDict_SetItemString( pyDict,QString("%1_numpy_array")
422  .arg(varName).toStdString().c_str(),
423  npyArray );
424 
425 
426  // sanity check
427  if ( status != 0 )
428  return false;
429 
430 
431  command.append( QString("%1 = sitk.Image(%2,sitk.%3,%4)\n").arg(varName)
432  .arg(dimensionString)
433  .arg(QString(sitk_type.c_str())).arg(QString::number(pixelType.GetNumberOfComponents())) );
434  command.append( QString("%1.SetSpacing([%2,%3,%4])\n").arg(varName)
435  .arg(QString::number(spacing[0]))
436  .arg(QString::number(spacing[1]))
437  .arg(QString::number(spacing[2])) );
438  command.append( QString("%1.SetOrigin([%2,%3,%4])\n").arg(varName)
439  .arg(QString::number(origin[0]))
440  .arg(QString::number(origin[1]))
441  .arg(QString::number(origin[2])) );
442  command.append( QString("%1.SetDirection([%2,%3,%4,%5,%6,%7,%8,%9,%10])\n").arg(varName)
443  .arg(QString::number(xDirection[0]))
444  .arg(QString::number(xDirection[1]))
445  .arg(QString::number(xDirection[2]))
446  .arg(QString::number(yDirection[0]))
447  .arg(QString::number(yDirection[1]))
448  .arg(QString::number(yDirection[2]))
449  .arg(QString::number(zDirection[0]))
450  .arg(QString::number(zDirection[1]))
451  .arg(QString::number(zDirection[2]))
452  );
453  // directly access the cpp api from the lib
454  command.append( QString("_SimpleITK._SetImageFromArray(%1_numpy_array,%1)\n").arg(varName) );
455  command.append( QString("del %1_numpy_array").arg(varName) );
456 
457  MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
458 
459 
460  this->Execute( command.toStdString(), IPythonService::MULTI_LINE_COMMAND );
461 
462  return true;
463 }
464 
465 
466 mitk::PixelType DeterminePixelType(const std::string& pythonPixeltype, int nrComponents, int dimensions)
467 {
468  typedef itk::RGBPixel< unsigned char > UCRGBPixelType;
469  typedef itk::RGBPixel< unsigned short > USRGBPixelType;
470  typedef itk::RGBPixel< float > FloatRGBPixelType;
471  typedef itk::RGBPixel< double > DoubleRGBPixelType;
472  typedef itk::Image< UCRGBPixelType > UCRGBImageType;
473  typedef itk::Image< USRGBPixelType > USRGBImageType;
474  typedef itk::Image< FloatRGBPixelType > FloatRGBImageType;
475  typedef itk::Image< DoubleRGBPixelType > DoubleRGBImageType;
476  typedef itk::RGBAPixel< unsigned char > UCRGBAPixelType;
477  typedef itk::RGBAPixel< unsigned short > USRGBAPixelType;
478  typedef itk::RGBAPixel< float > FloatRGBAPixelType;
479  typedef itk::RGBAPixel< double > DoubleRGBAPixelType;
480  typedef itk::Image< UCRGBAPixelType > UCRGBAImageType;
481  typedef itk::Image< USRGBAPixelType > USRGBAImageType;
482  typedef itk::Image< FloatRGBAPixelType > FloatRGBAImageType;
483  typedef itk::Image< DoubleRGBAPixelType > DoubleRGBAImageType;
484 
485  mitk::PixelType pixelType = mitk::MakePixelType<char, char >(nrComponents);
486 
487  if (nrComponents == 1)
488  {
489  if( pythonPixeltype.compare("float64") == 0 ) {
490  pixelType = mitk::MakePixelType<double, double >(nrComponents);
491  } else if( pythonPixeltype.compare("float32") == 0 ) {
492  pixelType = mitk::MakePixelType<float, float >(nrComponents);
493  } else if( pythonPixeltype.compare("int16") == 0) {
494  pixelType = mitk::MakePixelType<short, short >(nrComponents);
495  } else if( pythonPixeltype.compare("int8") == 0 ) {
496  pixelType = mitk::MakePixelType<char, char >(nrComponents);
497  } else if( pythonPixeltype.compare("int32") == 0 ) {
498  pixelType = mitk::MakePixelType<int, int >(nrComponents);
499  } else if( pythonPixeltype.compare("int64") == 0 ) {
500  pixelType = mitk::MakePixelType<long, long >(nrComponents);
501  } else if( pythonPixeltype.compare("uint8") == 0 ) {
502  pixelType = mitk::MakePixelType<unsigned char, unsigned char >(nrComponents);
503  } else if( pythonPixeltype.compare("uint32") == 0 ) {
504  pixelType = mitk::MakePixelType<unsigned int, unsigned int >(nrComponents);
505  } else if( pythonPixeltype.compare("uint64") == 0 ) {
506  pixelType = mitk::MakePixelType<unsigned long, unsigned long >(nrComponents);
507  } else if( pythonPixeltype.compare("uint16") == 0 ) {
508  pixelType = mitk::MakePixelType<unsigned short, unsigned short >(nrComponents);
509  }
510  else
511  {
512  mitkThrow()<< "unknown scalar PixelType";
513  }
514  } else if(nrComponents == 3 && dimensions == 2) {
515  if( pythonPixeltype.compare("float64") == 0 ) {
516  pixelType = mitk::MakePixelType<DoubleRGBImageType>();
517  } else if( pythonPixeltype.compare("float32") == 0 ) {
518  pixelType = mitk::MakePixelType<FloatRGBImageType>();
519  } else if( pythonPixeltype.compare("uint8") == 0 ) {
520  pixelType = mitk::MakePixelType<UCRGBImageType>();
521  } else if( pythonPixeltype.compare("uint16") == 0 ) {
522  pixelType = mitk::MakePixelType<USRGBImageType>();
523  }
524  } else if( (nrComponents == 4) && dimensions == 2 ) {
525  if( pythonPixeltype.compare("float64") == 0 ) {
526  pixelType = mitk::MakePixelType<DoubleRGBAImageType>();
527  } else if( pythonPixeltype.compare("float32") == 0 ) {
528  pixelType = mitk::MakePixelType<FloatRGBAImageType>();
529  } else if( pythonPixeltype.compare("uint8") == 0 ) {
530  pixelType = mitk::MakePixelType<UCRGBAImageType>();
531  } else if( pythonPixeltype.compare("uint16") == 0 ) {
532  pixelType = mitk::MakePixelType<USRGBAImageType>();
533  }
534  }
535  else {
536  if( pythonPixeltype.compare("float64") == 0 ) {
537  pixelType = mitk::MakePixelType<double, itk::Vector<double,3> >(nrComponents);
538  } else if( pythonPixeltype.compare("float32") == 0 ) {
539  pixelType = mitk::MakePixelType<float, itk::Vector<float,3> >(nrComponents);
540  } else if( pythonPixeltype.compare("int16") == 0) {
541  pixelType = mitk::MakePixelType<short, itk::Vector<short,3> >(nrComponents);
542  } else if( pythonPixeltype.compare("int8") == 0 ) {
543  pixelType = mitk::MakePixelType<char, itk::Vector<char,3> >(nrComponents);
544  } else if( pythonPixeltype.compare("int32") == 0 ) {
545  pixelType = mitk::MakePixelType<int, itk::Vector<int,3> >(nrComponents);
546  } else if( pythonPixeltype.compare("int64") == 0 ) {
547  pixelType = mitk::MakePixelType<long, itk::Vector<long,3> >(nrComponents);
548  } else if( pythonPixeltype.compare("uint8") == 0 ) {
549  pixelType = mitk::MakePixelType<unsigned char, itk::Vector<unsigned char,3> >(nrComponents);
550  } else if( pythonPixeltype.compare("uint16") == 0 ) {
551  pixelType = mitk::MakePixelType<unsigned short, itk::Vector<unsigned short,3> >(nrComponents);
552  } else if( pythonPixeltype.compare("uint32") == 0 ) {
553  pixelType = mitk::MakePixelType<unsigned int, itk::Vector<unsigned int,3> >(nrComponents);
554  } else if( pythonPixeltype.compare("uint64") == 0 ) {
555  pixelType = mitk::MakePixelType<unsigned long, itk::Vector<unsigned long,3> >(nrComponents);
556  } else {
557  mitkThrow()<< "unknown vectorial PixelType";
558  }
559  }
560 
561  return pixelType;
562 }
563 
565 {
566  double*ds = NULL;
567  // access python module
568  PyObject *pyMod = PyImport_AddModule((char*)"__main__");
569  // global dictionarry
570  PyObject *pyDict = PyModule_GetDict(pyMod);
572  mitk::Vector3D spacing;
573  mitk::Point3D origin;
574  QString command;
575  QString varName = QString::fromStdString( stdvarName );
576 
577  command.append( QString("%1_numpy_array = sitk.GetArrayFromImage(%1)\n").arg(varName) );
578  command.append( QString("%1_spacing = numpy.asarray(%1.GetSpacing())\n").arg(varName) );
579  command.append( QString("%1_origin = numpy.asarray(%1.GetOrigin())\n").arg(varName) );
580  command.append( QString("%1_dtype = %1_numpy_array.dtype.name\n").arg(varName) );
581  command.append( QString("%1_direction = numpy.asarray(%1.GetDirection())\n").arg(varName) );
582  command.append( QString("%1_nrComponents = numpy.asarray(%1.GetNumberOfComponentsPerPixel())\n").arg(varName));
583  command.append( QString("%1_dtype = %1_numpy_array.dtype.name\n").arg(varName) );
584 
585 
586  MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
587  this->Execute(command.toStdString(), IPythonService::MULTI_LINE_COMMAND );
588 
589  PyObject* py_dtype = PyDict_GetItemString(pyDict,QString("%1_dtype").arg(varName).toStdString().c_str() );
590  std::string dtype = PyString_AsString(py_dtype);
591  PyArrayObject* py_data = (PyArrayObject*) PyDict_GetItemString(pyDict,QString("%1_numpy_array").arg(varName).toStdString().c_str() );
592  PyArrayObject* py_spacing = (PyArrayObject*) PyDict_GetItemString(pyDict,QString("%1_spacing").arg(varName).toStdString().c_str() );
593  PyArrayObject* py_origin = (PyArrayObject*) PyDict_GetItemString(pyDict,QString("%1_origin").arg(varName).toStdString().c_str() );
594  PyArrayObject* py_direction = (PyArrayObject*) PyDict_GetItemString(pyDict,QString("%1_direction").arg(varName).toStdString().c_str() );
595 
596  PyArrayObject* py_nrComponents = (PyArrayObject*) PyDict_GetItemString(pyDict,QString("%1_nrComponents").arg(varName).toStdString().c_str() );
597 
598  unsigned int nr_Components = *((unsigned int*) py_nrComponents->data);
599 
600  unsigned int nr_dimensions = py_data->nd;
601  if (nr_Components > 1) // for VectorImages the last dimension in the numpy array are the vector components.
602  {
603  --nr_dimensions;
604  }
605 
606  mitk::PixelType pixelType = DeterminePixelType(dtype, nr_Components, nr_dimensions);
607 
608  unsigned int* dimensions = new unsigned int[nr_dimensions];
609  // fill backwards , nd data saves dimensions in opposite direction
610  for( unsigned i = 0; i < nr_dimensions; ++i )
611  {
612  dimensions[i] = py_data->dimensions[nr_dimensions - 1 - i];
613  }
614 
615  mitkImage->Initialize(pixelType, nr_dimensions, dimensions);
616 
617 
618  mitkImage->SetChannel(py_data->data);
619 
620 
621  ds = (double*)py_spacing->data;
622  spacing[0] = ds[0];
623  spacing[1] = ds[1];
624  spacing[2] = ds[2];
625 
626  mitkImage->GetGeometry()->SetSpacing(spacing);
627 
628 
629  ds = (double*)py_origin->data;
630  origin[0] = ds[0];
631  origin[1] = ds[1];
632  origin[2] = ds[2];
633  mitkImage->GetGeometry()->SetOrigin(origin);
634 
635 
636  itk::Matrix<double,3,3> py_transform;
637 
638  ds = (double*)py_direction->data;
639  py_transform[0][0] = ds[0];
640  py_transform[0][1] = ds[1];
641  py_transform[0][2] = ds[2];
642 
643  py_transform[1][0] = ds[3];
644  py_transform[1][1] = ds[4];
645  py_transform[1][2] = ds[5];
646 
647  py_transform[2][0] = ds[6];
648  py_transform[2][1] = ds[7];
649  py_transform[2][2] = ds[8];
650 
651  mitk::AffineTransform3D::Pointer affineTransform = mitkImage->GetGeometry()->GetIndexToWorldTransform();
652 
653  itk::Matrix<double,3,3> transform = py_transform * affineTransform->GetMatrix();
654 
655  affineTransform->SetMatrix(transform);
656 
657  mitkImage->GetGeometry()->SetIndexToWorldTransform(affineTransform);
658 
659  // mitk::AffineTransform3D::New();
660  //mitkImage->GetGeometry()->SetIndexToWorldTransform();
661 
662  // cleanup
663  command.clear();
664  command.append( QString("del %1_numpy_array\n").arg(varName) );
665  command.append( QString("del %1_dtype\n").arg(varName) );
666  command.append( QString("del %1_spacing\n").arg(varName) );
667  command.append( QString("del %1_origin\n").arg(varName) );
668  command.append( QString("del %1_direction\n").arg(varName) );
669  command.append( QString("del %1_nrComponents\n").arg(varName) );
670  MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
671  this->Execute(command.toStdString(), IPythonService::MULTI_LINE_COMMAND );
672 
673  delete[] dimensions;
674 
675 
676  return mitkImage;
677 }
678 
679 bool mitk::PythonService::CopyToPythonAsCvImage( mitk::Image* image, const std::string& stdvarName )
680 {
681  QString varName = QString::fromStdString( stdvarName );
682  QString command;
683  unsigned int* imgDim = image->GetDimensions();
684  int npy_nd = 1;
685 
686  // access python module
687  PyObject *pyMod = PyImport_AddModule((char*)"__main__");
688  // global dictionary
689  PyObject *pyDict = PyModule_GetDict(pyMod);
690  mitk::PixelType pixelType = image->GetPixelType();
691  PyObject* npyArray = NULL;
692  mitk::ImageReadAccessor racc(image);
693  void* array = (void*) racc.GetData();
694 
695  // save the total number of elements here (since the numpy array is one dimensional)
696  npy_intp* npy_dims = new npy_intp[1];
697  npy_dims[0] = imgDim[0];
698 
704  QString dimensionString;
705  dimensionString.append(QString("["));
706  dimensionString.append(QString::number(imgDim[0]));
707  // ToDo: check if we need this
708  for (unsigned i = 1; i < 3; ++i)
709  // always three because otherwise the 3d-geometry gets destroyed
710  // (relevant for backtransformation of simple itk image to mitk.
711  {
712  dimensionString.append(QString(","));
713  dimensionString.append(QString::number(imgDim[i]));
714  npy_dims[0] *= imgDim[i];
715  }
716  dimensionString.append("]");
717 
718 
719  // the next line is necessary for vectorimages
720  npy_dims[0] *= pixelType.GetNumberOfComponents();
721 
722  // default pixeltype: unsigned short
723  NPY_TYPES npy_type = NPY_USHORT;
724  if( pixelType.GetComponentType() == itk::ImageIOBase::DOUBLE ) {
725  npy_type = NPY_DOUBLE;
726  } else if( pixelType.GetComponentType() == itk::ImageIOBase::FLOAT ) {
727  npy_type = NPY_FLOAT;
728  } else if( pixelType.GetComponentType() == itk::ImageIOBase::SHORT) {
729  npy_type = NPY_SHORT;
730  } else if( pixelType.GetComponentType() == itk::ImageIOBase::CHAR ) {
731  npy_type = NPY_BYTE;
732  } else if( pixelType.GetComponentType() == itk::ImageIOBase::INT ) {
733  npy_type = NPY_INT;
734  } else if( pixelType.GetComponentType() == itk::ImageIOBase::LONG ) {
735  npy_type = NPY_LONG;
736  } else if( pixelType.GetComponentType() == itk::ImageIOBase::UCHAR ) {
737  npy_type = NPY_UBYTE;
738  } else if( pixelType.GetComponentType() == itk::ImageIOBase::UINT ) {
739  npy_type = NPY_UINT;
740  } else if( pixelType.GetComponentType() == itk::ImageIOBase::ULONG ) {
741  npy_type = NPY_LONG;
742  } else if( pixelType.GetComponentType() == itk::ImageIOBase::USHORT ) {
743  npy_type = NPY_USHORT;
744  }
745  else {
746  MITK_WARN << "not a recognized pixeltype";
747  return false;
748  }
749 
750  // creating numpy array
751  import_array1 (true);
752  npyArray = PyArray_SimpleNewFromData(npy_nd,npy_dims,npy_type,array);
753 
754  // add temp array it to the python dictionary to access it in python code
755  const int status = PyDict_SetItemString( pyDict,QString("%1_numpy_array")
756  .arg(varName).toStdString().c_str(),
757  npyArray );
758  // sanity check
759  if ( status != 0 )
760  return false;
761 
762  command.append( QString("import numpy as np\n"));
763  //command.append( QString("if '%1' in globals():\n").arg(varName));
764  //command.append( QString(" del %1\n").arg(varName));
765  command.append( QString("%1_array_tmp=%1_numpy_array.copy()\n").arg(varName));
766  command.append( QString("%1_array_tmp=%1_array_tmp.reshape(%2,%3,%4)\n").arg( varName,
767  QString::number(imgDim[1]),
768  QString::number(imgDim[0]),
769  QString::number(pixelType.GetNumberOfComponents())));
770 
771  command.append( QString("%1 = %1_array_tmp[:,...,::-1]\n").arg(varName));
772  command.append( QString("del %1_numpy_array\n").arg(varName) );
773  command.append( QString("del %1_array_tmp").arg(varName) );
774 
775  MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
776 
777  this->Execute( command.toStdString(), IPythonService::MULTI_LINE_COMMAND );
778 
779  return true;
780 }
781 
782 
784 {
785 
786  // access python module
787  PyObject *pyMod = PyImport_AddModule((char*)"__main__");
788  // global dictionarry
789  PyObject *pyDict = PyModule_GetDict(pyMod);
791  QString command;
792  QString varName = QString::fromStdString( stdvarName );
793 
794  command.append( QString("import numpy as np\n"));
795  command.append( QString("%1_dtype=%1.dtype.name\n").arg(varName) );
796  command.append( QString("%1_shape=np.asarray(%1.shape)\n").arg(varName) );
797  command.append( QString("%1_np_array=%1[:,...,::-1]\n").arg(varName));
798  command.append( QString("%1_np_array=np.reshape(%1_np_array,%1.shape[0] * %1.shape[1] * %1.shape[2])").arg(varName) );
799 
800  MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
801  this->Execute(command.toStdString(), IPythonService::MULTI_LINE_COMMAND );
802 
803  PyObject* py_dtype = PyDict_GetItemString(pyDict,QString("%1_dtype").arg(varName).toStdString().c_str() );
804  std::string dtype = PyString_AsString(py_dtype);
805  PyArrayObject* py_data = (PyArrayObject*) PyDict_GetItemString(pyDict,QString("%1_np_array").arg(varName).toStdString().c_str() );
806  PyArrayObject* shape = (PyArrayObject*) PyDict_GetItemString(pyDict,QString("%1_shape").arg(varName).toStdString().c_str() );
807 
808  size_t* d = (size_t*)shape->data;
809 
810  unsigned int dimensions[3];
811  dimensions[0] = d[1];
812  dimensions[1] = d[0];
813  dimensions[2] = d[2];
814 
815  unsigned int nr_dimensions = 2;
816 
817  // get number of components
818  unsigned int nr_Components = (unsigned int) d[2];
819 
820  mitk::PixelType pixelType = DeterminePixelType(dtype, nr_Components, nr_dimensions);
821 
822  mitkImage->Initialize(pixelType, nr_dimensions, dimensions);
823  //mitkImage->SetChannel(py_data->data);
824 
825  {
826  mitk::ImageWriteAccessor ra(mitkImage);
827  char* data = (char*)(ra.GetData());
828  memcpy(data, (void*)py_data->data, dimensions[0] * dimensions[1] * pixelType.GetSize());
829  }
830 
831  command.clear();
832 
833  command.append( QString("del %1_shape\n").arg(varName) );
834  command.append( QString("del %1_dtype\n").arg(varName) );
835  command.append( QString("del %1_np_array").arg(varName));
836 
837  MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
838  this->Execute(command.toStdString(), IPythonService::MULTI_LINE_COMMAND );
839 
840  return mitkImage;
841 }
842 
843 ctkAbstractPythonManager *mitk::PythonService::GetPythonManager()
844 {
845  return &m_PythonManager;
846 }
847 
849 {
850  // access python module
851  PyObject *pyMod = PyImport_AddModule((char*)"__main__");
852  // global dictionarry
853  PyObject *pyDict = PyModule_GetDict(pyMod);
854  // python memory address
855  PyObject *pyAddr = NULL;
856  // cpp address
857  size_t addr = 0;
859  QString command;
860  QString varName = QString::fromStdString( stdvarName );
861 
862  command.append( QString("%1_addr_str = %1.GetAddressAsString(\"vtkPolyData\")\n").arg(varName) );
863  // remove 0x from the address
864  command.append( QString("%1_addr = int(%1_addr_str[5:],16)").arg(varName) );
865 
866  MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
867  this->Execute(command.toStdString(), IPythonService::MULTI_LINE_COMMAND );
868 
869  // get address of the object
870  pyAddr = PyDict_GetItemString(pyDict,QString("%1_addr").arg(varName).toStdString().c_str());
871 
872  // convert to long
873  addr = PyInt_AsLong(pyAddr);
874 
875  MITK_DEBUG << "Python object address: " << addr;
876 
877  // get the object
878  vtkPolyData* poly = (vtkPolyData*)((void*)addr);
879  surface->SetVtkPolyData(poly);
880 
881  // delete helper variables from python stack
882  command = "";
883  command.append( QString("del %1_addr_str\n").arg(varName) );
884  command.append( QString("del %1_addr").arg(varName) );
885 
886  MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
887  this->Execute(command.toStdString(), IPythonService::MULTI_LINE_COMMAND );
888 
889  return surface;
890 }
891 
892 bool mitk::PythonService::CopyToPythonAsVtkPolyData( mitk::Surface* surface, const std::string& stdvarName )
893 {
894  QString varName = QString::fromStdString( stdvarName );
895  std::ostringstream oss;
896  std::string addr = "";
897  QString command;
898  QString address;
899 
900  oss << (void*) ( surface->GetVtkPolyData() );
901 
902  // get the address
903  addr = oss.str();
904 
905  // remove "0x"
906  address = QString::fromStdString(addr.substr(2));
907 
908  command.append( QString("%1 = vtk.vtkPolyData(\"%2\")\n").arg(varName).arg(address) );
909 
910  MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
911  this->Execute(command.toStdString(), IPythonService::MULTI_LINE_COMMAND );
912 
913  return true;
914 }
915 
917 {
918  this->Execute( "import SimpleITK as sitk\n", IPythonService::SINGLE_LINE_COMMAND );
919  // directly access cpp lib
920  this->Execute( "import _SimpleITK\n", IPythonService::SINGLE_LINE_COMMAND );
921  m_ItkWrappingAvailable = !this->PythonErrorOccured();
922 
923  // check for numpy
924  this->Execute( "import numpy\n", IPythonService::SINGLE_LINE_COMMAND );
925 
926  if ( this->PythonErrorOccured() )
927  MITK_ERROR << "Numpy not found.";
928 
929  m_ItkWrappingAvailable = !this->PythonErrorOccured();
930 
931  return m_ItkWrappingAvailable;
932 }
933 
935 {
936  this->Execute( "import cv2\n", IPythonService::SINGLE_LINE_COMMAND );
937  m_OpenCVWrappingAvailable = !this->PythonErrorOccured();
938 
939  return m_OpenCVWrappingAvailable;
940 }
941 
943 {
944  this->Execute( "import vtk", IPythonService::SINGLE_LINE_COMMAND );
945  //this->Execute( "print \"Using VTK version \" + vtk.vtkVersion.GetVTKVersion()\n", IPythonService::SINGLE_LINE_COMMAND );
946  m_VtkWrappingAvailable = !this->PythonErrorOccured();
947 
948  return m_VtkWrappingAvailable;
949 }
950 
952 {
953  return m_ErrorOccured;
954 }
955 
const Point3D GetOrigin() const
Get the origin, e.g. the upper-left corner of the plane.
Class for storing surfaces (vtkPolyData).
Definition: mitkSurface.h:32
bool DoesVariableExist(const std::string &name) const
itk::SmartPointer< Self > Pointer
bool CopyToPythonAsVtkPolyData(mitk::Surface *surface, const std::string &varName)
#define MITK_ERROR
Definition: mitkLogMacros.h:24
virtual vtkPolyData * GetVtkPolyData(unsigned int t=0) const
ctkAbstractPythonManager * GetPythonManager()
mitk::Surface::Pointer CopyVtkPolyDataFromPython(const std::string &varName)
#define MITK_DEBUG
Definition: mitkLogMacros.h:26
const void * GetData() const
Gives const access to the data.
const mitk::Vector3D GetSpacing() const
Get the spacing (size of a pixel).
itk::ImageIOBase::IOPixelType GetPixelType() const
void * GetData()
Gives full data access.
static const int MULTI_LINE_COMMAND
void RemovePythonCommandObserver(PythonCommandObserver *observer)
void NotifyObserver(const std::string &command)
void FillVector3D(Tout &out, mitk::ScalarType x, mitk::ScalarType y, mitk::ScalarType z)
Definition: mitkArray.h:110
bool PythonErrorOccured() const
vcl_size_t GetSize() const
Get size of the PixelType in bytes.
std::string Execute(const std::string &pythonCommand, int commandType=SINGLE_LINE_COMMAND)
unsigned int * GetDimensions() const
Get the sizes of all dimensions as an integer-array.
Definition: mitkImage.cpp:1308
#define MITK_WARN
Definition: mitkLogMacros.h:23
std::vector< PythonVariable > GetVariableStack() const
static const int SINGLE_LINE_COMMAND
bool CopyToPythonAsSimpleItkImage(mitk::Image *image, const std::string &varName)
#define mitkThrow()
Image class for storing images.
Definition: mitkImage.h:76
~PythonService()
empty implementation...
mitk::Image::Pointer CopyCvImageFromPython(const std::string &varName)
bool CopyToPythonAsCvImage(mitk::Image *image, const std::string &varName)
int GetComponentType() const
Get the component type (the scalar (!) type). Each element may contain m_NumberOfComponents (more tha...
const mitk::PixelType GetPixelType(int n=0) const
Returns the PixelType of channel n.
Definition: mitkImage.cpp:105
QString GetTempDataFileName(const std::string &ext) const
static Pointer New()
mitk::PixelType DeterminePixelType(const std::string &pythonPixeltype, int nrComponents, int dimensions)
static std::string GetProgramPath()
Definition: mitkIOUtil.cpp:350
vcl_size_t GetNumberOfComponents() const
Get the number of components of which each element consists.
ImageWriteAccessor class to get locked write-access for a particular image part.
static const int EVAL_COMMAND
ImageReadAccessor class to get locked read access for a particular image part.
mitk::BaseGeometry * GetGeometry(int t=0) const
Return the geometry, which is a TimeGeometry, of the data as non-const pointer.
Definition: mitkBaseData.h:129
void ExecuteScript(const std::string &pathToPythonScript)
mitk::Image::Pointer CopySimpleItkImageFromPython(const std::string &varName)
PythonService()
instantiate python manager here
static Pointer New()
Class for defining the data type of pixels.
Definition: mitkPixelType.h:55
mitk::AffineTransform3D * GetIndexToWorldTransform()
Get the transformation used to convert from index to world coordinates.
void AddPythonCommandObserver(PythonCommandObserver *observer)