//#################### PRIVATE METHODS #################### void SpleenIdentifier3D::execute_impl() { set_status("Identifying spleen..."); VolumeIPFMultiFeatureSelection_Ptr multiFeatureSelection = get_multi_feature_selection(); // Step 1: Filter for spleen candidates. std::list<PFNodeID> candidates = filter_branch_nodes(boost::bind(&SpleenIdentifier3D::is_candidate, this, _1, _2)); // Step 2: Pick the best candidate (namely, the one which stretches furthest to the right of the image). PFNodeID bestCandidate; int bestXMax = INT_MIN; for(std::list<PFNodeID>::const_iterator it=candidates.begin(), iend=candidates.end(); it!=iend; ++it) { const BranchProperties& properties = volume_ipf()->branch_properties(*it); if(properties.x_max() > bestXMax) { bestCandidate = *it; bestXMax = properties.x_max(); } } // If we can't find a candidate spleen, exit. if(bestCandidate == PFNodeID::invalid()) return; // Step 3: (TEMPORARY) Mark the best candidate as spleen (and unmark it as liver if necessary). multiFeatureSelection->identify_node(bestCandidate, AbdominalFeature::SPLEEN); multiFeatureSelection->unidentify_node(bestCandidate, AbdominalFeature::LIVER); }
//#################### PRIVATE METHODS #################### void SpineIdentifier3D::execute_impl() { set_status("Identifying the spine..."); VolumeIPFMultiFeatureSelection_Ptr multiFeatureSelection = get_multi_feature_selection(); // Step 1: Filter for spine. std::list<PFNodeID> nodes = filter_branch_nodes(boost::bind(&SpineIdentifier3D::is_spine, this, _1, _2)); // Step 2: Convert the partition forest candidate nodes to positions in the volume. std::set<int> leaves; for(std::list<PFNodeID>::const_iterator it=nodes.begin(), iend=nodes.end(); it!=iend; ++it) { std::deque<int> leafIndices = volume_ipf()->receptive_region_of(*it); for(std::deque<int>::const_iterator jt=leafIndices.begin(), jend=leafIndices.end(); jt!=jend; ++jt) { leaves.insert(*jt); } } std::list<itk::Index<3> > positions; for(std::set<int>::const_iterator it=leaves.begin(), iend=leaves.end(); it!=iend; ++it) { if(210 < volume_ipf()->leaf_properties(*it).grey_value()) { positions.push_back(volume_ipf()->position_of_leaf(*it)); } } increment_progress(); // Step 3: Use the Fast Marching Method. FastMarching<3> fm(volume_ipf()->leaf_layer()->gradient_magnitude_image(), positions); positions = fm.get_shape_at_time(100.0); increment_progress(); // Step 4: Convert the positions in the volume to partition forest selection. leaves.clear(); for(std::list<itk::Index<3> >::const_iterator it=positions.begin(), iend=positions.end(); it!=iend; ++it) { leaves.insert(volume_ipf()->leaf_of_position(*it)); } PartitionForestSelection_Ptr region(new PartitionForestSelectionT(volume_ipf(), leaves)); // Step 5: Mark the results as spine. multiFeatureSelection->identify_selection(region, AbdominalFeature::VERTEBRA); }