void Filter() { XSum += X_Axis - XBuffer[index]; // Subtract out the oldest value in samples from sums YSum += Y_Axis - YBuffer[index]; // and add in the new value to sum ZSum += Z_Axis - ZBuffer[index]; XBuffer[index] = X_Axis; // Set oldest value to the new current reading YBuffer[index] = Y_Axis; ZBuffer[index] = Z_Axis; index++; // Increment the positition of the oldest value in samples if (index == NUM_SAMPLES) // Reset the index to 0 if it equals NUM_SAMPLES index = 0; ComputeAverage(); // Update averages }
/* 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; }