LabelImagePointer DeriveForegroundLabelImage(const ImagePointer I, const int threshold) { itk::ImageLinearConstIteratorWithIndex<ImageType> originitr(I, I->GetRequestedRegion()); originitr.SetDirection(2); originitr.GoToBegin(); ImageType::SizeType originsize = I->GetLargestPossibleRegion().GetSize(); LabelImagePointer pBinaryImage = LabelImageType::New(); LabelImageType::SizeType size; size[0] = originsize[0]; size[1] = originsize[1]; size[2] = originsize[2]; LabelImageType::IndexType idx; idx.Fill(0); LabelImageType::RegionType region; region.SetSize(size); region.SetIndex(idx); pBinaryImage->SetRegions(region); pBinaryImage->Allocate(); pBinaryImage->FillBuffer(0); itk::ImageLinearIteratorWithIndex<LabelImageType> binaryitr(pBinaryImage, pBinaryImage->GetRequestedRegion()); binaryitr.SetDirection(2); binaryitr.GoToBegin(); while( !originitr.IsAtEnd() && !binaryitr.IsAtEnd()) { while(!originitr.IsAtEndOfLine()){ if (originitr.Get() > threshold){ binaryitr.Set(1); } ++originitr; ++binaryitr; } originitr.NextLine(); binaryitr.NextLine(); } return pBinaryImage; }
vtkSmartPointer<vtkPolyData> getVTKPolyDataPrecise(LabelImageType::Pointer label) { LabelIteratorType liter = LabelIteratorType(label,label->GetLargestPossibleRegion()); liter.GoToBegin(); //find the maximum number of cells unsigned short max1 = 0; for(liter.GoToBegin();!liter.IsAtEnd();++liter) max1 = MAX(max1,liter.Get()); //find all the cubes in which cells lie cubecoord* carray = new cubecoord[max1+1]; for(int counter=0; counter<=max1; counter++) { carray[counter].sx=60000; carray[counter].sy=60000;carray[counter].sz=60000; carray[counter].ex=0;carray[counter].ey=0;carray[counter].ez=0; } typedef itk::ImageRegionConstIteratorWithIndex<LabelImageType> ConstLabelIteratorWithIndex; ConstLabelIteratorWithIndex cliter = ConstLabelIteratorWithIndex(label,label->GetLargestPossibleRegion()); InputImageType::IndexType index; for(cliter.GoToBegin();!cliter.IsAtEnd();++cliter) { int cur = cliter.Get(); if(cur!=0) { index = cliter.GetIndex(); carray[cur].sx= MIN(index[0],carray[cur].sx); carray[cur].sy= MIN(index[1],carray[cur].sy); carray[cur].sz= MIN(index[2],carray[cur].sz); carray[cur].ex= MAX(index[0],carray[cur].ex); carray[cur].ey= MAX(index[1],carray[cur].ey); carray[cur].ez= MAX(index[2],carray[cur].ez); } } //find the largest image size we need unsigned short wx=0,wy=0,wz=0; for(int counter=1; counter<=max1; counter++) { wx = MAX(carray[counter].ex-carray[counter].sx+1,wx); wy = MAX(carray[counter].ey-carray[counter].sy+1,wy); wz = MAX(carray[counter].ez-carray[counter].sz+1,wz); } // accommodate padding wx = wx+2;wy = wy +2; wz = wz+2; printf("wx wy wz %u %u %u\n",wx,wy,wz); // create a tiny image of maximum size //appendfilter->UserManagedInputsOn(); //appendfilter->SetNumberOfInputs(max1); vtkSmartPointer<vtkAppendPolyData> appendfilter = vtkSmartPointer<vtkAppendPolyData>::New(); /**************/ ExportFilterType::Pointer itkexporter = ExportFilterType::New(); vtkSmartPointer<vtkImageImport> vtkimporter = vtkSmartPointer<vtkImageImport>::New(); ConnectPipelines(itkexporter,(vtkImageImport *)vtkimporter); vtkSmartPointer<vtkMarchingCubes> contourf = vtkSmartPointer<vtkMarchingCubes>::New(); contourf->SetInputData(vtkimporter->GetOutput()); contourf->SetValue(0,127); contourf->ComputeNormalsOff(); contourf->ComputeScalarsOff(); contourf->ComputeGradientsOff(); vtkSmartPointer<vtkSmoothPolyDataFilter> smoothf = vtkSmartPointer<vtkSmoothPolyDataFilter>::New(); smoothf->SetInputData(contourf->GetOutput()); smoothf->SetRelaxationFactor(0.3); smoothf->SetNumberOfIterations(20); vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New(); transform->PostMultiply(); transform->Identity(); vtkSmartPointer<vtkTransformPolyDataFilter> tf = vtkSmartPointer<vtkTransformPolyDataFilter>::New(); tf->SetTransform(transform); tf->SetInputData(smoothf->GetOutput()); /******************/ InputImageType::Pointer t = getEmpty(wx,wy,wz); for(int counter=1; counter<=max1; counter++) { //printf("Maximum tiny image size I need is [%d %d %d]\n",wx,wy,wz); if(carray[counter].sx > 59999) continue; printf("Working..\n"); // scanf("%*d"); InputImageType::SizeType size; InputImageType::RegionType region; index.Fill(1); region.SetIndex(index); region.SetSize(size); LabelImageType::SizeType lsize; LabelImageType::IndexType lindex; LabelImageType::RegionType lregion; itkexporter->SetInput(t); t->FillBuffer(0); lsize[0] = carray[counter].ex-carray[counter].sx+1; lsize[1] = carray[counter].ey-carray[counter].sy+1; lsize[2] = carray[counter].ez-carray[counter].sz+1; lindex[0] = carray[counter].sx; lindex[1] = carray[counter].sy; lindex[2] = carray[counter].sz; lregion.SetIndex(lindex); lregion.SetSize(lsize); LabelIteratorType localiter = LabelIteratorType(label,lregion); size = lsize; region.SetSize(size); IteratorType iter = IteratorType(t,region); for(localiter.GoToBegin(),iter.GoToBegin();!localiter.IsAtEnd();++localiter,++iter) { if(localiter.Get()==counter) { iter.Set(255); } } t->Modified(); vtkimporter->Modified(); transform->Identity(); transform->Translate(carray[counter].sx-1,carray[counter].sy-1,carray[counter].sz-1); tf->SetTransform(transform); tf->Update(); vtkSmartPointer<vtkPolyData> pol=vtkSmartPointer<vtkPolyData>::New(); pol->DeepCopy(tf->GetOutput()); // tf->GetOutput()->Print(std::cout); appendfilter->AddInputData(pol); //appendfilter->Update(); //appendfilter->SetInputByNumber(counter-1,tf->GetOutput()); // appendfilter->Update(); // appendfilter->GetOutput()->Print(std::cout); //if(counter>500) // break; printf("Completed %d/%d\r",counter,max1); // scanf("%*d"); } appendfilter->Update(); vtkSmartPointer<vtkDecimatePro> decimate = vtkSmartPointer<vtkDecimatePro>::New(); decimate->SetInputData(appendfilter->GetOutput()); decimate->SetTargetReduction(0.1); //decimate->SetNumberOfDivisions(32,32,32); printf("Decimating the contours..."); decimate->Update(); printf("Done\n"); printf("Smoothing the contours after decimation..."); vtkSmartPointer<vtkSmoothPolyDataFilter> smoothfinal = vtkSmartPointer<vtkSmoothPolyDataFilter>::New(); smoothfinal->SetRelaxationFactor(0.2); smoothfinal->SetInputData(decimate->GetOutput()); smoothfinal->SetNumberOfIterations(0); smoothfinal->Update(); printf("Done\n"); delete [] carray; vtkSmartPointer<vtkPolyData> out = smoothfinal->GetOutput(); return out; }