예제 #1
0
bool mitk::PythonService::CopyToPythonAsCvImage( mitk::Image* image, const std::string& stdvarName )
{
  QString varName = QString::fromStdString( stdvarName );
  QString command;
  unsigned int* imgDim = image->GetDimensions();
  int npy_nd = 1;

  // access python module
  PyObject *pyMod = PyImport_AddModule((char*)"__main__");
  // global dictionary
  PyObject *pyDict = PyModule_GetDict(pyMod);
  mitk::PixelType pixelType = image->GetPixelType();
  PyObject* npyArray = nullptr;
  mitk::ImageReadAccessor racc(image);
  void* array = (void*) racc.GetData();

  // save the total number of elements here (since the numpy array is one dimensional)
  npy_intp* npy_dims = new npy_intp[1];
  npy_dims[0] = imgDim[0];

  /**
   * Build a string in the format [1024,1028,1]
   * to describe the dimensionality. This is needed for simple itk
   * to know the dimensions of the image
   */
  QString dimensionString;
  dimensionString.append(QString("["));
  dimensionString.append(QString::number(imgDim[0]));
  // ToDo: check if we need this
  for (unsigned i = 1; i < 3; ++i)
    // always three because otherwise the 3d-geometry gets destroyed
    // (relevant for backtransformation of simple itk image to mitk.
  {
    dimensionString.append(QString(","));
    dimensionString.append(QString::number(imgDim[i]));
    npy_dims[0] *= imgDim[i];
  }
  dimensionString.append("]");


  // the next line is necessary for vectorimages
  npy_dims[0] *= pixelType.GetNumberOfComponents();

  // default pixeltype: unsigned short
  NPY_TYPES npy_type  = NPY_USHORT;
  if( pixelType.GetComponentType() == itk::ImageIOBase::DOUBLE ) {
    npy_type = NPY_DOUBLE;
  } else if( pixelType.GetComponentType() == itk::ImageIOBase::FLOAT ) {
    npy_type = NPY_FLOAT;
  } else if( pixelType.GetComponentType() == itk::ImageIOBase::SHORT) {
    npy_type = NPY_SHORT;
  } else if( pixelType.GetComponentType() == itk::ImageIOBase::CHAR ) {
    npy_type = NPY_BYTE;
  } else if( pixelType.GetComponentType() == itk::ImageIOBase::INT ) {
    npy_type = NPY_INT;
  } else if( pixelType.GetComponentType() == itk::ImageIOBase::LONG ) {
    npy_type = NPY_LONG;
  } else if( pixelType.GetComponentType() == itk::ImageIOBase::UCHAR ) {
    npy_type = NPY_UBYTE;
  } else if( pixelType.GetComponentType() == itk::ImageIOBase::UINT ) {
    npy_type = NPY_UINT;
  } else if( pixelType.GetComponentType() == itk::ImageIOBase::ULONG ) {
    npy_type = NPY_LONG;
  } else if( pixelType.GetComponentType() == itk::ImageIOBase::USHORT ) {
    npy_type = NPY_USHORT;
  }
  else {
    MITK_WARN << "not a recognized pixeltype";
    return false;
  }

  // creating numpy array
  import_array1 (true);
  npyArray = PyArray_SimpleNewFromData(npy_nd,npy_dims,npy_type,array);

  // add temp array it to the python dictionary to access it in python code
  const int status = PyDict_SetItemString( pyDict,QString("%1_numpy_array")
      .arg(varName).toStdString().c_str(),
      npyArray );
  // sanity check
  if ( status != 0 )
    return false;

  command.append( QString("import numpy as np\n"));
  //command.append( QString("if '%1' in globals():\n").arg(varName));
  //command.append( QString("  del %1\n").arg(varName));
  command.append( QString("%1_array_tmp=%1_numpy_array.copy()\n").arg(varName));
  command.append( QString("%1_array_tmp=%1_array_tmp.reshape(%2,%3,%4)\n").arg( varName,
      QString::number(imgDim[1]),
      QString::number(imgDim[0]),
      QString::number(pixelType.GetNumberOfComponents())));

  command.append( QString("%1 = %1_array_tmp[:,...,::-1]\n").arg(varName));
  command.append( QString("del %1_numpy_array\n").arg(varName) );
  command.append( QString("del %1_array_tmp").arg(varName) );

  MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();

  this->Execute( command.toStdString(), IPythonService::MULTI_LINE_COMMAND );

  return true;
}
bool mitk::PythonService::CopyToPythonAsSimpleItkImage(mitk::Image *image, const std::string &stdvarName)
{
  QString varName = QString::fromStdString( stdvarName );
  QString command;
  unsigned int* imgDim = image->GetDimensions();
  int npy_nd = 1;
  npy_intp* npy_dims = new npy_intp[1];
  npy_dims[0] = imgDim[0] * imgDim[1] * imgDim[2];
  // access python module
  PyObject *pyMod = PyImport_AddModule((char*)"__main__");
  // global dictionarry
  PyObject *pyDict = PyModule_GetDict(pyMod);
  const mitk::Vector3D spacing = image->GetGeometry()->GetSpacing();
  const mitk::Point3D origin = image->GetGeometry()->GetOrigin();
  mitk::PixelType pixelType = image->GetPixelType();
  itk::ImageIOBase::IOPixelType ioPixelType = image->GetPixelType().GetPixelType();
  PyObject* npyArray = NULL;
  mitk::ImageReadAccessor racc(image);
  void* array = (void*) racc.GetData();

  // default pixeltype: unsigned short
  NPY_TYPES npy_type  = NPY_USHORT;
  std::string sitk_type = "sitkUInt8";
  if( ioPixelType == itk::ImageIOBase::SCALAR )
  {
    if( pixelType.GetComponentType() == itk::ImageIOBase::DOUBLE ) {
      npy_type = NPY_DOUBLE;
      sitk_type = "sitkFloat64";
    } else if( pixelType.GetComponentType() == itk::ImageIOBase::FLOAT ) {
      npy_type = NPY_FLOAT;
      sitk_type = "sitkFloat32";
    } else if( pixelType.GetComponentType() == itk::ImageIOBase::SHORT) {
      npy_type = NPY_SHORT;
      sitk_type = "sitkInt16";
    } else if( pixelType.GetComponentType() == itk::ImageIOBase::CHAR ) {
      npy_type = NPY_BYTE;
      sitk_type = "sitkInt8";
    } else if( pixelType.GetComponentType() == itk::ImageIOBase::INT ) {
      npy_type = NPY_INT;
      sitk_type = "sitkInt32";
    } else if( pixelType.GetComponentType() == itk::ImageIOBase::LONG ) {
      npy_type = NPY_LONG;
      sitk_type = "sitkInt64";
    } else if( pixelType.GetComponentType() == itk::ImageIOBase::UCHAR ) {
      npy_type = NPY_UBYTE;
      sitk_type = "sitkUInt8";
    } else if( pixelType.GetComponentType() == itk::ImageIOBase::UINT ) {
      npy_type = NPY_UINT;
      sitk_type = "sitkUInt32";
    } else if( pixelType.GetComponentType() == itk::ImageIOBase::ULONG ) {
      npy_type = NPY_LONG;
      sitk_type = "sitkUInt64";
    } else if( pixelType.GetComponentType() == itk::ImageIOBase::USHORT ) {
      npy_type = NPY_USHORT;
      sitk_type = "sitkUInt16";
    }
  } else {
    MITK_WARN << "not a scalar pixeltype";
    return false;
  }

  // creating numpy array
  import_array1 (true);
  npyArray = PyArray_SimpleNewFromData(npy_nd,npy_dims,npy_type,array);

  // add temp array it to the python dictionary to access it in python code
  const int status = PyDict_SetItemString( pyDict,QString("%1_numpy_array")
                                           .arg(varName).toStdString().c_str(),
                                           npyArray );

  // sanity check
  if ( status != 0 )
    return false;

  command.append( QString("%1 = sitk.Image(%2,%3,%4,sitk.%5)\n").arg(varName)
                  .arg(QString::number(imgDim[0]))
                  .arg(QString::number(imgDim[1]))
                  .arg(QString::number(imgDim[2]))
                  .arg(QString(sitk_type.c_str())) );
  command.append( QString("%1.SetSpacing([%2,%3,%4])\n").arg(varName)
                  .arg(QString::number(spacing[0]))
                  .arg(QString::number(spacing[1]))
                  .arg(QString::number(spacing[2])) );
  command.append( QString("%1.SetOrigin([%2,%3,%4])\n").arg(varName)
                  .arg(QString::number(origin[0]))
                  .arg(QString::number(origin[1]))
                  .arg(QString::number(origin[2])) );
  // directly access the cpp api from the lib
  command.append( QString("_SimpleITK._SetImageFromArray(%1_numpy_array,%1)\n").arg(varName) );
  command.append( QString("del %1_numpy_array").arg(varName) );

  MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
  this->Execute( command.toStdString(), IPythonService::MULTI_LINE_COMMAND );

  return true;
}
예제 #3
0
bool mitk::PythonService::CopyToPythonAsSimpleItkImage(mitk::Image *image, const std::string &stdvarName)
{
  QString varName = QString::fromStdString( stdvarName );
  QString command;
  unsigned int* imgDim = image->GetDimensions();
  int npy_nd = 1;

  // access python module
  PyObject *pyMod = PyImport_AddModule((char*)"__main__");
  // global dictionary
  PyObject *pyDict = PyModule_GetDict(pyMod);
  const mitk::Vector3D spacing = image->GetGeometry()->GetSpacing();
  const mitk::Point3D origin = image->GetGeometry()->GetOrigin();
  mitk::PixelType pixelType = image->GetPixelType();
  itk::ImageIOBase::IOPixelType ioPixelType = image->GetPixelType().GetPixelType();
  PyObject* npyArray = nullptr;
  mitk::ImageReadAccessor racc(image);
  void* array = (void*) racc.GetData();

  mitk::Vector3D xDirection;
  mitk::Vector3D yDirection;
  mitk::Vector3D zDirection;
  const vnl_matrix_fixed<ScalarType, 3, 3> &transform =
      image->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix();

  mitk::Vector3D s = image->GetGeometry()->GetSpacing();

  // ToDo: Check if this is a collumn or row vector from the matrix.
  // right now it works but not sure for rotated geometries
  mitk::FillVector3D(xDirection, transform[0][0]/s[0], transform[0][1]/s[1], transform[0][2]/s[2]);
  mitk::FillVector3D(yDirection, transform[1][0]/s[0], transform[1][1]/s[1], transform[1][2]/s[2]);
  mitk::FillVector3D(zDirection, transform[2][0]/s[0], transform[2][1]/s[1], transform[2][2]/s[2]);

  // save the total number of elements here (since the numpy array is one dimensional)
  npy_intp* npy_dims = new npy_intp[1];
  npy_dims[0] = imgDim[0];

  /**
   * Build a string in the format [1024,1028,1]
   * to describe the dimensionality. This is needed for simple itk
   * to know the dimensions of the image
   */
  QString dimensionString;
  dimensionString.append(QString("["));
  dimensionString.append(QString::number(imgDim[0]));
  for (unsigned i = 1; i < 3; ++i)
    // always three because otherwise the 3d-geometry gets destroyed
    // (relevant for backtransformation of simple itk image to mitk.
  {
    dimensionString.append(QString(","));
    dimensionString.append(QString::number(imgDim[i]));
    npy_dims[0] *= imgDim[i];
  }
  dimensionString.append("]");


  // the next line is necessary for vectorimages
  npy_dims[0] *= pixelType.GetNumberOfComponents();

  // default pixeltype: unsigned short
  NPY_TYPES npy_type  = NPY_USHORT;
  std::string sitk_type = "sitkUInt8";
  if( ioPixelType == itk::ImageIOBase::SCALAR )
  {
    if( pixelType.GetComponentType() == itk::ImageIOBase::DOUBLE ) {
      npy_type = NPY_DOUBLE;
      sitk_type = "sitkFloat64";
    } else if( pixelType.GetComponentType() == itk::ImageIOBase::FLOAT ) {
      npy_type = NPY_FLOAT;
      sitk_type = "sitkFloat32";
    } else if( pixelType.GetComponentType() == itk::ImageIOBase::SHORT) {
      npy_type = NPY_SHORT;
      sitk_type = "sitkInt16";
    } else if( pixelType.GetComponentType() == itk::ImageIOBase::CHAR ) {
      npy_type = NPY_BYTE;
      sitk_type = "sitkInt8";
    } else if( pixelType.GetComponentType() == itk::ImageIOBase::INT ) {
      npy_type = NPY_INT;
      sitk_type = "sitkInt32";
    } else if( pixelType.GetComponentType() == itk::ImageIOBase::LONG ) {
      npy_type = NPY_LONG;
      sitk_type = "sitkInt64";
    } else if( pixelType.GetComponentType() == itk::ImageIOBase::UCHAR ) {
      npy_type = NPY_UBYTE;
      sitk_type = "sitkUInt8";
    } else if( pixelType.GetComponentType() == itk::ImageIOBase::UINT ) {
      npy_type = NPY_UINT;
      sitk_type = "sitkUInt32";
    } else if( pixelType.GetComponentType() == itk::ImageIOBase::ULONG ) {
      npy_type = NPY_LONG;
      sitk_type = "sitkUInt64";
    } else if( pixelType.GetComponentType() == itk::ImageIOBase::USHORT ) {
      npy_type = NPY_USHORT;
      sitk_type = "sitkUInt16";
    }
  }
  else if ( ioPixelType == itk::ImageIOBase::VECTOR ||
      ioPixelType == itk::ImageIOBase::RGB ||
      ioPixelType == itk::ImageIOBase::RGBA
  )
  {
    if( pixelType.GetComponentType() == itk::ImageIOBase::DOUBLE ) {
      npy_type = NPY_DOUBLE;
      sitk_type = "sitkVectorFloat64";
    } else if( pixelType.GetComponentType() == itk::ImageIOBase::FLOAT ) {
      npy_type = NPY_FLOAT;
      sitk_type = "sitkVectorFloat32";
    } else if( pixelType.GetComponentType() == itk::ImageIOBase::SHORT) {
      npy_type = NPY_SHORT;
      sitk_type = "sitkVectorInt16";
    } else if( pixelType.GetComponentType() == itk::ImageIOBase::CHAR ) {
      npy_type = NPY_BYTE;
      sitk_type = "sitkVectorInt8";
    } else if( pixelType.GetComponentType() == itk::ImageIOBase::INT ) {
      npy_type = NPY_INT;
      sitk_type = "sitkVectorInt32";
    } else if( pixelType.GetComponentType() == itk::ImageIOBase::LONG ) {
      npy_type = NPY_LONG;
      sitk_type = "sitkVectorInt64";
    } else if( pixelType.GetComponentType() == itk::ImageIOBase::UCHAR ) {
      npy_type = NPY_UBYTE;
      sitk_type = "sitkVectorUInt8";
    } else if( pixelType.GetComponentType() == itk::ImageIOBase::UINT ) {
      npy_type = NPY_UINT;
      sitk_type = "sitkVectorUInt32";
    } else if( pixelType.GetComponentType() == itk::ImageIOBase::ULONG ) {
      npy_type = NPY_LONG;
      sitk_type = "sitkVectorUInt64";
    } else if( pixelType.GetComponentType() == itk::ImageIOBase::USHORT ) {
      npy_type = NPY_USHORT;
      sitk_type = "sitkVectorUInt16";
    }
  }
  else {
    MITK_WARN << "not a recognized pixeltype";
    return false;
  }

  // creating numpy array
  import_array1 (true);
  npyArray = PyArray_SimpleNewFromData(npy_nd,npy_dims,npy_type,array);

  // add temp array it to the python dictionary to access it in python code
  const int status = PyDict_SetItemString( pyDict,QString("%1_numpy_array")
      .arg(varName).toStdString().c_str(),
      npyArray );


  // sanity check
  if ( status != 0 )
    return false;


  command.append( QString("%1 = sitk.Image(%2,sitk.%3,%4)\n").arg(varName)
      .arg(dimensionString)
      .arg(QString(sitk_type.c_str())).arg(QString::number(pixelType.GetNumberOfComponents())) );
  command.append( QString("%1.SetSpacing([%2,%3,%4])\n").arg(varName)
      .arg(QString::number(spacing[0]))
      .arg(QString::number(spacing[1]))
      .arg(QString::number(spacing[2])) );
  command.append( QString("%1.SetOrigin([%2,%3,%4])\n").arg(varName)
      .arg(QString::number(origin[0]))
      .arg(QString::number(origin[1]))
      .arg(QString::number(origin[2])) );
  command.append( QString("%1.SetDirection([%2,%3,%4,%5,%6,%7,%8,%9,%10])\n").arg(varName)
      .arg(QString::number(xDirection[0]))
      .arg(QString::number(xDirection[1]))
      .arg(QString::number(xDirection[2]))
      .arg(QString::number(yDirection[0]))
      .arg(QString::number(yDirection[1]))
      .arg(QString::number(yDirection[2]))
      .arg(QString::number(zDirection[0]))
      .arg(QString::number(zDirection[1]))
      .arg(QString::number(zDirection[2]))
  );
  // directly access the cpp api from the lib
  command.append( QString("_SimpleITK._SetImageFromArray(%1_numpy_array,%1)\n").arg(varName) );
  command.append( QString("del %1_numpy_array").arg(varName) );

  MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();


  this->Execute( command.toStdString(), IPythonService::MULTI_LINE_COMMAND );

  return true;
}
예제 #4
0
int main(int argc,char *argv[])
{
    Timer* timer=new Timer("make array");
    
    Partio::ParticlesDataMutable& foo=*Partio::create();
    int nParticles=10000000;
    foo.addParticles(nParticles);
    Partio::ParticleAttribute position=foo.addAttribute("position",Partio::VECTOR,3);
    Partio::ParticleAttribute radius=foo.addAttribute("radius",Partio::FLOAT,1);
    Partio::ParticleAttribute life=foo.addAttribute("life",Partio::FLOAT,2);
    delete timer;

    {

        Timer timer("write data");
        for(int i=0;i<nParticles;i++){
            float* pos=foo.dataWrite<float>(position,i);
            float* rad=foo.dataWrite<float>(radius,i);
            float* lifeVal=foo.dataWrite<float>(life,i);
            pos[0]=i;pos[1]=2*i;pos[2]=3*i;
            rad[0]=.1*i;
            lifeVal[0]=.01*i;
            lifeVal[1]=1.;
            //std::cerr<<"writing data "<<pos[0]<<" "<<pos[1]<<" "<<pos[2]<<std::endl;
        }
    }

    int i=0;
    Partio::ParticlesDataMutable::iterator it=foo.begin();
    Partio::ParticleAccessor Xacc(position);
    it.addAccessor(Xacc);
    for(;it!=foo.end();++it){
        Partio::Data<float,3>& X=Xacc.data<Partio::Data<float,3> >(it);
//        Partio::Data<float,3>& X=it.data<Partio::Data<float,3> >(position);
        //const Partio::Data<float,1>& r=it.data<Partio::Data<float,1> >(radius);
        //const Partio::Data<float,2>& l=it.data<Partio::Data<float,2> >(life);
        
//        std::cerr<<"write guy X="<<X<<std::endl; // " life="<<l<<" radius="<<r<<std::endl;
        X[1]+=.1*i;// 100.;
        i++;
    }
    std::vector<double> iteratorTimes,handTimes,rawTimes;
    for(int i=0;i<10;i++){

        {
            Timer timer("Access and sum with iterator");
            
            Partio::ParticlesData& fooc=foo;
            float sum=0;
            Partio::ParticlesDataMutable::const_iterator it=fooc.begin();
            Partio::ParticleAccessor Xacc(position);
            Partio::ParticleAccessor racc(radius);
            Partio::ParticleAccessor lacc(life);
            it.addAccessor(Xacc);
            it.addAccessor(racc);
            it.addAccessor(lacc);
            
            for(;it!=fooc.end();++it){
                const Partio::Data<float,3>& X=Xacc.data<Partio::Data<float,3> >(it);
                const Partio::Data<float,1>& r=racc.data<Partio::Data<float,1> >(it);
                const Partio::Data<float,2>& l=lacc.data<Partio::Data<float,2> >(it);
                
//                std::cerr<<"guy X="<<X[0]<<" "<<X[1]<<" "<<X[2]<<" life="<<l<<" radius="<<r<<std::endl;
                sum+= X[0]+r[0]+l[0];
            }
            std::cerr<<"sum is "<<sum<<std::endl;
            iteratorTimes.push_back( timer.Stop_Time());
        }
    
        {
            Timer timer("Access and sum by hand");
            
            Partio::ParticlesData& fooc=foo;
            float sum=0;
            for(uint64_t i=0;i<(uint64_t)fooc.numParticles();i++){
                const float* X=fooc.data<float>(position,i);
                const float* r=fooc.data<float>(radius,i);
                const float* l=fooc.data<float>(life,i);
                
//                std::cerr<<"guy X="<<X[0]<<" "<<X[1]<<" "<<X[2]<<" life="<<l<<" radius="<<r<<std::endl;
                sum+= X[0]+r[0]+l[0];
            }
            std::cerr<<"sum is "<<sum<<std::endl;
           
            handTimes.push_back( timer.Stop_Time());

        }

        // NOTE: this is using direct access and assuming ParticlesSimple (non-interleaved data)
        // This is not what you should ever do, and is not guaranteed to work under any stretch of the imagination.
        // I am only doing it here to see what I'm losing in iteration.
        {
            Timer timer("Access and sum raw");
            std::string fooType=typeid(foo).name();
            if(fooType.find("ParticlesSimple")==std::string::npos){
                std::cerr<<"You are using the wrong particle type for this test it must be ParticlesSimple"<<std::endl;
                exit(1);
            }
            Partio::ParticlesData& fooc=foo;
            int nParts=fooc.numParticles();
            float sum=0;
            const float* X=fooc.data<float>(position,0);
            const float* r=fooc.data<float>(radius,0);
            const float* l=fooc.data<float>(life,0);
            for(int i=0;i<nParts;i++){
                //std::cout<<i<<std::endl;
                //sum+= X[0]+X[3]+X[4];
                sum+= X[0]+r[0]+l[0];
                X+=3;
                r++;
                l+=2;
            }
            std::cerr<<"sum is "<<sum<<std::endl;
           
            rawTimes.push_back( timer.Stop_Time());

        }
    }

    double avgHand=0,avgIterator=0,raw=0;
    for(unsigned int i=0;i<handTimes.size();i++){
        avgHand+=handTimes[i];
        avgIterator+=iteratorTimes[i];
        raw+=rawTimes[i];
    }
    avgIterator/=handTimes.size();
    avgHand/=handTimes.size();
    raw/=handTimes.size();
    float megs=nParticles*20./float(1<<20);
    std::cerr<<megs<<" MB"<<std::endl;
    std::cerr<<"Iterator "<<avgIterator<<" s "<<megs/avgIterator<<" MB/s"<<std::endl;
    std::cerr<<"Hand "<<avgHand<<" s "<<megs/avgHand<<" MB/s"<<std::endl;
    std::cerr<<"Raw "<<raw<<" s "<<megs/raw<<" MB/s"<<std::endl;

    return 0;

}