예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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 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;
}