void otb::Wrapper::ObjectsRadiometricStatistics::DoExecute()
{
	VectorImageType::Pointer referenceImage = GetParameterImage("im");

	otb::ogr::DataSource::Pointer ogrDS;
	ogrDS = otb::ogr::DataSource::New(GetParameterString("in"), otb::ogr::DataSource::Modes::Update_LayerUpdate);

	m_OGRDataSourceRendering = OGRDataSourceToMapFilterType::New();
	m_OGRDataSourceRendering->AddOGRDataSource(ogrDS);

	m_OGRDataSourceRendering->SetOutputSize(referenceImage->GetLargestPossibleRegion().GetSize());
	m_OGRDataSourceRendering->SetOutputOrigin(referenceImage->GetOrigin());

	m_OGRDataSourceRendering->SetOutputSpacing(referenceImage->GetSpacing());

	m_OGRDataSourceRendering->SetOutputProjectionRef(referenceImage->GetProjectionRef());

	//	m_OGRDataSourceRendering->SetOutputParametersFromImage(referenceImage); // A tester

	m_OGRDataSourceRendering->SetBackgroundValue(GetParameterInt("background"));
	m_OGRDataSourceRendering->SetBurnAttributeMode(true);
	m_OGRDataSourceRendering->SetBurnAttribute(GetParameterString("field"));

	// Write label image from OGR
	/*
	   WriterType::Pointer writer = WriterType::New(); 
	   writer->SetInput(m_OGRDataSourceRendering->GetOutput());	
	   writer->SetFileName("label_image.tif");
	   writer->Update();
	 */

	// Label image from OGR to statistics label map
	ConverterStatisticsType::Pointer converterStats = ConverterStatisticsType::New(); 
	converterStats->SetInput(m_OGRDataSourceRendering->GetOutput()); 
	converterStats->SetBackgroundValue(GetParameterInt("background")); 
	converterStats->Update();

	// Prepare channel extraction

	ExtractROIFilterType::Pointer m_ExtractROIFilter = ExtractROIFilterType::New();
	m_ExtractROIFilter->SetInput(referenceImage);

	// Update dataset with new fields

	otb::ogr::Layer layer = ogrDS->GetLayerChecked(0);

	OGRFieldDefn fieldNbPixels("NbPixels", OFTInteger);
	layer.CreateField(fieldNbPixels, true);

	OGRFieldDefn fieldFlatness("Flat", OFTReal);
	layer.CreateField(fieldFlatness, true);

	OGRFieldDefn fieldRoundness("Round", OFTReal);
	layer.CreateField(fieldRoundness, true);

	OGRFieldDefn fieldElongation("Elong", OFTReal);
	layer.CreateField(fieldElongation, true);

	OGRFieldDefn fieldPerimeter("Perim", OFTReal);
	layer.CreateField(fieldPerimeter, true);

	for(unsigned int i = 0; i < referenceImage->GetNumberOfComponentsPerPixel(); i++)
	{
		std::ostringstream fieldoss;
		fieldoss<<"meanB"<<i+1;
		OGRFieldDefn field(fieldoss.str().c_str(), OFTReal);
		layer.CreateField(field, true);
	}

	for(unsigned int i = 0; i < referenceImage->GetNumberOfComponentsPerPixel(); i++)
	{
		std::ostringstream fieldoss;
		fieldoss<<"stdB"<<i+1;
		OGRFieldDefn field(fieldoss.str().c_str(), OFTReal);
		layer.CreateField(field, true);
	}

	for(unsigned int i = 0; i < referenceImage->GetNumberOfComponentsPerPixel(); i++)
	{
		std::ostringstream fieldoss;
		fieldoss<<"MedB"<<i+1;
		OGRFieldDefn field(fieldoss.str().c_str(), OFTReal);
		layer.CreateField(field, true);
	}

	for(unsigned int i = 0; i < referenceImage->GetNumberOfComponentsPerPixel(); i++)
	{
		std::ostringstream fieldoss;
		fieldoss<<"VarB"<<i+1;
		OGRFieldDefn field(fieldoss.str().c_str(), OFTReal);
		layer.CreateField(field, true);
	}

	for(unsigned int i = 0; i < referenceImage->GetNumberOfComponentsPerPixel(); i++)
	{
		std::ostringstream fieldoss;
		fieldoss<<"KurtB"<<i+1;
		OGRFieldDefn field(fieldoss.str().c_str(), OFTReal);
		layer.CreateField(field, true);
	}

	for(unsigned int i = 0; i < referenceImage->GetNumberOfComponentsPerPixel(); i++)
	{
		std::ostringstream fieldoss;
		fieldoss<<"SkewB"<<i+1;
		OGRFieldDefn field(fieldoss.str().c_str(), OFTReal);
		layer.CreateField(field, true);
	}

	for(unsigned int i = 0; i < referenceImage->GetNumberOfComponentsPerPixel(); i++)
	{
		// Channel selection

		m_ExtractROIFilter->SetChannel(i + 1);

		// Statistics computation
		StatisticsFilterType::Pointer statistics = StatisticsFilterType::New(); 
		statistics->SetInput(converterStats->GetOutput());
		statistics->SetFeatureImage(m_ExtractROIFilter->GetOutput());
		statistics->SetComputePerimeter(true);
		statistics->Update();

		// Write shape attributes only one time
		if(i==0)
		{
			for(otb::ogr::Layer::iterator featIt = layer.begin(); featIt!=layer.end(); ++featIt)
			{
				otb::ogr::Feature m_Feature = *featIt;

				unsigned int label = m_Feature.ogr().GetFieldAsInteger(layer.GetLayerDefn().GetFieldIndex(GetParameterString("field").c_str()));

				if(statistics->GetOutput()->HasLabel(label))
				{
					const StatisticsLabelObjectType *labelObjectStats = statistics->GetOutput()->GetLabelObject(label);

					m_Feature.ogr().SetField("NbPixels", (int)labelObjectStats->GetNumberOfPixels());
					m_Feature.ogr().SetField("Flat", labelObjectStats->GetFlatness());
					m_Feature.ogr().SetField("Round", labelObjectStats->GetRoundness());
					m_Feature.ogr().SetField("Elong", labelObjectStats->GetElongation());
					m_Feature.ogr().SetField("Perim", labelObjectStats->GetPerimeter());

					layer.SetFeature(m_Feature);
				}
			}	
		}

		// Features iteration
		for(otb::ogr::Layer::iterator featIt = layer.begin(); featIt!=layer.end(); ++featIt)
		{
			otb::ogr::Feature m_Feature = *featIt;

			unsigned int label = m_Feature.ogr().GetFieldAsInteger(layer.GetLayerDefn().GetFieldIndex(GetParameterString("field").c_str()));

			if(statistics->GetOutput()->HasLabel(label))
			{
				const StatisticsLabelObjectType *labelObjectStats = statistics->GetOutput()->GetLabelObject(label);
				std::ostringstream fieldoss;

				fieldoss<<"meanB"<<i+1;
				m_Feature.ogr().SetField(fieldoss.str().c_str(),labelObjectStats->GetMean());
				fieldoss.str("");	

				fieldoss<<"stdB"<<i+1;
				m_Feature.ogr().SetField(fieldoss.str().c_str(),labelObjectStats->GetStandardDeviation());
				fieldoss.str("");

				fieldoss<<"medB"<<i+1;
				m_Feature.ogr().SetField(fieldoss.str().c_str(),labelObjectStats->GetMedian());
				fieldoss.str("");	

				fieldoss<<"varB"<<i+1;
				m_Feature.ogr().SetField(fieldoss.str().c_str(),labelObjectStats->GetVariance());
				fieldoss.str("");	

				fieldoss<<"kurtB"<<i+1;
				m_Feature.ogr().SetField(fieldoss.str().c_str(),labelObjectStats->GetKurtosis());
				fieldoss.str("");	

				fieldoss<<"skewB"<<i+1;
				m_Feature.ogr().SetField(fieldoss.str().c_str(),labelObjectStats->GetSkewness());
				fieldoss.str("");	
			}
			else
			{
				otbAppLogINFO( << "Object number " << label << " is skipped. This could happen during the rasterisation process when an object is smaller than 1 pixel.");
			}
		}
	}
}
bool itkDataTensorImageReaderBase::read (const QString &path)
{
    if (this->io.IsNull())
        return false;
	
    this->readInformation ( path );
	
    qDebug() << "Read with: " << this->identifier();

    if (medAbstractData *medData = dynamic_cast<medAbstractData*>(this->data()) ) {
      
        if (medData->identifier()=="itkDataTensorImageDouble3") {

	  if (this->io->GetNumberOfComponents()==6) {

	    typedef itk::Tensor<double, 3>    TensorType;
	    typedef itk::Image<TensorType, 3> TensorImageType;

	    typedef itk::Vector<double, 6>    VectorType;
	    typedef itk::Image<VectorType, 3> VectorImageType;

	    typedef itk::ImageFileReader<VectorImageType> ReaderType;
	    
	    VectorImageType::Pointer image = 0;
	    {
	      ReaderType::Pointer reader = ReaderType::New();
	      reader->SetImageIO (this->io);
	      reader->SetFileName ( path.toAscii().constData() );
	      try {
		reader->Update();
	      }
	      catch (itk::ExceptionObject &e) {
		qDebug() << e.GetDescription();
		return false;
	      }
	      image = reader->GetOutput(); 
	    }

	    TensorImageType::Pointer tensors = TensorImageType::New();
	    TensorImageType::RegionType region = image->GetLargestPossibleRegion();
	    tensors->SetRegions   (region);
	    tensors->SetSpacing   (image->GetSpacing());
	    tensors->SetOrigin    (image->GetOrigin());
	    tensors->SetDirection (image->GetDirection());

	    try {
	        tensors->Allocate();
	    }
	    catch (itk::ExceptionObject &e) {
	        qDebug() << e.GetDescription();
		return false;
	    }

	    itk::ImageRegionConstIteratorWithIndex<VectorImageType>  itIn (image,
									   image->GetLargestPossibleRegion());
	    itk::ImageRegionIteratorWithIndex<TensorImageType> itOut(tensors,
								     tensors->GetLargestPossibleRegion());

	    while(!itOut.IsAtEnd()) {
      
	      VectorType vec = itIn.Get();
	      TensorType tensor;
	      
	      for( unsigned int j=0; j<6; j++) {
		tensor[j] = vec[j];
	      }
      
	      itOut.Set (tensor);
	      
	      ++itOut;
	      ++itIn;
	    }

	    medData->setData (tensors);
	    
	  }
	  else if (this->io->GetNumberOfComponents()==9) {

	    typedef itk::Tensor<double, 3>    TensorType;
	    typedef itk::Image<TensorType, 3> TensorImageType;

	    typedef itk::Vector<double, 9>    VectorType;
	    typedef itk::Image<VectorType, 3> VectorImageType;

	    typedef itk::ImageFileReader<VectorImageType> ReaderType;
	    
	    VectorImageType::Pointer image = 0;
	    {
	      ReaderType::Pointer reader = ReaderType::New();
	      reader->SetImageIO (this->io);
	      reader->SetFileName ( path.toAscii().constData() );
	      try {
		reader->Update();
	      }
	      catch (itk::ExceptionObject &e) {
		qDebug() << e.GetDescription();
		return false;
	      }
	      image = reader->GetOutput(); 
	    }

	    TensorImageType::Pointer tensors = TensorImageType::New();
	    TensorImageType::RegionType region = image->GetLargestPossibleRegion();
	    tensors->SetRegions   (region);
	    tensors->SetSpacing   (image->GetSpacing());
	    tensors->SetOrigin    (image->GetOrigin());
	    tensors->SetDirection (image->GetDirection());

	    try {
	        tensors->Allocate();
	    }
	    catch (itk::ExceptionObject &e) {
	        qDebug() << e.GetDescription();
		return false;
	    }

	    itk::ImageRegionConstIteratorWithIndex<VectorImageType>  itIn (image,
									   image->GetLargestPossibleRegion());
	    itk::ImageRegionIteratorWithIndex<TensorImageType> itOut(tensors,
								     tensors->GetLargestPossibleRegion());

	    while(!itOut.IsAtEnd()) {
      
	      VectorType vec = itIn.Get();
	      TensorType tensor;
	      
	      for (unsigned int i=0; i<3; i++)
		for (unsigned int j=0; j<3; j++)
		  tensor.SetComponent (i, j, vec[i*3+j]);
      
	      itOut.Set (tensor);
	      
	      ++itOut;
	      ++itIn;
	    }

	    medData->setData (tensors);
	  }
	  else {
	      qDebug() << "Unsupported number of components";
	      return false;
	  } 
	}

	else if (medData->identifier()=="itkDataTensorImageFloat3") {

	  if (this->io->GetNumberOfComponents()==6) {

	    typedef itk::Tensor<float, 3>     TensorType;
	    typedef itk::Image<TensorType, 3> TensorImageType;

	    typedef itk::Vector<float, 6>     VectorType;
	    typedef itk::Image<VectorType, 3> VectorImageType;

	    typedef itk::ImageFileReader<VectorImageType> ReaderType;
	    
	    VectorImageType::Pointer image = 0;
	    {
	      ReaderType::Pointer reader = ReaderType::New();
	      reader->SetImageIO (this->io);
	      reader->SetFileName ( path.toAscii().constData() );
	      try {
		reader->Update();
	      }
	      catch (itk::ExceptionObject &e) {
		qDebug() << e.GetDescription();
		return false;
	      }
	      image = reader->GetOutput(); 
	    }

	    TensorImageType::Pointer tensors = TensorImageType::New();
	    TensorImageType::RegionType region = image->GetLargestPossibleRegion();
	    tensors->SetRegions   (region);
	    tensors->SetSpacing   (image->GetSpacing());
	    tensors->SetOrigin    (image->GetOrigin());
	    tensors->SetDirection (image->GetDirection());

	    try {
	        tensors->Allocate();
	    }
	    catch (itk::ExceptionObject &e) {
	        qDebug() << e.GetDescription();
		return false;
	    }

	    itk::ImageRegionConstIteratorWithIndex<VectorImageType>  itIn (image,
									   image->GetLargestPossibleRegion());
	    itk::ImageRegionIteratorWithIndex<TensorImageType> itOut(tensors,
								     tensors->GetLargestPossibleRegion());

	    while(!itOut.IsAtEnd()) {
      
	      VectorType vec = itIn.Get();
	      TensorType tensor;
	      
	      for( unsigned int j=0; j<6; j++) {
		tensor[j] = vec[j];
	      }
      
	      itOut.Set (tensor);
	      
	      ++itOut;
	      ++itIn;
	    }
	    
	    medData->setData (tensors);
	  }
	  else if (this->io->GetNumberOfComponents()==9) {

	    typedef itk::Tensor<float, 3>     TensorType;
	    typedef itk::Image<TensorType, 3> TensorImageType;

	    typedef itk::Vector<float, 9>     VectorType;
	    typedef itk::Image<VectorType, 3> VectorImageType;

	    typedef itk::ImageFileReader<VectorImageType> ReaderType;
	    
	    VectorImageType::Pointer image = 0;
	    {
	      ReaderType::Pointer reader = ReaderType::New();
	      reader->SetImageIO (this->io);
	      reader->SetFileName ( path.toAscii().constData() );
	      try {
		reader->Update();
	      }
	      catch (itk::ExceptionObject &e) {
		qDebug() << e.GetDescription();
		return false;
	      }
	      image = reader->GetOutput(); 
	    }

	    TensorImageType::Pointer tensors = TensorImageType::New();
	    TensorImageType::RegionType region = image->GetLargestPossibleRegion();
	    tensors->SetRegions   (region);
	    tensors->SetSpacing   (image->GetSpacing());
	    tensors->SetOrigin    (image->GetOrigin());
	    tensors->SetDirection (image->GetDirection());

	    try {
	        tensors->Allocate();
	    }
	    catch (itk::ExceptionObject &e) {
	        qDebug() << e.GetDescription();
		return false;
	    }

	    itk::ImageRegionConstIteratorWithIndex<VectorImageType>  itIn (image,
									   image->GetLargestPossibleRegion());
	    itk::ImageRegionIteratorWithIndex<TensorImageType> itOut(tensors,
								     tensors->GetLargestPossibleRegion());

	    while(!itOut.IsAtEnd()) {
      
	      VectorType vec = itIn.Get();
	      TensorType tensor;
	      
	      for (unsigned int i=0; i<3; i++)
		for (unsigned int j=0; j<3; j++)
		  tensor.SetComponent (i, j, vec[i*3+j]);
      
	      itOut.Set (tensor);
	      
	      ++itOut;
	      ++itIn;
	    }

	    medData->setData (tensors);
	  }
	  else {
	      qDebug() << "Unsupported number of components";
	      return false;
	  } 
	}
	else {
	  qDebug() << "Unsupported data type";
	  return false;
	}
    }
    else {
      qDebug() << "No data set or could not create one";
      return false;
    }

    return true;
    
}
Esempio n. 3
0
  mitk::TbssImage::Pointer mitk::TbssImporter::ImportMeta()
  {
    mitk::TbssImage::Pointer tbssImg = mitk::TbssImage::New();

    m_Data = DataImageType::New();

    std::vector< std::pair<mitk::TbssImage::MetaDataFunction, int> > metaInfo;

    // Gradient images are vector images, so they will add more dimensions to the vector
    int vecLength = m_MetaFiles.size();
    //Check if there is a gradient image

    for(int i=0; i < m_MetaFiles.size(); i++)
    {
      std::pair<std::string, std::string> p = m_MetaFiles.at(i);
      if(RetrieveTbssFunction(p.first) == mitk::TbssImage::GRADIENT_X)
      {
        vecLength += 2;
      }
    }


    int currIndex = 0;


    for(int i=0; i < m_MetaFiles.size(); i++)
    {
      std::pair<std::string, std::string> p = m_MetaFiles.at(i);
      std::string function = p.first;
      std::string file = p.second;

      // Add to metainfo to give the tbss image a function-index pair
      std::pair<mitk::TbssImage::MetaDataFunction, int> pair;


      pair.first = RetrieveTbssFunction(function);
      pair.second = i;

      if(pair.first == mitk::TbssImage::GRADIENT_X)
      {
        metaInfo.push_back(std::pair<mitk::TbssImage::MetaDataFunction, int>(mitk::TbssImage::GRADIENT_X, i));
        metaInfo.push_back(std::pair<mitk::TbssImage::MetaDataFunction, int>(mitk::TbssImage::GRADIENT_Y, i+1));
        metaInfo.push_back(std::pair<mitk::TbssImage::MetaDataFunction, int>(mitk::TbssImage::GRADIENT_Z, i+2));


        VectorReaderType::Pointer fileReader = VectorReaderType::New();
        fileReader->SetFileName(file);
        itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New();
        fileReader->SetImageIO(io);
        fileReader->Update();

        VectorImageType::Pointer img = fileReader->GetOutput();

        VectorImageType::SizeType size = img->GetLargestPossibleRegion().GetSize();

        if(i==0)
        {
          // First image in serie. Properties should be used to initialize m_Data
          m_Data->SetRegions(img->GetLargestPossibleRegion().GetSize());
          m_Data->SetSpacing(img->GetSpacing());
          m_Data->SetOrigin(img->GetOrigin());
          m_Data->SetDirection(img->GetDirection());
          m_Data->SetVectorLength(vecLength);
          m_Data->Allocate();
        }


        /* Dealing with a gradient image, so the size of the vector need to be increased by 2
            since this image contains 3 volumes. Old data should not be deleted*/



        for(int x=0; x<size[0]; x++)
        {
          for(int y=0; y<size[1]; y++)
          {
            for(int z=0; z<size[2]; z++)
            {
              itk::Index<3> ix;
              ix[0] = x;
              ix[1] = y;
              ix[2] = z;

              itk::VariableLengthVector<int> vec = img->GetPixel(ix);
              itk::VariableLengthVector<float> pixel = m_Data->GetPixel(ix);
              for(int j=0; j<vec.Size(); j++)
              {
                int pos = currIndex+j;
                float f = vec.GetElement(j);
                pixel.SetElement(pos, f);

              }
              m_Data->SetPixel(ix, pixel);
            }
          }
        }

        currIndex += img->GetVectorLength();
        tbssImg->SetContainsGradient(true);
        // Read vector image and add to m_Data
      }

      else {

        metaInfo.push_back(pair);
        FileReaderType3D::Pointer fileReader = FileReaderType3D::New();
        fileReader->SetFileName(file);
        fileReader->Update();

        FloatImage3DType::Pointer img = fileReader->GetOutput();

        FloatImage3DType::SizeType size = img->GetLargestPossibleRegion().GetSize();

        if(i==0)
        {
          // First image in serie. Properties should be used to initialize m_Data
          m_Data->SetRegions(img->GetLargestPossibleRegion().GetSize());
          m_Data->SetSpacing(img->GetSpacing());
          m_Data->SetOrigin(img->GetOrigin());
          m_Data->SetDirection(img->GetDirection());
          m_Data->SetVectorLength(vecLength);         
          m_Data->Allocate();
        }

        for(int x=0; x<size[0]; x++)
        {
          for(int y=0; y<size[1]; y++)
          {
            for(int z=0; z<size[2]; z++)
            {
              itk::Index<3> ix;
              ix[0] = x;
              ix[1] = y;
              ix[2] = z;

              float f = img->GetPixel(ix);
              itk::VariableLengthVector<float> pixel = m_Data->GetPixel(ix);
              pixel.SetElement(currIndex, f);
              m_Data->SetPixel(ix, pixel);

            }
          }
        }
      }

      if(pair.first == mitk::TbssImage::MEAN_FA_SKELETON)
      {
        tbssImg->SetContainsMeanSkeleton(true);
      }
      else if(pair.first == mitk::TbssImage::MEAN_FA_SKELETON_MASK)
      {
        tbssImg->SetContainsSkeletonMask(true);
      }
      else if(pair.first == mitk::TbssImage::DISTANCE_MAP)
      {
        tbssImg->SetContainsDistanceMap(true);
      }

      currIndex++;

    }

    tbssImg->SetIsMeta(true);
    tbssImg->SetImage(m_Data);
    tbssImg->SetMetaInfo(metaInfo);
    tbssImg->InitializeFromVectorImage();

    return tbssImg;
  }
QVector<double> PerfusionMapCalculatorThread::deconvolve(QVector<double> tissue)
{
    QVector<double> residuefunc(tissue.size());
    int i;
    //std::cout<<"?"<<std::endl;
    /*for(i=0;i<tissue.size();i++)
    {
        std::cout<<tissue[i]<<" "<<std::flush;
    }*/
    //std::cout<<"?"<<std::endl;
    typedef std::complex<double> complexd;
    complexd num1, num2, num3;

//     //Usant fftw
//     fftw_complex* in;
//     fftw_complex* out;
//
//     in = new fftw_complex[tissue.size()];
//     out = new fftw_complex[tissue.size()];
//
//     fftw_plan pf, pb;
//
//     pf = fftw_plan_dft_1d(tissue.size(), in, out, FFTW_FORWARD, FFTW_ESTIMATE);
//     pb = fftw_plan_dft_1d(tissue.size(), in, out, FFTW_BACKWARD, FFTW_ESTIMATE);
//
//     int i;
//     for(i=0;i<tissue.size();i++)
//     {
//         in[i][0]=tissue[i];
//         in[i][1]=0.0;
//     }
//
//     fftw_execute(pf);
//
//     for(i=0;i<tissue.size();i++)
//     {
//         num1=complexd(fftaifreal[i],fftaifimag[i]);
//         num2=complexd(out[i][0],out[i][1]);
//
//         if((reg_fact > 1e-6) || ((fabs(num1.real()) + fabs(num1.imag()))> 1e-6))
//         {
//             num3 = num2* (conj(num1) / (num1*conj(num1) + reg_fact*pow(-1,reg_exp)*pow(omega[i],2*reg_exp)));
//             in[i][0] = num3.real();
//             in[i][1] = num3.imag();
//         }
//         else
//         {
//             in[i][0] = 0.0;
//             in[i][1] = 0.0;
//         }
//     }
//     fftw_execute(pb);
//     for(i=0;i<tissue.size();i++)
//     {
//         residuefunc[i]=out[i][0]/tissue.size();
//     }
//     fftw_destroy_plan(pf);
//     fftw_destroy_plan(pb);
//     free(in);
//     free(out);

    //Usant itk's
    //std::cout<<"Usant itk's"<<std::endl;
    typedef itk::Image< double, 1 > VectorImageType;
    VectorImageType::RegionType region;
    VectorImageType::IndexType start;
    start[0]=0;
    VectorImageType::SizeType size;
    size[0] = m_sizet;  //les mostres temporals
    region.SetSize(size);
    region.SetIndex(start);
    //std::cout<<"&"<<std::endl;

    VectorImageType::Pointer tissueImage = VectorImageType::New();
    tissueImage->SetRegions(region);
    try
        {
        tissueImage->Allocate();
        }
    catch(itk::ExceptionObject & excp)
        {
        std::cerr << "Error: " << std::endl;
        std::cerr << excp << std::endl;
        return residuefunc;
        }
    //std::cout<<"$"<<std::endl;

    typedef itk::ImageRegionIterator<VectorImageType> VectorIteratorType;
    VectorIteratorType tissueIter(tissueImage, tissueImage->GetLargestPossibleRegion());
    //std::cout<<"@"<<tissueImage->GetLargestPossibleRegion().GetSize()[0]<<std::endl;

    typedef itk::VnlFFTRealToComplexConjugateImageFilter< double, 1 >  FFTFilterType;
    FFTFilterType::Pointer fftFilter = FFTFilterType::New();
    //std::cout<<"#"<<std::endl;

    tissueIter.GoToBegin();

    //std::cout<<"%"<<std::endl;
    for(i=0;i<tissue.size();i++)
    {
        tissueIter.Set(tissue[i]);
        ++tissueIter;
    }
    fftFilter->SetInput(tissueImage);

    try
        {
        fftFilter->Update();
        }
    catch(itk::ExceptionObject & excp)
        {
        std::cerr << "Error: " << std::endl;
        std::cerr << excp << std::endl;
        return residuefunc;
        }

    typedef FFTFilterType::OutputImageType ComplexImageType;
    ComplexImageType::Pointer residualFFTImage = ComplexImageType::New();
    residualFFTImage->SetRegions(region);
    residualFFTImage->Allocate();

    typedef itk::ImageRegionIterator<ComplexImageType> ComplexIteratorType;
    ComplexIteratorType fftTissueIter(fftFilter->GetOutput(), fftFilter->GetOutput()->GetLargestPossibleRegion());
    fftTissueIter.GoToBegin();

    ComplexIteratorType fftResidualIter(residualFFTImage, residualFFTImage->GetLargestPossibleRegion());
    fftResidualIter.GoToBegin();

    //std::cout<<"!"<<fftFilter->GetOutput()->GetLargestPossibleRegion().GetSize()[0]<<std::endl;
    for(i=0;i<tissue.size();i++)
    {
        num1=complexd(fftaifreal[i],fftaifimag[i]);
        num2=complexd(fftTissueIter.Get().real(),fftTissueIter.Get().imag());

        if((reg_fact > 1e-6) || ((fabs(num1.real()) + fabs(num1.imag()))> 1e-6))
        {
            num3 = num2* (conj(num1) / (num1*conj(num1) + reg_fact*pow(-1,reg_exp)*pow(omega[i],2*reg_exp)));
            fftResidualIter.Set(num3);
        }
        else
        {
            num3 = complexd(0.0, 0.0);
            fftResidualIter.Set(num3);
        }
        ++fftTissueIter;
        ++fftResidualIter;
    }

    typedef itk::VnlFFTComplexConjugateToRealImageFilter< double, 1 >  IFFTFilterType;
    IFFTFilterType::Pointer fftInverseFilter = IFFTFilterType::New();
    fftInverseFilter->SetInput(residualFFTImage);

    try
        {
        fftInverseFilter->Update();
        }
    catch(itk::ExceptionObject & excp)
        {
        std::cerr << "Error: " << std::endl;
        std::cerr << excp << std::endl;
        return residuefunc;
        }

    //std::cout<<"*"<<fftInverseFilter->GetOutput()->GetLargestPossibleRegion().GetSize()[0]<<std::endl;
    VectorIteratorType residualIter(fftInverseFilter->GetOutput(), fftInverseFilter->GetOutput()->GetLargestPossibleRegion());
    residualIter.GoToBegin();

    for(i=0;i<residuefunc.size();i++)
    {
        //if(residuefunc[i]!=residualIter.Get()) std::cout<<"Resultat residuefunc diferent: "<<residuefunc[i]<<" ," <<residualIter.Get()/tissue.size()<<std::endl;

        residuefunc[i]=residualIter.Get();
        ++residualIter;
    }
    for(i=0;i<residuefunc.size();i++)
    {
        //std::cout<<residuefunc[i]<<" "<<std::flush;
    }
    //std::cout<<"?"<<std::endl;
    return residuefunc;
}