/* use this function to compute one associative measurement */
float NuclearAssociationRules::ComputeOneAssocMeasurement(itk::SmartPointer<TargImageType> trgIm, int ruleID, int objID)
{	
	//fisrt, get the bounding box around the object
	//The bounding box is defined by the area around the object such that the object+outerdistance are included	
	int imBounds[6] = {0,x_Size,0,y_Size,0,z_Size};
	LabelGeometryType::BoundingBoxType bbox = labGeometryFilter->GetBoundingBox(objID);
	//make sure the object exists
	int valid = 0;
	for(int dim=0; dim < imDim*2; ++dim)
	{
		if(bbox[dim] > 0)
			valid = 1;
	}
	if(valid == 0)
		return -1;

	std::vector< int > retBbox(0);
	int dist, val;
	dist = assocRulesList[ruleID].GetOutDistance();
	for(int dim=0; dim < imDim*2; ++dim)
	{  
		if(dim%2 == 0) //even
		{			
			val = int(bbox[dim])-dist-1;
			if(val<imBounds[dim])
				val=imBounds[dim];
		}
		else //odd
		{
			val = int(bbox[dim])+dist+1;
			if(val>=imBounds[dim])
				val=imBounds[dim]-1;
		}
		retBbox.push_back( val );
	}

	//the bounding box defines the region of interest we need (from both segmentation and target images)
	//so, use it to get sub images
	DistImageType::Pointer subSegImg = DistImageType::New();
	
	LabImageType::IndexType start;
    start[0] =   0;  // first index on X
    start[1] =   0;  // first index on Y    
	start[2] =   0;  // first index on Z    
	
    LabImageType::SizeType  size;
    size[0]  = retBbox[1]-retBbox[0]+1;  // size along X
    size[1]  = retBbox[3]-retBbox[2]+1;  // size along Y
	if(imDim == 3)
		size[2]  = retBbox[5]-retBbox[4]+1;  // size along Z
	else
		size[2] = 1;
  
    LabImageType::RegionType region;
    region.SetSize( size );
    region.SetIndex( start );
	subSegImg->SetRegions( region );	
    subSegImg->Allocate();
    subSegImg->FillBuffer(0);
	subSegImg->Update();	
	

	LabImageType::IndexType start2;
    start2[0] =   retBbox[0];  // first index on X
    start2[1] =   retBbox[2];  // first index on Y    
	if(imDim == 3)
		start2[2] =   retBbox[4];  // first index on Z   
	else
		start2[2] = 0;
	LabImageType::RegionType region2;
    region2.SetSize( size );
    region2.SetIndex( start2 );
	labImage->SetRequestedRegion(region2);
	trgIm->SetRequestedRegion(region2);

	typedef itk::ImageRegionIteratorWithIndex< LabImageType > IteratorType;	
	IteratorType iterator1(labImage, labImage->GetRequestedRegion());
	typedef itk::ImageRegionIteratorWithIndex< DistImageType > IteratorType2;	
	IteratorType2 iterator2(subSegImg, subSegImg->GetRequestedRegion());

	//in the sub-segmentation image, we need to mask out any pixel from another object	
	int counter = 0;
	while ( ! iterator1.IsAtEnd())
	{		
		int V = iterator1.Get();
		if(V == objID)
		{
			iterator2.Set(255.0);
			counter++; //just for debuging purposes,, will be removed
		}
		else
			iterator2.Set(0.0);
		++iterator1;
		++iterator2;		
	}	
	//Let's try this (for debugging): save the binary mask
	/*	typedef itk::Image< unsigned short, 3 > OutputImageType;
		typedef itk::CastImageFilter< DistImageType, OutputImageType > CastType; 
		CastType::Pointer cast = CastType::New(); 
		cast->SetInput( subSegImg ); 
		cast->Update(); 

		typedef itk::ImageFileWriter< OutputImageType > WriterType; 
		WriterType::Pointer writer = WriterType::New( ); 
		writer->SetInput( cast->GetOutput() ); 
		writer->SetFileName( "c:/bin_mask.tif" ); 
		writer->Update(); */

	//Compute the distance transform in the sub-segmentation image region	
	DTFilter::Pointer dt_obj= DTFilter::New() ;
	dt_obj->SetInput(subSegImg) ;
	//dt_obj->SetInsideValue(255.0);
	//dt_obj->SetOutsideValue(0.0);	
	try{
		dt_obj->Update() ;
	}
	catch( itk::ExceptionObject & err ){
		std::cout << "Error in Distance Transform: " << err << std::endl; 
		return 0;	
	}

	//Let's try this (for debugging): save the distance map
		////typedef itk::Image< unsigned short, 3 > OutputImageType;
		////typedef itk::CastImageFilter< DistImageType, OutputImageType > CastType; 
		////CastType::Pointer cast = CastType::New(); 
		//cast->SetInput( dt_obj->GetOutput() ); 
		//cast->Update(); 

		////typedef itk::ImageFileWriter< OutputImageType > WriterType; 
		////WriterType::Pointer writer = WriterType::New( ); 
		//writer->SetInput( cast->GetOutput() ); 
		//writer->SetFileName( "c:/dist_map.tif" ); 
		//writer->Update(); 
	
	//now, mask out all the pixels (in the sub-seg image) that are not in the region of interest as defined by the association rule and get the intensities of the needed pixels from the target image. The intensities are saved into an std vector
	IteratorType2 iterator3(dt_obj->GetOutput(), dt_obj->GetOutput()->GetRequestedRegion());
	IteratorType iterator4(trgIm, trgIm->GetRequestedRegion());
	std::vector<int> trgInt;
	int counter_in = 0;
	int counter_at = 0;
	int counter_ot = 0;
	while ( ! iterator3.IsAtEnd())
	{
		int V = (int)iterator3.Get();
		if(V<0)
			counter_in++;
		if(V==0)
			counter_at++;
		if(V>0)
			counter_ot++;
		//if it is outside with distance less than outDistance away
		if(V>0 && V<=assocRulesList[ruleID].GetOutDistance())
			trgInt.push_back(iterator4.Get());
		//if it is inside and the whole cell is used
		else if(V<=0 && assocRulesList[ruleID].IsUseWholeObject())
			trgInt.push_back(iterator4.Get());
		//if it is inside with distance less than in Distance
		else if(V<=0 && abs(V)<=assocRulesList[ruleID].GetInDistance())
			trgInt.push_back(iterator4.Get());

		++iterator3;
		++iterator4;
	}
	if(!trgInt.size())
		return 0;
	
	//Finally, given the list of intensities compute the associative measrement based on the type defined by the association rule
	switch(assocRulesList[ruleID].GetAssocType())
	{
		case ASSOC_MIN:
			return FindMin(trgInt);
			break;
		case ASSOC_MAX:
			return FindMax(trgInt);
			break;
		case ASSOC_TOTAL:
			return ComputeTotal(trgInt);
			break;
		case ASSOC_AVERAGE:
			return ComputeAverage(trgInt);
			break;
		default:
			return ComputeAverage(trgInt);
	}	
  //we will never go here, just silencing a compiler warning
  return 0.0;
}
Example #2
0
USImageType::PixelType returnthresh( itk::SmartPointer<USImageType> input_image,
			     int num_bin_levs, int num_in_fg ){
	//Instantiate the different image and filter types that will be used
	typedef itk::ImageRegionConstIterator< USImageType > ConstIteratorType;
	typedef itk::Statistics::Histogram< float > HistogramType;
	typedef itk::OtsuMultipleThresholdsCalculator< HistogramType > CalculatorType;

	std::cout<<"Starting threshold computation\n";

	//Create a temporary histogram container:
	const int numBins = itk::NumericTraits<USImageType::PixelType>::max();
	double *tempHist;
	tempHist = (double*) malloc( sizeof(double) * numBins );
	for(USImageType::PixelType i=0; i<numBins; ++i)
		tempHist[i] = 0;

	USImageType::PixelType maxval = itk::NumericTraits<USImageType::PixelType>::ZeroValue();
	USImageType::PixelType minval = itk::NumericTraits<USImageType::PixelType>::max();
	//Populate the histogram (assume pixel type is actually is some integer type):
	ConstIteratorType it( input_image, input_image->GetRequestedRegion() );
	for ( it.GoToBegin(); !it.IsAtEnd(); ++it ){
		USImageType::PixelType pix = it.Get();
		++tempHist[pix];
		if( pix > maxval ) maxval = pix;
		if( pix < minval ) minval = pix;
	}
	//return max of type if there is no variation in the staining
	if( (maxval-minval)<3 ) return itk::NumericTraits<USImageType::PixelType>::max(); 
	const USImageType::PixelType numBinsPresent = maxval+1;
	
	//Find max value in the histogram
	double floatIntegerMax = itk::NumericTraits<USImageType::PixelType>::max();
	double max = 0.0;
	for(USImageType::PixelType i=0; i<numBinsPresent; ++i)
		if( tempHist[i] > max )
			max = tempHist[i];

	double scaleFactor = 1;
	if(max >= floatIntegerMax)
		scaleFactor = floatIntegerMax / max;

	HistogramType::Pointer histogram = HistogramType::New() ;
	// initialize histogram
	HistogramType::SizeType size;
	HistogramType::MeasurementVectorType lowerBound;
	HistogramType::MeasurementVectorType upperBound;

	lowerBound.SetSize(1);
	upperBound.SetSize(1);
	size.SetSize(1);

	lowerBound.Fill(0.0);
	upperBound.Fill((double)maxval);
	size.Fill(numBinsPresent);

	histogram->SetMeasurementVectorSize(1);
	histogram->Initialize(size, lowerBound, upperBound ) ;

	USImageType::PixelType i=0;
	for (HistogramType::Iterator iter = histogram->Begin(); iter != histogram->End(); ++iter ){
		float norm_freq = (float)(tempHist[i] * scaleFactor);
		iter.SetFrequency(norm_freq);
		++i;
	}

	std::cout<<"Histogram computed\n";

	CalculatorType::Pointer calculator = CalculatorType::New();
	calculator->SetNumberOfThresholds( num_bin_levs );
	calculator->SetInputHistogram( histogram );
	calculator->Update();
	const CalculatorType::OutputType &thresholdVector = calculator->GetOutput(); 
	CalculatorType::OutputType::const_iterator itNum = thresholdVector.begin();

	float thresh;

	for(USImageType::PixelType i=0; i < num_in_fg; ++itNum, ++i)
		thresh = (static_cast<float>(*itNum));

	std::cout<<"Threshold computed: "<<thresh<<std::endl;

	return (USImageType::PixelType)(thresh+0.5);
}