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(); }
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)); }
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; }