LabelImageType::Pointer getYousefSegmented(InputImageType::Pointer im_input,std::list<Seed> &seed_list,char *filename) { // copy the image into a unsigned char * char configfile[1024]; strcpy(configfile,filename); printf("Entering YousefSeg\n"); InputImageType::SizeType size = im_input->GetLargestPossibleRegion().GetSize(); unsigned char * in_Image; in_Image = (unsigned char*) malloc( size[0]*size[1]*(size[2]+1)*sizeof(unsigned char)); if(in_Image == NULL) { printf("Couldn't allocate memory\n"); } memset(in_Image,0,size[0]*size[1]*(size[2]+1)*sizeof(unsigned char)); ConstIteratorType pix_buf(im_input,im_input->GetLargestPossibleRegion()); int ind = 0; for ( pix_buf.GoToBegin(); !pix_buf.IsAtEnd(); ++pix_buf, ++ind ) in_Image[ind]=(pix_buf.Get()); printf("Copied input data\n"); yousef_nucleus_seg *NucleusSeg = new yousef_nucleus_seg(); NucleusSeg->readParametersFromFile(configfile); NucleusSeg->setDataImage(in_Image,size[0],size[1],size[2]+1,"null"); unsigned short * output_img; // int *bounds_img; NucleusSeg->runBinarization(); output_img = NucleusSeg->getBinImage(); // getITKImage(output_img); // getProcessedBinaryImage( NucleusSeg->runSeedDetection(); std::vector<Seed> seeds = NucleusSeg->getSeeds(); printf("In yousef_seg Seed size = %d\n", (int)seeds.size()); std::vector<Seed>::iterator iter = seeds.begin(); for(;iter!=seeds.end();iter++) { seed_list.push_back(*iter); } NucleusSeg->runClustering(); printf("Finished Clustering\n"); if(NucleusSeg->isSegmentationFinEnabled()) { NucleusSeg->runAlphaExpansion3D(); output_img=NucleusSeg->getSegImage(); } else { output_img=NucleusSeg->getClustImage(); } // bounds_img = NucleusSeg->getBoundsImage(); printf("Finished segmentation\n"); LabelImageType::Pointer label = LabelImageType::New(); label->SetRegions(im_input->GetLargestPossibleRegion()); label->Allocate(); LabelIteratorType liter(label,label->GetLargestPossibleRegion()); ind = 0; for(liter.GoToBegin();!liter.IsAtEnd();++liter,++ind) { liter.Set(output_img[ind]); } delete NucleusSeg; free(in_Image); return label; }
int main(int argc, char **argv) { if(argc <5) { std::cout<<"Usage: mixture_segment <MixtureLabelImageFileName> <OutputMixtureLabelImageFileName> <volume1> <volume2>\n"; return 0; } // read the parameters // std::string ifName = argv[1]; std::string ofName = argv[2]; unsigned int volume1 = atoi(argv[3]); // minimum area1 of the large components unsigned int volume2 = atoi(argv[4]); // minimum area2 of the small components ( heads of the cells ) printf("volume1: %d\t",volume1); printf("volume2: %d\n",volume2); // read input image: LabelImageType::Pointer mixtureLabelImage = readImage<LabelImageType>(ifName.c_str()); LabelPixelType nr = mixtureLabelImage->GetLargestPossibleRegion().GetSize()[0]; LabelPixelType nc = mixtureLabelImage->GetLargestPossibleRegion().GetSize()[1]; LabelPixelType ns = mixtureLabelImage->GetLargestPossibleRegion().GetSize()[2]; LabelPixelType * mixtureLabelImagePtr = mixtureLabelImage->GetBufferPointer(); //generate label image LabelImageType::SizeType size; size[0] = nr; size[1] = nc; size[2] = ns; LabelImageType::Pointer outputImage = GetITKImageOfSize<LabelImageType>(size); LabelPixelType * outputImagePtr = outputImage->GetBufferPointer(); // parameters for 2D image LabelImageType::SizeType sz2; sz2[0] = nr; sz2[1] = nc; sz2[2] = 1; unsigned int sz = nr*nc; //bool FoundLabel = true; omp_set_num_threads(1); itk::MultiThreader::SetGlobalDefaultNumberOfThreads(1); #pragma omp parallel for num_threads(80) for(size_t t = 0; t<ns; ++t) { LabelImageType::Pointer output2DImage = GetITKImageOfSize<LabelImageType>(sz2); LabelPixelType * output2DImagePtr = output2DImage->GetBufferPointer(); unsigned int i; LabelImageType::Pointer binaryLabelImage = GetITKImageOfSize<LabelImageType>(sz2); LabelPixelType * binaryLabelImagePtr = binaryLabelImage->GetBufferPointer(); size_t offset = t*((nr*nc)); // first mixture for(i = 0; i < sz; ++i) { if(mixtureLabelImagePtr[i+offset]>0) { binaryLabelImagePtr[i] = 1; //printf("set pixel to one\n"); } else { binaryLabelImagePtr[i] = 0; } } // well size is 90x90: if any of the connected components is larger than that it meas something went wrong with the segmnetation // bool isEmpty = CleanImage(binaryLabelImage,6000); bool isEmpty = false; if(!isEmpty) { RemoveSmallComponents(binaryLabelImage, volume1); // copy the clean image to the output for(i = 0; i < sz; ++i) { if(binaryLabelImagePtr[i]>0) { output2DImagePtr[i] +=1; //printf("added\n"); } } // second mixture for(i = 0; i < sz; ++i) { if(mixtureLabelImagePtr[i+offset]>1) { binaryLabelImagePtr[i] = 1; } else { binaryLabelImagePtr[i] = 0; } } RemoveSmallComponents(binaryLabelImage, volume2); // copy the clean image to the output for(i = 0; i < sz; ++i) { if(binaryLabelImagePtr[i]>0) { output2DImagePtr[i] +=1; //printf("added2\n"); } } }// end of if statement for(i=0 ; i<sz ; ++i) outputImagePtr[i+offset] = output2DImagePtr[i]; } // end of time loop writeImage<LabelImageType>(outputImage, ofName.c_str()); return 0; }
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; }
//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; }