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