MSER-patternspec-cli.cpp 3.71 KB
Newer Older
1
#include <mln/accu/accumulators/max.hpp>
Michaël Roynard's avatar
Michaël Roynard committed
2
3
#include <mln/core/algorithm/accumulate.hpp>
#include <mln/core/image/image2d.hpp>
4

Michaël Roynard's avatar
Michaël Roynard committed
5
#include <mln/morpho/algebraic_filter.hpp>
6
7
#include <mln/morpho/component_tree/accumulate.hpp>
#include <mln/morpho/component_tree/filtering.hpp>
Michaël Roynard's avatar
Michaël Roynard committed
8
9
#include <mln/morpho/component_tree/io.hpp>
#include <mln/morpho/component_tree/reconstruction.hpp>
10

Michaël Roynard's avatar
Michaël Roynard committed
11
12
#include "cMSER.hpp"
#include <apps/tos/topology.hpp>
13
14
15
16
#include <mln/accu/accumulators/accu_if.hpp>
#include <mln/accu/accumulators/count.hpp>

#include <mln/morpho/datastruct/checktree.hpp>
Michaël Roynard's avatar
Michaël Roynard committed
17
#include <mln/morpho/extinction.hpp>
18

Michaël Roynard's avatar
Michaël Roynard committed
19
20
int
main(int argc, char** argv)
21
22
{
  if (argc < 9)
Michaël Roynard's avatar
Michaël Roynard committed
23
24
25
26
27
28
29
30
31
32
33
  {
    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);
  }
34
35
36
37
38
39
40

  using namespace mln;

  const char* tree_path = argv[1];
  const char* img_path = argv[2];
  unsigned grain = std::atoi(argv[3]);
  int eps = std::atoi(argv[4]);
41
42
43
  float threshold1 = std::atof(argv[5]);
  float threshold2 = std::atof(argv[6]);
  const char* out_path = argv[7];
44

Michaël Roynard's avatar
Michaël Roynard committed
45
  typedef morpho::component_tree<unsigned, image2d<unsigned>> tree_t;
46
47
48
49
50
51
52
53
54
55
  tree_t tree;
  {
    std::ifstream f(tree_path, std::ios::binary);
    morpho::load(f, tree);
  }

  image2d<uint16> ima;
  io::imread(img_path, ima);

  if (ima.domain() != tree._get_data()->m_pmap.domain())
Michaël Roynard's avatar
Michaël Roynard committed
56
57
58
59
  {
    std::cerr << "Domain between image differ.\n"
              << ima.domain() << " vs " << tree._get_data()->m_pmap.domain() << std::endl;
  }
60
61
62

  auto vmap = morpho::make_attribute_map_from_image(tree, ima);

Michaël Roynard's avatar
Michaël Roynard committed
63
  accu::accumulators::accu_if<accu::accumulators::count<>, K1::is_face_2_t, point2d> counter;
64
65
  auto amap = morpho::paccumulate(tree, ima, counter);

Michaël Roynard's avatar
Michaël Roynard committed
66
67
  auto pred = make_functional_property_map<tree_t::vertex_id_t>(
      [&amap, grain](tree_t::vertex_id_t x) { return amap[x] > grain; });
68
69
70
71
72
73
74
75
  morpho::filter_direct_inplace(tree, pred);
  morpho::internal::checktree(tree);

  auto amser = compute_MSER(tree, vmap, amap, eps, MSER_NORM);

  // convert to image and filter
  auto imser = morpho::make_image(tree, amser);
  {
Michaël Roynard's avatar
Michaël Roynard committed
76
77
    // float maxval = accumulate(imser, accu::features::max<> ());
    mln_foreach (float& v, imser.values())
78
79
80
81
82
      if (v > threshold1)
        v = threshold1;
  }

  auto nmser = morpho::extinction(imser, morpho::tree_neighb_t());
Michaël Roynard's avatar
Michaël Roynard committed
83
84
  // auto nmser = eval(nmser_ / imser);
  // auto nmser = morpho::area_closing(imser, morpho::tree_neighb_t(), areaAS);
85
86
87
88

  {
    std::ofstream fout(out_path);
    fout << "area,mser,extinction\n";
Michaël Roynard's avatar
Michaël Roynard committed
89
    mln_foreach (auto x, tree.nodes())
90
91
92
93
94
95
96
97
98
      fout << amap[x] << "," << amser[x] << "," << nmser(x) << "\n";
    fout.close();
  }

  {
    image2d<uint16> tmp;
    resize(tmp, ima);
    auto& attr = nmser.get_vmap();
    auto pred = [&attr, threshold2](const tree_t::node_type& x) { return threshold2 < attr[x]; };
Michaël Roynard's avatar
Michaël Roynard committed
99
    morpho::filter_direct_and_reconstruct(tree, make_functional_property_map<tree_t::node_type>(pred), vmap, tmp);
100
101
102
103
104
105
106
107
108
109
    io::imsave(tmp, "selection.tiff");
  }

  // image2d<float> out(200,200);
  // morpho::pattern_spectra(tree, amser, amap,
  //                         make_functional_property_map([&](const tree_t::node_type& x) -> float {
  //                             return amap[x];
  //                           }), out, true, true);
  // io::imsave(out, argv[4]);
}