Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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)