/* Begin Funtion Definitions */ int main (int argc, const char * argv[]) { cl_int error; GPUInit(&context, &queue, &is_nvidia, &program, "remap_kern.cl"); cHash_kernel = clCreateKernel(program, "cellHash_kern", &error); remap1_kernel = clCreateKernel(program, "remap1_kern", &error); printf(" REMAP\n\n"); if (is_nvidia) printf("size, Brute Force, CPU kD Tree, CPU Hash1, CPU Hash2, NVIDIA Hash1\n"); else printf("size, Brute Force, CPU kD Tree, CPU Hash1, CPU Hash2, ATI Hash1\n"); for( int levmx = 1; levmx < 10; levmx++) { printf("\nlevmx is %d\n\n",levmx); for( int i = 1024; i < 50000000; i *= 2) { printf("%d, ", i); remaps(i, i, 1.0, (double)levmx, 0.0); printf("\n"); } } }
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 cube_p<int> get_segmentation( std::vector<cube_p<real>> affs, real threshold = 0.5 ) { // only takes 3D affinity graph ZI_ASSERT(affs.size==3); vec3i s = size(*affs[0]); size_t n = s[0]*s[1]*s[2]; cube<real> const & xaff = *affs[0]; cube<real> const & yaff = *affs[1]; cube<real> const & zaff = *affs[2]; zi::disjoint_sets<uint32_t> sets(n+1); std::vector<uint32_t> sizes(n+1); cube_p<int> ids_ptr = get_cube<int>(s); cube<int> & ids = *ids_ptr; for ( size_t i = 0; i < n; ++i ) { ids.data()[i] = i+1; sizes[i+1] = 1; } typedef std::pair<uint32_t,uint32_t> edge_type; std::vector<edge_type> edges; // thresholded affinity graph for ( size_t z = 0; z < s[0]; ++z ) { for ( size_t y = 0; y < s[1]; ++y ) { for ( size_t x = 0; x < s[2]; ++x ) { long id1 = ids[z][y][x]; if ( x > 0 ) { // skip disconnected (black) edges // only count connected (white) edges if ( xaff[z][y][x] > threshold ) { long id2 = ids[z][y][x-1]; edges.push_back(edge_type(id1, id2)); } } if ( y > 0 ) { // skip disconnected (black) edges // only count connected (white) edges if ( yaff[z][y][x] > threshold ) { long id2 = ids[z][y-1][x]; edges.push_back(edge_type(id1, id2)); } } if ( z > 0 ) { // skip disconnected (black) edges // only count connected (white) edges if ( zaff[z][y][x] > threshold ) { long id2 = ids[z-1][y][x]; edges.push_back(edge_type(id1, id2)); } } } } } // connected components of the thresholded affinity graph // computed the size of each connected component for ( auto& e: edges ) { uint32_t set1 = sets.find_set(e.first); uint32_t set2 = sets.find_set(e.second); if ( set1 != set2 ) { uint32_t new_set = sets.join(set1, set2); sizes[set1] += sizes[set2]; sizes[set2] = 0; std::swap(sizes[new_set], sizes[set1]); } } std::vector<uint32_t> remaps(n+1); uint32_t next_id = 1; // assign a unique segment ID to each of // the pixel in a connected component for ( size_t i = 0; i < n; ++i ) { uint32_t id = sets.find_set(ids.data()[i]); if ( sizes[id] > 1 ) { if ( remaps[id] == 0 ) { remaps[id] = next_id; ids.data()[i] = next_id; ++next_id; } else { ids.data()[i] = remaps[id]; } } else { remaps[id] = 0; ids.data()[i] = 0; } } return ids_ptr; }
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; }