Commit 94aabc11 authored by Michaël Roynard's avatar Michaël Roynard
Browse files

clang-format

parent 72f038c5
#include <mln/core/image/image2d.hpp>
#include <mln/core/algorithm/accumulate.hpp>
#include <mln/accu/accumulators/max.hpp>
#include <mln/core/algorithm/accumulate.hpp>
#include <mln/core/image/image2d.hpp>
#include <mln/morpho/component_tree/io.hpp>
#include <mln/morpho/algebraic_filter.hpp>
#include <mln/morpho/component_tree/accumulate.hpp>
#include <mln/morpho/component_tree/reconstruction.hpp>
#include <mln/morpho/component_tree/filtering.hpp>
#include <mln/morpho/algebraic_filter.hpp>
#include <mln/morpho/component_tree/io.hpp>
#include <mln/morpho/component_tree/reconstruction.hpp>
#include "cMSER.hpp"
#include <apps/tos/topology.hpp>
#include <mln/accu/accumulators/accu_if.hpp>
#include <mln/accu/accumulators/count.hpp>
#include <apps/tos/topology.hpp>
#include "cMSER.hpp"
#include <mln/morpho/extinction.hpp>
#include <mln/morpho/datastruct/checktree.hpp>
#include <mln/morpho/extinction.hpp>
int main(int argc, char** argv)
int
main(int argc, char** argv)
{
if (argc < 9)
{
std::cerr << "Usage: " << argv[0] << "tree image.tiff λ ε t₁ t₂ spectra.csv\n"
<< " λ:\t Grain filter before anything else (number of 2F) (consider: 20-50, *20*) \n"
<< " ε:\t The delta level considered when fetching the neighborhood of a node in MSER (consider 5-20, *10*)\n"
<< " t₁:\t Threshold above which node having a MSER value greater that t₁ are removed (consider 0.7-2.0, *1.0*)\n"
<< " t₂:\t Threshold below which node having an extinction value lesser than t₂ are removed (consider 0-t₁, *0.2*).\n";
std::exit(1);
}
{
std::cerr
<< "Usage: " << argv[0] << "tree image.tiff λ ε t₁ t₂ spectra.csv\n"
<< " λ:\t Grain filter before anything else (number of 2F) (consider: 20-50, *20*) \n"
<< " ε:\t The delta level considered when fetching the neighborhood of a node in MSER (consider 5-20, *10*)\n"
<< " t₁:\t Threshold above which node having a MSER value greater that t₁ are removed (consider 0.7-2.0, "
"*1.0*)\n"
<< " t₂:\t Threshold below which node having an extinction value lesser than t₂ are removed (consider 0-t₁, "
"*0.2*).\n";
std::exit(1);
}
using namespace mln;
......@@ -38,7 +42,7 @@ int main(int argc, char** argv)
float threshold2 = std::atof(argv[6]);
const char* out_path = argv[7];
typedef morpho::component_tree<unsigned, image2d<unsigned> > tree_t;
typedef morpho::component_tree<unsigned, image2d<unsigned>> tree_t;
tree_t tree;
{
std::ifstream f(tree_path, std::ios::binary);
......@@ -49,22 +53,18 @@ int main(int argc, char** argv)
io::imread(img_path, ima);
if (ima.domain() != tree._get_data()->m_pmap.domain())
{
std::cerr << "Domain between image differ.\n"
<< ima.domain() << " vs "
<< tree._get_data()->m_pmap.domain() << std::endl;
}
{
std::cerr << "Domain between image differ.\n"
<< ima.domain() << " vs " << tree._get_data()->m_pmap.domain() << std::endl;
}
auto vmap = morpho::make_attribute_map_from_image(tree, ima);
accu::accumulators::accu_if< accu::accumulators::count<>,
K1::is_face_2_t,
point2d > counter;
accu::accumulators::accu_if<accu::accumulators::count<>, K1::is_face_2_t, point2d> counter;
auto amap = morpho::paccumulate(tree, ima, counter);
auto pred = make_functional_property_map<tree_t::vertex_id_t>([&amap, grain](tree_t::vertex_id_t x) {
return amap[x] > grain;
});
auto pred = make_functional_property_map<tree_t::vertex_id_t>(
[&amap, grain](tree_t::vertex_id_t x) { return amap[x] > grain; });
morpho::filter_direct_inplace(tree, pred);
morpho::internal::checktree(tree);
......@@ -73,21 +73,20 @@ int main(int argc, char** argv)
// convert to image and filter
auto imser = morpho::make_image(tree, amser);
{
//float maxval = accumulate(imser, accu::features::max<> ());
mln_foreach(float& v, imser.values())
// float maxval = accumulate(imser, accu::features::max<> ());
mln_foreach (float& v, imser.values())
if (v > threshold1)
v = threshold1;
}
auto nmser = morpho::extinction(imser, morpho::tree_neighb_t());
//auto nmser = eval(nmser_ / imser);
//auto nmser = morpho::area_closing(imser, morpho::tree_neighb_t(), areaAS);
// auto nmser = eval(nmser_ / imser);
// auto nmser = morpho::area_closing(imser, morpho::tree_neighb_t(), areaAS);
{
std::ofstream fout(out_path);
fout << "area,mser,extinction\n";
mln_foreach(auto x, tree.nodes())
mln_foreach (auto x, tree.nodes())
fout << amap[x] << "," << amser[x] << "," << nmser(x) << "\n";
fout.close();
}
......@@ -97,8 +96,7 @@ int main(int argc, char** argv)
resize(tmp, ima);
auto& attr = nmser.get_vmap();
auto pred = [&attr, threshold2](const tree_t::node_type& x) { return threshold2 < attr[x]; };
morpho::filter_direct_and_reconstruct(tree, make_functional_property_map<tree_t::node_type>(pred),
vmap, tmp);
morpho::filter_direct_and_reconstruct(tree, make_functional_property_map<tree_t::node_type>(pred), vmap, tmp);
io::imsave(tmp, "selection.tiff");
}
......
#ifndef APPS_ATTTRIBUTES_MSER_HPP
# define APPS_ATTTRIBUTES_MSER_HPP
#define APPS_ATTTRIBUTES_MSER_HPP
#include <cstdlib>
#include <mln/core/image/image2d.hpp>
#include <mln/core/trace.hpp>
# include <mln/core/image/image2d.hpp>
# include <mln/core/trace.hpp>
# include <cstdlib>
enum eMSER_attribute { MSER_DIFF, MSER_RATIO, MSER_NORM };
enum eMSER_attribute
{
MSER_DIFF,
MSER_RATIO,
MSER_NORM
};
///
///
......@@ -25,24 +28,14 @@ enum eMSER_attribute { MSER_DIFF, MSER_RATIO, MSER_NORM };
///
template <typename V, typename T, class Distance>
mln::image2d<float>
compute_MSER_attribute(const mln::image2d<V>& f,
const mln::image2d<T>& K,
const mln::image2d<unsigned>& parent,
const std::vector<unsigned>& S,
typename std::result_of<Distance(V,V)>::type eps,
eMSER_attribute amser = MSER_DIFF,
Distance dist = Distance() );
compute_MSER_attribute(const mln::image2d<V>& f, const mln::image2d<T>& K, const mln::image2d<unsigned>& parent,
const std::vector<unsigned>& S, typename std::result_of<Distance(V, V)>::type eps,
eMSER_attribute amser = MSER_DIFF, Distance dist = Distance());
template <typename V, typename T, typename T2>
mln::image2d<float>
compute_MSER_attribute(const mln::image2d<V>& f,
const mln::image2d<T>& K,
const mln::image2d<unsigned>& parent,
const std::vector<unsigned>& S,
T2 eps,
eMSER_attribute amser = MSER_DIFF);
compute_MSER_attribute(const mln::image2d<V>& f, const mln::image2d<T>& K, const mln::image2d<unsigned>& parent,
const std::vector<unsigned>& S, T2 eps, eMSER_attribute amser = MSER_DIFF);
/********************/
/** Implementation **/
......@@ -50,32 +43,22 @@ compute_MSER_attribute(const mln::image2d<V>& f,
template <typename V, typename T, typename T2>
mln::image2d<float>
compute_MSER_attribute(const mln::image2d<V>& f,
const mln::image2d<T>& K,
const mln::image2d<unsigned>& parent,
const std::vector<unsigned>& S,
T2 eps,
eMSER_attribute amser)
compute_MSER_attribute(const mln::image2d<V>& f, const mln::image2d<T>& K, const mln::image2d<unsigned>& parent,
const std::vector<unsigned>& S, T2 eps, eMSER_attribute amser)
{
auto fun = [](V x, V y) { return std::abs(x - y); };
return compute_MSER_attribute(f, K, parent, S, eps, amser, fun);
}
template <typename V, typename T, class Distance>
mln::image2d<float>
compute_MSER_attribute(const mln::image2d<V>& f,
const mln::image2d<T>& K,
const mln::image2d<unsigned>& parent,
const std::vector<unsigned>& S,
typename std::result_of<Distance(V,V)>::type eps,
eMSER_attribute amser,
Distance dist)
compute_MSER_attribute(const mln::image2d<V>& f, const mln::image2d<T>& K, const mln::image2d<unsigned>& parent,
const std::vector<unsigned>& S, typename std::result_of<Distance(V, V)>::type eps,
eMSER_attribute amser, Distance dist)
{
using namespace mln;
trace::entering("compute_MSER_attribute");
// compute area
image2d<unsigned> area;
image2d<unsigned> maxarea; // the max area of the children in Δh
......@@ -84,52 +67,62 @@ compute_MSER_attribute(const mln::image2d<V>& f,
resize(area, K).init(0);
resize(maxarea, K).init((unsigned)0);
area[S[0]] = 1;
for (int i = S.size()-1; i > 0; --i)
{
unsigned x = S[i];
++area[x];
area[parent[x]] += area[x];
if (K[x] != K[parent[x]]) { // canonical propagate to parent
unsigned y = parent[x];
unsigned a = area[x];
V v = f[x];
while (parent[y] != y and dist(v, f[y]) < eps) {
y = parent[y];
}
maxarea[y] = std::max(a, maxarea[y]);
}
for (int i = S.size() - 1; i > 0; --i)
{
unsigned x = S[i];
++area[x];
area[parent[x]] += area[x];
if (K[x] != K[parent[x]])
{ // canonical propagate to parent
unsigned y = parent[x];
unsigned a = area[x];
V v = f[x];
while (parent[y] != y and dist(v, f[y]) < eps)
{
y = parent[y];
}
maxarea[y] = std::max(a, maxarea[y]);
}
}
}
// MSER attr
image2d<float> mser;
resize(mser, K);
{
//mser[S[0]] = 0; // FIXME !!
for (int i = S.size()-1; i > 0; --i)
// mser[S[0]] = 0; // FIXME !!
for (int i = S.size() - 1; i > 0; --i)
{
unsigned x = S[i];
if (K[parent[x]] == K[x]) // not a canonical element
continue;
V v = f[x];
unsigned y = parent[x];
unsigned smally = parent[x];
while (dist(v, f[y]) < eps and y != parent[y])
{
if (dist(v, f[y]) < (eps / 3))
smally = y;
y = parent[y];
}
switch (amser)
{
unsigned x = S[i];
if (K[parent[x]] == K[x]) // not a canonical element
continue;
V v = f[x];
unsigned y = parent[x];
unsigned smally = parent[x];
while (dist(v, f[y]) < eps and y != parent[y]) {
if (dist(v,f[y]) < (eps / 3))
smally = y;
y = parent[y];
}
switch (amser) {
case MSER_DIFF: mser[x] = area[y] - maxarea[x]; break;
case MSER_RATIO: mser[x] = //(float) area[x] / area[y]; break;
//mser[x] = std::max(10.0f, (float) (area[y] - maxarea[x]) / area[x]); break;
mser[x] = (float) (area[smally] - area[x]) / (area[y] - area[x]); break;
case MSER_NORM: mser[x] = (float) (area[y] - maxarea[x]) / maxarea[x]; break;
}
case MSER_DIFF:
mser[x] = area[y] - maxarea[x];
break;
case MSER_RATIO:
mser[x] = //(float) area[x] / area[y]; break;
// mser[x] = std::max(10.0f, (float) (area[y] - maxarea[x]) / area[x]); break;
mser[x] = (float)(area[smally] - area[x]) / (area[y] - area[x]);
break;
case MSER_NORM:
mser[x] = (float)(area[y] - maxarea[x]) / maxarea[x];
break;
}
}
if (amser == MSER_DIFF or amser == MSER_NORM)
mser[S[0]] = 0;
......@@ -141,5 +134,4 @@ compute_MSER_attribute(const mln::image2d<V>& f,
return mser;
}
#endif // ! APPS_ATTTRIBUTES_MSER_HPP
#include "MSERArgparser.hpp"
#include <boost/program_options.hpp>
MSERArgParser::MSERArgParser()
: m_desc("MSER options")
MSERArgParser::MSERArgParser() : m_desc("MSER options")
{
namespace po = boost::program_options;
m_desc.add_options()
("mode,m", po::value<std::string>()->default_value("MSER_RATIO"),
"Mode: (MSER_DIFF | MSER_RATIO | MSER_NORM) : \n"
"MSER_DIFF: Area(parent) - Area(current)\n"
"MSER_RATIO 0-1: Area(current)/Area(parent)\n"
"MSER_NORM: Area(parent) / Area(current) - 1"
)
("delta,d", po::value<float>()->default_value(20), "Number of gray levels in to accept a parent.")
("a0", po::value<float>()->default_value(5), "A0 Penalty term: P = a0.exp(a1 * area)")
("a1", po::value<float>()->default_value(0.0005), "A1 Penalty term: P = a0.exp(a1 * area)")
;
m_desc.add_options()("mode,m", po::value<std::string>()->default_value("MSER_RATIO"),
"Mode: (MSER_DIFF | MSER_RATIO | MSER_NORM) : \n"
"MSER_DIFF: Area(parent) - Area(current)\n"
"MSER_RATIO 0-1: Area(current)/Area(parent)\n"
"MSER_NORM: Area(parent) / Area(current) - 1")("delta,d", po::value<float>()->default_value(20),
"Number of gray levels in to accept a parent.")(
"a0", po::value<float>()->default_value(5), "A0 Penalty term: P = a0.exp(a1 * area)")(
"a1", po::value<float>()->default_value(0.0005), "A1 Penalty term: P = a0.exp(a1 * area)");
}
boost::program_options::options_description&
......@@ -24,4 +20,3 @@ MSERArgParser::description()
{
return m_desc;
}
#ifndef APPS_ATTRIBUTES_MSERARGPARSER_HPP
# define APPS_ATTRIBUTES_MSERARGPARSER_HPP
# include "argparser.hpp"
# include "MSER.hpp"
# include <boost/program_options/errors.hpp>
# include <boost/program_options/variables_map.hpp>
# include <apps/tos/topology.hpp>
# include <string>
#define APPS_ATTRIBUTES_MSERARGPARSER_HPP
#include "MSER.hpp"
#include "argparser.hpp"
#include <apps/tos/topology.hpp>
#include <boost/program_options/errors.hpp>
#include <boost/program_options/variables_map.hpp>
#include <string>
class MSERArgParser : public AttributeArgParser
{
......@@ -17,12 +15,9 @@ public:
virtual boost::program_options::options_description& description();
template <typename V, typename T>
mln::image2d<float>
run(const boost::program_options::variables_map& vm,
const mln::image2d<V>& f,
const mln::image2d<T>& K,
const mln::image2d<unsigned>& parent,
const std::vector<unsigned>& S);
mln::image2d<float> run(const boost::program_options::variables_map& vm, const mln::image2d<V>& f,
const mln::image2d<T>& K, const mln::image2d<unsigned>& parent,
const std::vector<unsigned>& S);
private:
boost::program_options::options_description m_desc;
......@@ -34,11 +29,8 @@ private:
template <typename V, typename T>
mln::image2d<float>
MSERArgParser::run(const boost::program_options::variables_map& vm,
const mln::image2d<V>& f,
const mln::image2d<T>& K,
const mln::image2d<unsigned>& parent,
const std::vector<unsigned>& S)
MSERArgParser::run(const boost::program_options::variables_map& vm, const mln::image2d<V>& f, const mln::image2d<T>& K,
const mln::image2d<unsigned>& parent, const std::vector<unsigned>& S)
{
std::string smode = vm["mode"].as<std::string>();
eMSER_attribute mode;
......@@ -61,7 +53,7 @@ MSERArgParser::run(const boost::program_options::variables_map& vm,
mln::image2d<unsigned> area;
mln::resize(area, K).init(0);
area[S[0]] = 1; // root handling
for (int i = S.size()-1; i > 0; --i)
for (int i = S.size() - 1; i > 0; --i)
{
unsigned x = S[i];
if (mln::K1::is_face_2(K.point_at_index(x)))
......@@ -69,14 +61,10 @@ MSERArgParser::run(const boost::program_options::variables_map& vm,
area[parent[x]] += area[x];
}
auto attr = transform(imzip(amser, area),
[a0, a1](const std::tuple<float,unsigned>& v) -> float{
return std::max(std::get<0>(v), a0 * std::exp(-a1 * std::get<1>(v)) );
});
auto attr = transform(imzip(amser, area), [a0, a1](const std::tuple<float, unsigned>& v) -> float {
return std::max(std::get<0>(v), a0 * std::exp(-a1 * std::get<1>(v)));
});
return eval(attr);
}
#endif // ! APPS_ATTRIBUTES_MSERARGPARSER_HPP
#ifndef APPS_ATTRIBUTES_ARGPARSER_HPP
# define APPS_ATTRIBUTES_ARGPARSER_HPP
# include <boost/program_options/options_description.hpp>
#define APPS_ATTRIBUTES_ARGPARSER_HPP
#include <boost/program_options/options_description.hpp>
class AttributeArgParser
{
public:
virtual boost::program_options::options_description& description() = 0;
};
#endif // ! APPS_ATTRIBUTES_ARGPARSER_HPP
#ifndef APPS_ATTRIBUTE_CMSER_HPP
# define APPS_ATTRIBUTE_CMSER_HPP
#define APPS_ATTRIBUTE_CMSER_HPP
# include <mln/core/trace.hpp>
# include <mln/morpho/component_tree/component_tree.hpp>
#include <mln/core/trace.hpp>
#include <mln/morpho/component_tree/component_tree.hpp>
enum eMSER_attribute {
MSER_DIFF, // Val > 0, δΓ = A(Γ⁺) - A(Γ⁻)
MSER_RATIO, // 0 < Val < 1 δΓ = A(Γ⁻) / A(Γ⁺)
MSER_NORM // 0 < Val < 1 δΓ = (A(Γ⁺) - A(Γ⁻)) / A(Γ)
enum eMSER_attribute
{
MSER_DIFF, // Val > 0, δΓ = A(Γ⁺) - A(Γ⁻)
MSER_RATIO, // 0 < Val < 1 δΓ = A(Γ⁻) / A(Γ⁺)
MSER_NORM // 0 < Val < 1 δΓ = (A(Γ⁺) - A(Γ⁻)) / A(Γ)
};
enum eMSER_accum_type {
MSER_ABSOLUTE, // Γ⁺ = ⋁ { Γ ⊂ Γ', |V(Γ') - V(Γ)| ≥ ε }
MSER_SUM // Γ⁺ = ⋁ { Γ ⊂ Γ', ∑ |V(par(u)) - V(u)| > ε, u ∈ [Γ → Γ'] }
enum eMSER_accum_type
{
MSER_ABSOLUTE, // Γ⁺ = ⋁ { Γ ⊂ Γ', |V(Γ') - V(Γ)| ≥ ε }
MSER_SUM // Γ⁺ = ⋁ { Γ ⊂ Γ', ∑ |V(par(u)) - V(u)| > ε, u ∈ [Γ → Γ'] }
};
namespace mln
{
template <class P, class Amap,
class ValuePropertyMap,
class AreaPropertyMap,
class Distance>
template <class P, class Amap, class ValuePropertyMap, class AreaPropertyMap, class Distance>
property_map<morpho::component_tree<P, Amap>, float>
compute_MSER(const morpho::component_tree<P, Amap>& tree,
const ValuePropertyMap& vmap,
const AreaPropertyMap& amap,
float eps,
eMSER_attribute amser = MSER_DIFF,
eMSER_accum_type fsum = MSER_ABSOLUTE,
compute_MSER(const morpho::component_tree<P, Amap>& tree, const ValuePropertyMap& vmap, const AreaPropertyMap& amap,
float eps, eMSER_attribute amser = MSER_DIFF, eMSER_accum_type fsum = MSER_ABSOLUTE,
Distance dist = Distance());
template <class P, class Amap,
class ValuePropertyMap,
class AreaPropertyMap>
template <class P, class Amap, class ValuePropertyMap, class AreaPropertyMap>
property_map<morpho::component_tree<P, Amap>, float>
compute_MSER(const morpho::component_tree<P, Amap>& tree,
const ValuePropertyMap& vmap,
const AreaPropertyMap& amap,
float eps,
eMSER_attribute amser = MSER_DIFF,
eMSER_accum_type fsum = MSER_ABSOLUTE);
compute_MSER(const morpho::component_tree<P, Amap>& tree, const ValuePropertyMap& vmap, const AreaPropertyMap& amap,
float eps, eMSER_attribute amser = MSER_DIFF, eMSER_accum_type fsum = MSER_ABSOLUTE);
/**********************/
/** Implementation **/
/**********************/
template <class P, class Amap,
class ValuePropertyMap,
class AreaPropertyMap,
class Distance>
template <class P, class Amap, class ValuePropertyMap, class AreaPropertyMap, class Distance>
property_map<morpho::component_tree<P, Amap>, float>
compute_MSER(const morpho::component_tree<P, Amap>& tree,
const ValuePropertyMap& vmap,
const AreaPropertyMap& amap,
float eps,
eMSER_attribute amser,
eMSER_accum_type fsum,
Distance dist)
compute_MSER(const morpho::component_tree<P, Amap>& tree, const ValuePropertyMap& vmap, const AreaPropertyMap& amap,
float eps, eMSER_attribute amser, eMSER_accum_type fsum, Distance dist)
{
mln_entering("mln::compute_MSER");
......@@ -70,72 +49,66 @@ namespace mln
property_map<tree_t, unsigned> aminus(tree, 0);
if (fsum == MSER_ABSOLUTE)
{
mln_reverse_foreach(auto n, tree.nodes())
{
mln_reverse_foreach(auto n, tree.nodes())
{
auto x = n;
while (x.get_parent_id() != tree.npos() and dist(vmap[n], vmap[x]) < eps)
x = x.parent();
aminus[x] = std::max<unsigned>(aminus[x], amap[n]);
aplus[n] = amap[x];
}
auto x = n;
while (x.get_parent_id() != tree.npos() and dist(vmap[n], vmap[x]) < eps)
x = x.parent();
aminus[x] = std::max<unsigned>(aminus[x], amap[n]);
aplus[n] = amap[x];
}
}
else
{
mln_reverse_foreach(auto n, tree.nodes())
{
mln_reverse_foreach(auto n, tree.nodes())
{
auto x = n;
float d = 0;
while (x.id() != x.get_parent_id() and d < eps)
{
d += dist(vmap[x], vmap[x.parent()]);
x = x.parent();
}
aminus[x] = std::max<unsigned>(aminus[x], amap[n]);
aplus[n] = amap[x];
}
auto x = n;
float d = 0;
while (x.id() != x.get_parent_id() and d < eps)
{
d += dist(vmap[x], vmap[x.parent()]);
x = x.parent();
}
aminus[x] = std::max<unsigned>(aminus[x], amap[n]);
aplus[n] = amap[x];
}
}
aplus[tree.get_root_id()] = amap[tree.get_root()];
std::function<float(const node_t&)> f;
switch (amser) {
case MSER_DIFF:
f = [&](const node_t& x) -> float { return aplus[x] -<