ImagePtr MergeOperator::merge(const std::vector<ImagePtr>& images, const Settings& settings) { if (images.size() == 0) throw NoImagesException("NoImagesException: no picture supplied to the merge operator"); checkImagesExposureValue(images); ImagePtr image = getEmptyImage(images); coreMerge(image, images, settings); return image; }
//Function to process the poly data out of the label image 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=6000;carray[counter].sy=6000;carray[counter].sz=6000; carray[counter].ex=0;carray[counter].ey=0;carray[counter].ez=0; } //Declare label image iterators typedef itk::ImageRegionConstIteratorWithIndex<labelImageType> ConstLabelIteratorWithIndex; ConstLabelIteratorWithIndex cliter = ConstLabelIteratorWithIndex(label,label->GetLargestPossibleRegion()); inputImageType::IndexType index; //Iterate through the label image 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); //Declare itk image exporter and vtk image importer, then connect their pipelines vtkSmartPointer<vtkImageImport> vtkimporter = vtkSmartPointer<vtkImageImport>::New(); ExportFilterType::Pointer itkexporter = ExportFilterType::New(); connectPipelines(itkexporter,(vtkImageImport *)vtkimporter); //Using Marching cubes as a contour filter vtkSmartPointer<vtkMarchingCubes> contourf = vtkSmartPointer<vtkMarchingCubes>::New(); contourf->SetInput(vtkimporter->GetOutput()); contourf->SetValue(0,127); contourf->ComputeNormalsOff(); contourf->ComputeScalarsOff(); contourf->ComputeGradientsOff(); //Using vtkSmoothPolyDataFilter as an initial smoothing filter vtkSmartPointer<vtkSmoothPolyDataFilter> smoothf = vtkSmartPointer<vtkSmoothPolyDataFilter>::New(); smoothf->SetInput(contourf->GetOutput()); smoothf->SetRelaxationFactor(0.3); smoothf->SetNumberOfIterations(20); //Set up polydata transform vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New(); transform->PostMultiply(); transform->Identity(); vtkSmartPointer<vtkTransformPolyDataFilter> tf = vtkSmartPointer<vtkTransformPolyDataFilter>::New(); tf->SetTransform(transform); tf->SetInput(smoothf->GetOutput()); vtkSmartPointer<vtkAppendPolyData> appendfilter = vtkSmartPointer<vtkAppendPolyData>::New(); //Generate empty image, and iterate through the cells, filling the image inputImageType::Pointer t = getEmptyImage(wx,wy,wz); for(int counter=1; counter<=max1; counter++) { 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()); appendfilter->AddInput(pol); printf("Completed %d/%d\r",counter,max1); } appendfilter->Update(); //Decimate filter (reduces the number of triangles in the mesh) for the poly data vtkSmartPointer<vtkDecimatePro> decimate = vtkSmartPointer<vtkDecimatePro>::New(); decimate->SetInput(appendfilter->GetOutput()); decimate->SetTargetReduction(0.75); printf("Decimating the contours..."); decimate->Update(); printf("Done\n"); //Smooth poly data filter for a final smoothing printf("Smoothing the contours after decimation..."); vtkSmartPointer<vtkSmoothPolyDataFilter> smoothfinal = vtkSmartPointer<vtkSmoothPolyDataFilter>::New(); smoothfinal->SetRelaxationFactor(0.2); smoothfinal->SetInput(decimate->GetOutput()); smoothfinal->SetNumberOfIterations(0); smoothfinal->Update(); printf("Done\n"); //Return processed poly data vtkSmartPointer<vtkPolyData> out = smoothfinal->GetOutput(); return out; }