void LabelsVolumeGenerator::postProcessTargetITK()
{
    typedef unsigned char       PixelType;
    typedef Image<PixelType, 3> ImageType;

    // create a new image from the target data

    ImageType::Pointer input = ImageType::New();

    ImageType::IndexType start;
    start.Fill(0);

    ImageType::SizeType size;
    for (int i = 0; i < 3; ++i) size[i] = m_targetVolume->dimensions[i];

    ImageType::RegionType region;
    region.SetSize(size);
    region.SetIndex(start);

    input->SetRegions(region);
    input->SetSpacing(m_targetVolume->spacing.data());
    input->Allocate();

    memcpy(input->GetBufferPointer(), m_targetVolume->data, m_bufferSize);

    // create a grayscale dilation filter and a structuring element

    typedef BinaryBallStructuringElement<PixelType, 3> StructureType;
    typedef GrayscaleDilateImageFilter<ImageType, ImageType, StructureType> DilateFilterType;

    DilateFilterType::Pointer filter = DilateFilterType::New();

    StructureType structure;
    structure.SetRadius(1);

    filter->SetKernel(structure);

    // set up progress reporting
    if (m_progressReporter)
    {
        CStyleCommand::Pointer command = CStyleCommand::New();
        command->SetClientData(m_progressReporter);
        command->SetCallback(ProgressCallback);
        filter->AddObserver(ProgressEvent(), command);
        m_progressReporter->start("Post-Processing Label volume",
                                  "Dilating label field...");
    }

    // hook up the filters and run

    filter->SetInput(input);
    filter->Update();

    if (m_progressReporter)
        m_progressReporter->finish();

    // copy back into the target volume data
    memcpy(m_targetVolume->data, filter->GetOutput()->GetBufferPointer(), m_bufferSize);

    // threshold and gaussian blur to put a smooth version into the alpha channel

    typedef BinaryThresholdImageFilter<ImageType, ImageType> ThresholderType;
//    typedef DiscreteGaussianImageFilter<ImageType, ImageType> SmoothFilterType;
    typedef SmoothingRecursiveGaussianImageFilter<ImageType, ImageType> SmoothFilterType;

    ThresholderType::Pointer thresholder = ThresholderType::New();
    thresholder->SetLowerThreshold(1);
    thresholder->SetUpperThreshold(255);
    thresholder->SetInsideValue(255);
    thresholder->SetOutsideValue(0);

    SmoothFilterType::Pointer smoother = SmoothFilterType::New();
//    smoother->SetVariance(0.05); // in physical units
//    smoother->SetMaximumKernelWidth(5);
    smoother->SetSigma(0.2);

    // set up progress reporting (again)
    if (m_progressReporter)
    {
        CStyleCommand::Pointer command = CStyleCommand::New();
        command->SetClientData(m_progressReporter);
        command->SetCallback(ProgressCallback);
        smoother->AddObserver(ProgressEvent(), command);
        m_progressReporter->start("Post-Processing Label volume",
                                  "Smoothing alpha mask...");
    }

    // hook up the filters and run

    thresholder->SetInput(input);
    smoother->SetInput(thresholder->GetOutput());
    smoother->Update();

    // copy back into the target volume data
    memcpy(m_targetMask->data, smoother->GetOutput()->GetBufferPointer(), m_bufferSize);

    if (m_progressReporter)
        m_progressReporter->finish();
}
Пример #2
0
void
DistanceMapFilter::applyDistanceMapFilter(QString flnm,
					  QList<Vec> clipPos,
					  QList<Vec> clipNormal,
					  QList<CropObject> crops,
					  QList<PathObject> paths,
					  uchar *lut,
					  int chan)
{
  int bpv = 1;
  if (m_voxelType > 0) bpv = 2;
  int nbytes = bpv*m_nY*m_nZ;

  bool trim = (qRound(m_dataSize.x) < m_height ||
	       qRound(m_dataSize.y) < m_width ||
	       qRound(m_dataSize.z) < m_depth);
  bool clipPresent = (clipPos.count() > 0);

  m_cropPresent = false;
  m_tearPresent = false;
  m_blendPresent = false;
  for(int ci=0; ci<m_crops.count(); ci++)
    {
      if (crops[ci].cropType() < CropObject::Tear_Tear)
	m_cropPresent = true;
      else if (crops[ci].cropType() < CropObject::View_Tear)
	m_tearPresent = true;
      else if (m_crops[ci].cropType() > CropObject::Displace_Displace &&
	       m_crops[ci].cropType() < CropObject::Glow_Ball)
	m_blendPresent = true;
    }

  m_pathCropPresent = false;
  m_pathBlendPresent = false;
  for (int i=0; i<m_paths.count(); i++)
    {
      if (m_paths[i].blend()) m_pathBlendPresent = true;
      if (m_paths[i].crop()) m_pathCropPresent = true;
    }

  m_meshLog->moveCursor(QTextCursor::End);
  int d0 = 0;
  int d1 = m_nX-1;
  int d0z = d0 + qRound(m_dataMin.z);
  int d1z = d1 + qRound(m_dataMin.z);

  uchar *opacityVol = new uchar[m_nX*m_nY*m_nZ];
  
  uchar *cropped = new uchar[nbytes];
  uchar *tmp = new uchar[nbytes];

  int i0 = 0;
  for(int i=d0z; i<=d1z; i++)
    {
      m_meshProgress->setValue((int)(100.0*(float)i0/(float)m_nX));
      qApp->processEvents();

      int iv = qBound(0, i, m_depth-1);
      uchar *vslice = m_vfm->getSlice(iv);

      memset(cropped, 0, nbytes);

      if (!trim)
	memcpy(tmp, vslice, nbytes);
      else
	{
	  int wmin = qRound(m_dataMin.y);
	  int hmin = qRound(m_dataMin.x);
	  if (m_voxelType == 0)
	    {
	      for(int w=0; w<m_nY; w++)
		for(int h=0; h<m_nZ; h++)
		  tmp[w*m_nZ + h] = vslice[(wmin+w)*m_height + (hmin+h)];
	    }
	  else
	    {
	      for(int w=0; w<m_nY; w++)
		for(int h=0; h<m_nZ; h++)
		  ((ushort*)tmp)[w*m_nZ + h] = ((ushort*)vslice)[(wmin+w)*m_height + (hmin+h)];
	    }
	}

      int jk = 0;
      for(int j=0; j<m_nY; j++)
	for(int k=0; k<m_nZ; k++)
	  {
	    Vec po = Vec(m_dataMin.x+k, m_dataMin.y+j, iv);
	    bool ok = true;
	    
	    // we don't want to scale before pruning
	    int mop = 0;
	    {
	      Vec pp = po - m_dataMin;
	      int ppi = pp.x/m_pruneLod;
	      int ppj = pp.y/m_pruneLod;
	      int ppk = pp.z/m_pruneLod;
	      ppi = qBound(0, ppi, m_pruneX-1);
	      ppj = qBound(0, ppj, m_pruneY-1);
	      ppk = qBound(0, ppk, m_pruneZ-1);
	      int mopidx = ppk*m_pruneY*m_pruneX + ppj*m_pruneX + ppi;
	      mop = m_pruneData[3*mopidx + chan];
	      ok = (mop > 0);
	    }
	    
	    po *= m_samplingLevel;
	    
	    if (ok && clipPresent)
	      ok = StaticFunctions::getClip(po, clipPos, clipNormal);
	    
	    if (ok && m_cropPresent)
	      ok = checkCrop(po);
	    
	    if (ok && m_pathCropPresent)
	      ok = checkPathCrop(po);
	    
	    if (ok && m_blendPresent)
	      {
		ushort v;
		if (m_voxelType == 0)
		  v = tmp[j*m_nZ + k];
		else
		  v = ((ushort*)tmp)[j*m_nZ + k];
		ok = checkBlend(po, v, lut);
	      }
	    
	    if (ok && m_pathBlendPresent)
	      {
		ushort v;
		if (m_voxelType == 0)
		  v = tmp[j*m_nZ + k];
		else
		  v = ((ushort*)tmp)[j*m_nZ + k];
		ok = checkPathBlend(po, v, lut);
	      }
	    
	    if (ok)
	      cropped[jk] = mop;
	    else
	      cropped[jk] = 0;
	    
	    jk ++;
	  }
      
      if (m_voxelType == 0)
	{
	  for(int j=0; j<m_nY*m_nZ; j++)
	    {
	      if (cropped[j] == 0)
		tmp[j] = 0;
	    }
	}
      else
	{
	  for(int j=0; j<m_nY*m_nZ; j++)
	    {
	      if (cropped[j] == 0)
		((ushort*)tmp)[j] = 0;
	    }
	}
      
      applyOpacity(iv, cropped, lut, tmp);
      memcpy(opacityVol + i0*m_nY*m_nZ, tmp, m_nY*m_nZ);
      
      i0++;
    }
  delete [] tmp;
  delete [] cropped;
  m_meshProgress->setValue(100);
  qApp->processEvents();

  //------------
  if (m_tearPresent)
    {
      uchar *data0 = new uchar[m_nX*m_nY*m_nZ];
      memcpy(data0, opacityVol, m_nX*m_nY*m_nZ);
      applyTear(d0, d1, 0,
		data0, opacityVol, false);
      
      delete [] data0;
    }


  typedef uchar PixelType;
  const unsigned int Dimension = 3;
  typedef itk::Image< PixelType, Dimension > ImageType;

  ImageType::IndexType start;
  start.Fill(0);

  ImageType::SizeType size;
  size[0] = m_nZ;
  size[1] = m_nY;
  size[2] = m_nX;

  ImageType::RegionType region(start, size);

  ImageType::Pointer image = ImageType::New();
  image->SetRegions(region);
  image->Allocate();
  image->FillBuffer(0);
  uchar *iptr = (uchar*)image->GetBufferPointer();
  memcpy(iptr, opacityVol, m_nX*m_nY*m_nZ);

  typedef itk::Image< float, 3 > OutputImageType;
  typedef itk::SignedMaurerDistanceMapImageFilter<ImageType, OutputImageType> DistanceMapFilter;
  DistanceMapFilter::Pointer filter = DistanceMapFilter::New();
  filter->SetInput( image );
  filter->SetSquaredDistance(0);
  filter->SetUseImageSpacing(0);
  filter->SetInsideIsPositive(1);
  filter->Update();

  QFile fp;
  fp.setFileName(flnm);
  fp.open(QFile::WriteOnly);
  uchar vt = 8;
  fp.write((char*)&vt, 1);
  fp.write((char*)&m_nX, 4);
  fp.write((char*)&m_nY, 4);
  fp.write((char*)&m_nZ, 4);
  OutputImageType *dimg = filter->GetOutput();
  char *tdata = (char*)(dimg->GetBufferPointer());
  fp.write(tdata, 4*m_nX*m_nY*m_nZ);
  fp.close();

  m_meshLog->moveCursor(QTextCursor::End);
  m_meshLog->insertPlainText("Signed Distance Map data saved in "+flnm);

  QMessageBox::information(0, "", QString("Signed Distance Map saved in "+flnm));
}
Пример #3
0
int main(int argc, char**argv)
{
	int nx, ny, nz, nbytes, direction, nx8, ny8, nz8, k;
//	int n, x, y, z, dx, dy;
	long long width, height, depth, xysize;
	char *dataFile, *tiffFile;
	bool use_compression = true, data2tiff, compressdata = true;
	FILE *fpdata;

	if (argc != 4) {
		printf("Usage: maketiff dataFile tiffFile direction\n");
		printf("       direction = 0 (tiff to data) = 1 (data to tiff)\n");
		return 1;
	}

	dataFile = argv[1];
	tiffFile = argv[2];
	sscanf(argv[3],"%d",&direction);
	if (direction == 0) {
		data2tiff = false;
		printf("Output data file: %s\n",dataFile);
	} else {
		data2tiff = true;
		printf("Output image file: %s\n",tiffFile);
	}

	if (data2tiff) {		// create tiff file
		fpdata = fopen(dataFile,"rb");
		if (fpdata == NULL) {
			return 2;
		}
		fread(&nx,4,1,fpdata);
		fread(&ny,4,1,fpdata);
		fread(&nz,4,1,fpdata);
//		fread(&nbytes,4,1,fpdata);

		//if (nbytes != nx*ny*nz) {
		//	printf("Error: this is a compressed data file\n");
		//	return 10;
		//}
		width = nx;
		height = ny;
		depth = nz;
		xysize = width*height;
		printf("Desired image dimensions: width, height, depth: %d %d %d\n",width,height,depth);

		ImageType::Pointer im = ImageType::New();
		ImageType::SizeType imsize; 
		imsize[0] = width;
		imsize[1] = height;
		imsize[2] = depth;
		ImageType::IndexType imstart; 
		imstart[0] = 0;
		imstart[1] = 0;
		imstart[2] = 0;
		ImageType::RegionType imregion; 
		imregion.SetSize(imsize);
		imregion.SetIndex(imstart);
		im->SetRegions(imregion);
		im->Allocate();
		p = (unsigned char *)(im->GetBufferPointer());

		nbytes = nx*ny*nz;
		fread(p,nbytes,1,fpdata);

		typedef itk::ImageFileWriter<ImageType> FileWriterType;
		FileWriterType::Pointer writer = FileWriterType::New();
		writer->SetFileName(tiffFile);
		writer->SetInput(im);
		if (use_compression) {
			writer->UseCompressionOn();
		}
		try
		{
			writer->Update();
		}
		catch (itk::ExceptionObject &e)
		{
			std::cout << e << std::endl;
			return 3;
		}
		if (use_compression) {
			printf("Created compressed image file: %s\n",tiffFile);
		} else {
			printf("Created uncompressed image file: %s\n",tiffFile);
		}
	} else {		// create data file
		typedef itk::ImageFileReader<ImageType> FileReaderType;
		FileReaderType::Pointer reader = FileReaderType::New();

		reader->SetFileName(tiffFile);
		try
		{
			reader->Update();
		}
		catch (itk::ExceptionObject &e)
		{
			std::cout << e << std::endl;
			printf("Read error on input file\n");
			return 2;	// Read error on input tiff file
		}

		im = reader->GetOutput();
		width = im->GetLargestPossibleRegion().GetSize()[0];
		height = im->GetLargestPossibleRegion().GetSize()[1];
		depth = im->GetLargestPossibleRegion().GetSize()[2];
		printf("Image dimensions: width, height, depth: %d %d %d\n",width,height,depth);

		p = (unsigned char *)(im->GetBufferPointer());

		fpdata = fopen(dataFile,"wb");
		if (fpdata == NULL) {
			return 2;
		}
		nx = width;
		ny = height;
		nz = depth;

		if (compressdata) {
			// create compressed buffer pc from p using (0,1)
			// First round up nx, ny, nz to a multiple of 8
			k = nx%8;
			if (k == 0)
				nx8 = nx;
			else
				nx8 = nx + 8-k;
			k = ny%8;
			if (k == 0)
				ny8 = ny;
			else
				ny8 = ny + 8-k;
			k = nx%8;
			if (k == 0)
				nz8 = nz;
			else
				nz8 = nz + 8-k;
			nbytes = nx8*ny8*nz8/8;

			pc = (unsigned char *)malloc(nbytes*sizeof(unsigned char));
			int kbit = 0;
			int kbyte = 0;
			k = 0;
			unsigned char pcbyte = 0;
			for (int iz=0; iz<nz8; iz++) {
				bool zok = (iz<nz);
				for (int iy=0; iy<ny8; iy++) {
					bool yok = (iy<ny);
					for (int ix=0; ix<nx8; ix++) {
						bool xok = (ix<nx);
						if (xok && yok && zok) {
							// set bit kbit of pcbyte to (0,1) based on p[k]
							if (p[k] == 1 || p[k] == 255) {
								pcbyte |= 1 << kbit;
							}
							if (kbyte < 4) printf("ix,iy,iz k p[k] pcbyte: %d %d %d  %d  %d  %d\n", ix,iy,iz,k,p[k],pcbyte);
							k++;
						}
						kbit++;
						if (kbit == 8) {
							pc[kbyte] = pcbyte;
							if (kbyte == 0) {
								printf("byte:%d  %d\n",kbyte,pc[kbyte]);
							}
							kbyte++;
							pcbyte = 0;
							kbit = 0;
						}
					}
				}
			}
		}
		fwrite(&nx,4,1,fpdata);
		fwrite(&ny,4,1,fpdata);
		fwrite(&nz,4,1,fpdata);
		fwrite(&nx8,4,1,fpdata);
		fwrite(&ny8,4,1,fpdata);
		fwrite(&nz8,4,1,fpdata);
		fwrite(&nbytes,4,1,fpdata);
		printf("nx,ny,nz  nx8,ny8,nz8: %d %d %d  %d %d %d\n",nx,ny,nz,nx8,ny8,nz8);

		width = nx;
		height = ny;
		depth = nz;
		xysize = width*height;
// write(nfdata) nx,ny,nz,(((imagedata(ix,iy,iz),ix=1,nx),iy=1,ny),iz=1,nz)
		// try this...
		if (compressdata) {
			fwrite(pc,1,nbytes,fpdata);
		} else {
			fwrite(p,1,nx*ny*nz,fpdata);
		}
		fclose(fpdata);
	}

	return 0;
}
  mitk::Image::Pointer PartialVolumeAnalysisClusteringCalculator::CaculateAngularErrorImage(
      mitk::Image::Pointer comp1, mitk::Image::Pointer comp2, mitk::Image::Pointer probImg) const
  {

    // cast input images to itk
    typedef itk::Image<float, 3> ImageType;
    typedef mitk::ImageToItk<ImageType> CastType;
    CastType::Pointer caster = CastType::New();
    caster->SetInput(comp1);
    caster->Update();
    ImageType::Pointer comp1Image = caster->GetOutput();

    caster = CastType::New();
    caster->SetInput(comp2);
    caster->Update();
    ImageType::Pointer comp2Image = caster->GetOutput();

    caster = CastType::New();
    caster->SetInput(probImg);
    caster->Update();
    ImageType::Pointer probImage = caster->GetOutput();

    // figure out maximum probability for fiber class
    float maxProb = 0;
    itk::ImageRegionConstIterator<ImageType>
        itprob(probImage, probImage->GetLargestPossibleRegion());
    itprob.GoToBegin();
    while( !itprob.IsAtEnd() )
    {
      maxProb = itprob.Get() > maxProb ? itprob.Get() : maxProb;
      ++itprob;
    }

    // generate a list sample of angles at positions
    // where the fiber-prob is higher than .2*maxprob
    typedef float MeasurementType;
    const unsigned int MeasurementVectorLength = 2;
    typedef itk::Vector< MeasurementType , MeasurementVectorLength >
                                                                 MeasurementVectorType;
    typedef itk::Statistics::ListSample< MeasurementVectorType > ListSampleType;
    ListSampleType::Pointer listSample = ListSampleType::New();
    listSample->SetMeasurementVectorSize( MeasurementVectorLength );

    itk::ImageRegionIterator<ImageType>
        it1(comp1Image, comp1Image->GetLargestPossibleRegion());
    itk::ImageRegionIterator<ImageType>
        it2(comp2Image, comp2Image->GetLargestPossibleRegion());

    it1.GoToBegin();
    it2.GoToBegin();
    itprob.GoToBegin();

    while( !itprob.IsAtEnd() )
    {
      if(itprob.Get() > 0.2 * maxProb)
      {
        MeasurementVectorType mv;
        mv[0] = ( MeasurementType ) it1.Get();
        mv[1] = ( MeasurementType ) it2.Get();
        listSample->PushBack(mv);
      }
      ++it1;
      ++it2;
      ++itprob;
    }

    // generate a histogram from the list sample
    typedef float HistogramMeasurementType;
    typedef itk::Statistics::Histogram< HistogramMeasurementType, itk::Statistics::DenseFrequencyContainer2 > HistogramType;
    typedef itk::Statistics::SampleToHistogramFilter< ListSampleType, HistogramType > GeneratorType;
    GeneratorType::Pointer generator = GeneratorType::New();

    GeneratorType::HistogramType::SizeType size(2);
    size.Fill(30);
    generator->SetHistogramSize( size );

    generator->SetInput( listSample );
    generator->SetMarginalScale( 10.0 );

    generator->Update();

    // look for frequency mode in the histogram
    GeneratorType::HistogramType::ConstPointer histogram = generator->GetOutput();
    GeneratorType::HistogramType::ConstIterator iter = histogram->Begin();
    float maxFreq = 0;
    MeasurementVectorType maxValue;
    maxValue.Fill(0);
    while ( iter != histogram->End() )
    {
      if(iter.GetFrequency() > maxFreq)
      {
        maxFreq = iter.GetFrequency();
        maxValue[0] = iter.GetMeasurementVector()[0];
        maxValue[1] = iter.GetMeasurementVector()[1];
      }
      ++iter;
    }

    // generate return image that contains the angular
    // error of the voxels to the histogram max measurement
    ImageType::Pointer returnImage = ImageType::New();
    returnImage->SetSpacing( comp1Image->GetSpacing() );   // Set the image spacing
    returnImage->SetOrigin( comp1Image->GetOrigin() );     // Set the image origin
    returnImage->SetDirection( comp1Image->GetDirection() );  // Set the image direction
    returnImage->SetRegions( comp1Image->GetLargestPossibleRegion() );
    returnImage->Allocate();

    itk::ImageRegionConstIterator<ImageType>
        cit1(comp1Image, comp1Image->GetLargestPossibleRegion());

    itk::ImageRegionConstIterator<ImageType>
        cit2(comp2Image, comp2Image->GetLargestPossibleRegion());

    itk::ImageRegionIterator<ImageType>
        itout(returnImage, returnImage->GetLargestPossibleRegion());

    cit1.GoToBegin();
    cit2.GoToBegin();
    itout.GoToBegin();

    vnl_vector<float> v(3);
    v[0] = cos( maxValue[0] ) * sin( maxValue[1] );
    v[1] = sin( maxValue[0] ) * sin( maxValue[1] );
    v[2] = cos( maxValue[1] );
//    MITK_INFO << "max vector: " << v;
    while( !cit1.IsAtEnd() )
    {
      vnl_vector<float> v1(3);
      v1[0] = cos( cit1.Get() ) * sin( cit2.Get() );
      v1[1] = sin( cit1.Get() ) * sin( cit2.Get() );
      v1[2] = cos( cit2.Get() );

      itout.Set(fabs(angle(v,v1)));
//      MITK_INFO << "ang_error " << v1 << ": " << fabs(angle(v,v1));

      ++cit1;
      ++cit2;
      ++itout;
    }

    mitk::Image::Pointer retval = mitk::Image::New();
    retval->InitializeByItk(returnImage.GetPointer());
    retval->SetVolume(returnImage->GetBufferPointer());
    return retval;
  }