void octree::generate ( volume_ptr const& volume, std::vector<face_ptr> const& faces, split_traversal const& splitter, volume_type::boundingbox_type::value_type const& border_offset_percentage ) { // store pointer to object octree is built for _object = volume; // border set bbox _boundingbox.min = volume->bbox().min - border_offset_percentage * volume->bbox().size(); _boundingbox.max = volume->bbox().max + border_offset_percentage * volume->bbox().size(); // create new root-node _root.reset( new ocnode ( std::shared_ptr<node>(), 0, uid::generate("ocnode") ) ); // add all found faces to root node std::for_each ( faces.begin(), faces.end(), std::bind(&ocnode::add_face, std::ref(_root), std::placeholders::_1) ); // apply volume's geometric bounding box to node _root->boundingbox ( _boundingbox ); // apply volume attribute range to root node std::string attribute_name = *(volume->parent()->attribute_list().begin()); nurbsvolumeobject::attribute_boundingbox attribute_range = volume->parent()->bbox ( attribute_name ); _root->range ( ocnode::interval_t ( attribute_range.min[0], attribute_range.max[0] ) ); // start splitting process _root->accept ( splitter ); }
inline bool write_volume_to_file( const std::string& fname, const volume_ptr<T>& vol ) { std::ofstream f(fname.c_str(), (std::ios::out | std::ios::binary) ); if ( !f ) { return false; } f.write( reinterpret_cast<char*>(vol->data()), vol->shape()[0] * vol->shape()[1] * vol->shape()[2] * sizeof(T)); return true; }
inline void merge_segments_with_function( const volume_ptr<ID>& seg_ptr, const region_graph_ptr<ID,F> rg_ptr, std::vector<std::size_t>& counts, const FN& func, const M& lowt ) { zi::disjoint_sets<ID> sets(counts.size()); region_graph<ID,F>& rg = *rg_ptr; for ( auto& it: rg ) { std::size_t size = func(std::get<0>(it)); if ( size == 0 ) { break; } ID s1 = sets.find_set(std::get<1>(it)); ID s2 = sets.find_set(std::get<2>(it)); if ( s1 != s2 && s1 && s2 ) { if ( (counts[s1] < size) || (counts[s2] < size) ) { counts[s1] += counts[s2]; counts[s2] = 0; ID s = sets.join(s1,s2); std::swap(counts[s], counts[s1]); } } } std::cout << "Done with merging" << std::endl; std::vector<ID> remaps(counts.size()); ID next_id = 1; std::size_t low = static_cast<std::size_t>(lowt); for ( ID id = 0; id < counts.size(); ++id ) { ID s = sets.find_set(id); if ( s && (remaps[s] == 0) && (counts[s] >= low) ) { remaps[s] = next_id; counts[next_id] = counts[s]; ++next_id; } } counts.resize(next_id); std::ptrdiff_t xdim = seg_ptr->shape()[0]; std::ptrdiff_t ydim = seg_ptr->shape()[1]; std::ptrdiff_t zdim = seg_ptr->shape()[2]; std::ptrdiff_t total = xdim * ydim * zdim; ID* seg_raw = seg_ptr->data(); for ( std::ptrdiff_t idx = 0; idx < total; ++idx ) { seg_raw[idx] = remaps[sets.find_set(seg_raw[idx])]; } std::cout << "Done with remapping, total: " << (next_id-1) << std::endl; region_graph<ID,F> new_rg; for ( auto& it: rg ) { ID s1 = remaps[sets.find_set(std::get<1>(it))]; ID s2 = remaps[sets.find_set(std::get<2>(it))]; if ( s1 != s2 && s1 && s2 ) { auto mm = std::minmax(s1,s2); new_rg.emplace_back(std::get<0>(it), mm.first, mm.second); } } rg.swap(new_rg); std::cout << "Done with updating the region graph, size: " << rg.size() << std::endl; }
inline std::vector<double> merge_segments_with_function_err( const volume_ptr<ID>& seg_ptr, const volume_ptr<ID>& gt_ptr, const region_graph_ptr<ID,F> rg_ptr, std::vector<std::size_t>& counts, const FN& func, const M& lowt ) { std::vector<double> ret; std::ptrdiff_t xdim = seg_ptr->shape()[0]; std::ptrdiff_t ydim = seg_ptr->shape()[1]; std::ptrdiff_t zdim = seg_ptr->shape()[2]; volume<ID>& seg = *seg_ptr; volume<ID>& gt = *gt_ptr; zi::disjoint_sets<ID> sets(counts.size()); std::size_t tot = 0; std::vector<std::size_t> s_i(counts.size()); std::map<ID,std::size_t> t_j; std::vector<std::map<ID,std::size_t>> p_ij(counts.size()); for ( std::ptrdiff_t z = 0; z < zdim; ++z ) for ( std::ptrdiff_t y = 0; y < ydim; ++y ) for ( std::ptrdiff_t x = 0; x < xdim; ++x ) { uint32_t sgv = seg[x][y][z]; uint32_t gtv = gt[x][y][z]; if ( gtv ) { tot += 1; ++p_ij[sgv][gtv]; ++s_i[sgv]; ++t_j[gtv]; } } double sum_p_ij = 0; for ( auto& a: p_ij ) { for ( auto& b: a ) { sum_p_ij += (static_cast<double>(b.second) / tot) * (static_cast<double>(b.second) / tot); } } double sum_t_k = 0; for ( auto& a: t_j ) { sum_t_k += (static_cast<double>(a.second) / tot) * (static_cast<double>(a.second) / tot); } double sum_s_k = 0; for ( auto& a: s_i ) { sum_s_k += (static_cast<double>(a) / tot) * (static_cast<double>(a) / tot); } ret.push_back(sum_p_ij/sum_t_k); ret.push_back(sum_p_ij/sum_s_k); region_graph<ID,F>& rg = *rg_ptr; int mod = 0; F minf = 0; for ( auto& it: rg ) { std::size_t size = func(std::get<0>(it)); if ( size == 0 ) { minf = std::get<0>(it); break; } ID s1 = sets.find_set(std::get<1>(it)); ID s2 = sets.find_set(std::get<2>(it)); if ( s1 != s2 && s1 && s2 ) { if ( (counts[s1] < size) || (counts[s2] < size) ) { counts[s1] += counts[s2]; counts[s2] = 0; sum_s_k -= (static_cast<double>(s_i[s1])/tot) * (static_cast<double>(s_i[s1])/tot); sum_s_k -= (static_cast<double>(s_i[s2])/tot) * (static_cast<double>(s_i[s2])/tot); s_i[s1] += s_i[s2]; s_i[s2] = 0; sum_s_k += (static_cast<double>(s_i[s1])/tot) * (static_cast<double>(s_i[s1])/tot); for ( auto& b: p_ij[s1] ) { sum_p_ij -= (static_cast<double>(b.second) / tot) * (static_cast<double>(b.second) / tot); } for ( auto& b: p_ij[s2] ) { sum_p_ij -= (static_cast<double>(b.second) / tot) * (static_cast<double>(b.second) / tot); p_ij[s1][b.first] += b.second; } for ( auto& b: p_ij[s1] ) { sum_p_ij += (static_cast<double>(b.second) / tot) * (static_cast<double>(b.second) / tot); } p_ij[s2].clear(); if ( (++mod) % 100 == 0 ) { //std::cout << "Now Error: " << (sum_p_ij/sum_t_k) << " " // << (sum_p_ij/sum_s_k) << "\n"; ret.push_back(sum_p_ij/sum_t_k); ret.push_back(sum_p_ij/sum_s_k); } ID s = sets.join(s1,s2); std::swap(counts[s], counts[s1]); std::swap(s_i[s], s_i[s1]); std::swap(p_ij[s], p_ij[s1]); } } } std::cout << "Done with merging" << std::endl; for ( auto& it: rg ) { break; if ( minf > std::get<0>(it) ) { break; } ID s1 = sets.find_set(std::get<1>(it)); ID s2 = sets.find_set(std::get<2>(it)); if ( s1 != s2 && s1 && s2 ) { //if ( (counts[s1] < 100) || (counts[s2] < 100) ) { counts[s1] += counts[s2]; counts[s2] = 0; sum_s_k -= (static_cast<double>(s_i[s1])/tot) * (static_cast<double>(s_i[s1])/tot); sum_s_k -= (static_cast<double>(s_i[s2])/tot) * (static_cast<double>(s_i[s2])/tot); s_i[s1] += s_i[s2]; s_i[s2] = 0; sum_s_k += (static_cast<double>(s_i[s1])/tot) * (static_cast<double>(s_i[s1])/tot); for ( auto& b: p_ij[s1] ) { sum_p_ij -= (static_cast<double>(b.second) / tot) * (static_cast<double>(b.second) / tot); } for ( auto& b: p_ij[s2] ) { sum_p_ij -= (static_cast<double>(b.second) / tot) * (static_cast<double>(b.second) / tot); p_ij[s1][b.first] += b.second; } for ( auto& b: p_ij[s1] ) { sum_p_ij += (static_cast<double>(b.second) / tot) * (static_cast<double>(b.second) / tot); } p_ij[s2].clear(); //if ( (++mod) % 100 == 0 ) std::cout << "Now Error: " << (sum_p_ij/sum_t_k) << " " << (sum_p_ij/sum_s_k) << "\n"; ret.push_back(sum_p_ij/sum_t_k); ret.push_back(sum_p_ij/sum_s_k); ID s = sets.join(s1,s2); std::swap(counts[s], counts[s1]); std::swap(s_i[s], s_i[s1]); std::swap(p_ij[s], p_ij[s1]); } } } std::cout << "Done with merging" << std::endl; std::vector<ID> remaps(counts.size()); ID next_id = 1; std::size_t low = static_cast<std::size_t>(lowt); for ( ID id = 0; id < counts.size(); ++id ) { ID s = sets.find_set(id); if ( s && (remaps[s] == 0) && (counts[s] >= low) ) { remaps[s] = next_id; counts[next_id] = counts[s]; ++next_id; } } counts.resize(next_id); std::ptrdiff_t total = xdim * ydim * zdim; ID* seg_raw = seg_ptr->data(); for ( std::ptrdiff_t idx = 0; idx < total; ++idx ) { seg_raw[idx] = remaps[sets.find_set(seg_raw[idx])]; } std::cout << "Done with remapping, total: " << (next_id-1) << std::endl; region_graph<ID,F> new_rg; std::vector<std::set<ID>> in_rg; for ( auto& it: rg ) { ID s1 = remaps[sets.find_set(std::get<1>(it))]; ID s2 = remaps[sets.find_set(std::get<2>(it))]; if ( s1 != s2 && s1 && s2 ) { auto mm = std::minmax(s1,s2); if ( in_rg[mm.first].count(mm.second) == 0 ) { new_rg.emplace_back(std::get<0>(it), mm.first, mm.second); in_rg[mm.first].insert(mm.second); } } } rg.swap(new_rg); std::cout << "Done with updating the region graph, size: " << rg.size() << std::endl; return ret; }
inline void merge_segments( const volume_ptr<ID>& seg_ptr, const region_graph_ptr<ID,F> rg_ptr, std::vector<std::size_t>& counts, const L& tholds, const M& lowt ) { zi::disjoint_sets<ID> sets(counts.size()); typename region_graph<ID,F>::iterator rit = rg_ptr->begin(); region_graph<ID,F>& rg = *rg_ptr; for ( auto& it: tholds ) { std::size_t size = static_cast<std::size_t>(it.first); F thld = static_cast<F>(it.second); while ( (rit != rg.end()) && ( std::get<0>(*rit) > thld) ) { ID s1 = sets.find_set(std::get<1>(*rit)); ID s2 = sets.find_set(std::get<2>(*rit)); if ( s1 != s2 && s1 && s2 ) { if ( (counts[s1] < size) || (counts[s2] < size) ) { counts[s1] += counts[s2]; counts[s2] = 0; ID s = sets.join(s1,s2); std::swap(counts[s], counts[s1]); } } ++rit; } } std::cout << "Done with merging" << std::endl; std::vector<ID> remaps(counts.size()); ID next_id = 1; std::size_t low = static_cast<std::size_t>(lowt); for ( ID id = 0; id < counts.size(); ++id ) { ID s = sets.find_set(id); if ( s && (remaps[s] == 0) && (counts[s] >= low) ) { remaps[s] = next_id; counts[next_id] = counts[s]; ++next_id; } } counts.resize(next_id); std::ptrdiff_t xdim = seg_ptr->shape()[0]; std::ptrdiff_t ydim = seg_ptr->shape()[1]; std::ptrdiff_t zdim = seg_ptr->shape()[2]; std::ptrdiff_t total = xdim * ydim * zdim; ID* seg_raw = seg_ptr->data(); for ( std::ptrdiff_t idx = 0; idx < total; ++idx ) { seg_raw[idx] = remaps[sets.find_set(seg_raw[idx])]; } std::cout << "Done with remapping, total: " << (next_id-1) << std::endl; region_graph<ID,F> new_rg; std::vector<std::set<ID>> in_rg; for ( auto& it: rg ) { ID s1 = remaps[sets.find_set(std::get<1>(it))]; ID s2 = remaps[sets.find_set(std::get<2>(it))]; if ( s1 != s2 && s1 && s2 ) { auto mm = std::minmax(s1,s2); if ( in_rg[mm.first].count(mm.second) == 0 ) { new_rg.emplace_back(std::get<0>(it), mm.first, mm.second); in_rg[mm.first].insert(mm.second); } } } rg.swap(new_rg); std::cout << "Done with updating the region graph, size: " << rg.size() << std::endl; }
inline void yet_another_watershed( const volume_ptr<ID>& seg_ptr, const region_graph_ptr<ID,F> rg_ptr, std::vector<std::size_t>& counts, const L& lowl) { F low = static_cast<F>(lowl); std::vector<std::size_t> new_counts({0}); std::vector<ID> remaps(counts.size()); zi::disjoint_sets<ID> sets(counts.size()); std::vector<F> maxs(counts.size()); region_graph<ID,F>& rg = *rg_ptr; ID next_id = 1; ID merged = 0; for ( auto& it: rg ) { if ( std::get<0>(it) <= low ) { break; } ID s1 = std::get<1>(it); ID s2 = std::get<2>(it); F f = std::get<0>(it); if ( s1 && s2 ) { if ( (remaps[s1] == 0) || (remaps[s2] == 0) ) { if ( remaps[s1] == 0 ) { std::swap(s1,s2); } if ( remaps[s1] == 0 ) { maxs[next_id] = f; remaps[s1] = remaps[s2] = next_id; new_counts.push_back(counts[s1]+counts[s2]); ++next_id; } else { ID actual = sets.find_set(remaps[s1]); remaps[s2] = remaps[s1]; new_counts[actual] += counts[s2]; } } else { ID a1 = sets.find_set(remaps[s1]); ID a2 = sets.find_set(remaps[s2]); if ( 0 && a1 != a2 && ((maxs[a1]==f)||(maxs[a2]==f)) ) { ++merged; new_counts[a1] += new_counts[a2]; new_counts[a2] = 0; maxs[a1] = std::max(maxs[a1],maxs[a2]); maxs[a2] = 0; ID a = sets.join(a1,a2); std::swap(new_counts[a], new_counts[a1]); std::swap(maxs[a], maxs[a1]); } } } } next_id -= merged; std::vector<ID> remaps2(counts.size()); next_id = 1; for ( ID id = 0; id < counts.size(); ++id ) { ID s = sets.find_set(remaps[id]); if ( s && (remaps2[s]==0) ) { remaps2[s] = next_id; new_counts[next_id] = new_counts[s]; ++next_id; } } new_counts.resize(next_id); std::ptrdiff_t xdim = seg_ptr->shape()[0]; std::ptrdiff_t ydim = seg_ptr->shape()[1]; std::ptrdiff_t zdim = seg_ptr->shape()[2]; std::ptrdiff_t total = xdim * ydim * zdim; ID* seg_raw = seg_ptr->data(); for ( std::ptrdiff_t idx = 0; idx < total; ++idx ) { seg_raw[idx] = remaps2[remaps[seg_raw[idx]]]; } region_graph<ID,F> new_rg; for ( auto& it: rg ) { ID s1 = remaps2[remaps[std::get<1>(it)]]; ID s2 = remaps2[remaps[std::get<2>(it)]]; if ( s1 != s2 && s1 && s2 ) { auto mm = std::minmax(s1,s2); new_rg.emplace_back(std::get<0>(it), mm.first, mm.second); } } rg.swap(new_rg); counts.swap(new_counts); std::cout << "New count: " << counts.size() << std::endl; std::cout << "Done with updating the region graph, size: " << rg.size() << std::endl; }