Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Olena
pylene
Commits
94aabc11
Commit
94aabc11
authored
Nov 15, 2017
by
Michaël Roynard
Browse files
clang-format
parent
72f038c5
Changes
435
Expand all
Hide whitespace changes
Inline
Side-by-side
apps/attributes/MSER-patternspec-cli.cpp
View file @
94aabc11
#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"
);
}
...
...
apps/attributes/MSER.hpp
View file @
94aabc11
#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
apps/attributes/MSERArgparser.cpp
View file @
94aabc11
#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
;
}
apps/attributes/MSERArgparser.hpp
View file @
94aabc11
#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
apps/attributes/argparser.hpp
View file @
94aabc11
#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
apps/attributes/cMSER.hpp
View file @
94aabc11
#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
)
{