Skip to content
GitLab
Menu
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
cf7233e9
Commit
cf7233e9
authored
Jan 13, 2020
by
Edwin Carlinet
Browse files
Make the ToS use the original levels (not the depth).
parent
5b702052
Changes
3
Hide whitespace changes
Inline
Side-by-side
pylene/include/mln/morpho/experimental/component_tree.hpp
View file @
cf7233e9
...
...
@@ -12,18 +12,12 @@
namespace
mln
::
morpho
::
experimental
{
// namespace details
// {
// void filter_treeT(const int* parent, std::size_t n, e_filtering strategy, F predicate);
// void filter_tree(const int* parent, std::size_t n, e_filtering strategy, std::function<bool(int)> predicate);
// }
enum
ct_filtering
{
CT_FILTER_DIRECT
,
CT_FILTER_MIN
,
CT_FILTER_MAX
,
CT_FILTER_SUBTRACTIVE
//
CT_FILTER_SUBTRACTIVE
(not yet implemented)
};
...
...
@@ -100,6 +94,20 @@ namespace mln::morpho::experimental
compute_attribute_on_points
(
I
node_map
,
Accu
acc
);
/// \brief Compute attribute on pixels
///
/// Compute attribute with pixels (point + value) given from an image
///
/// \param node_map Image point -> node_id mapping
/// \param values Image point -> value mapping
/// \param acc Accumulator to apply on values
template
<
class
I
,
class
J
,
class
Accu
>
std
::
vector
<
typename
accu
::
result_of
<
Accu
,
image_pixel_t
<
J
>>::
type
>
//
compute_attribute_on_pixels
(
I
node_map
,
J
values
,
Accu
acc
);
/// \brief Reconstruct an image from an attribute map
///
/// \param node_map Image point -> node_id mapping
...
...
@@ -130,9 +138,9 @@ namespace mln::morpho::experimental
public:
template
<
class
I
>
image_ch_value_t
<
I
,
T
>
reconstruct
(
I
node_map
)
image_ch_value_t
<
std
::
remove_reference_t
<
I
>
,
T
>
reconstruct
(
I
&&
node_map
)
{
return
this
->
reconstruct_from
(
std
::
move
(
node_map
),
::
ranges
::
make_span
(
values
.
data
(),
values
.
size
()));
return
this
->
reconstruct_from
(
std
::
forward
<
I
>
(
node_map
),
::
ranges
::
make_span
(
values
.
data
(),
values
.
size
()));
}
...
...
@@ -150,7 +158,7 @@ namespace mln::morpho::experimental
std
::
size_t
n
=
parent
.
size
();
for
(
std
::
size_t
i
=
1
;
i
<
n
;
++
i
)
if
(
!
pred
(
parent
[
i
]))
if
(
parent
[
i
]
>
0
&&
!
pred
(
parent
[
i
]))
// If the parent[i] > 0 <=> not the root
parent
[
i
]
=
parent
[
parent
[
i
]];
}
...
...
@@ -160,7 +168,7 @@ namespace mln::morpho::experimental
{
mln_foreach_new
(
auto
&
id
,
node_map
.
new_values
())
{
if
(
!
pred
(
id
))
if
(
id
>
0
&&
!
pred
(
id
))
id
=
this
->
parent
[
id
];
}
}
...
...
@@ -170,6 +178,8 @@ namespace mln::morpho::experimental
template
<
class
F
>
void
component_tree
<
void
>::
filter
(
ct_filtering
strategy
,
F
pred
)
{
mln_entering
(
"mln::morpho::component_tree::filter"
);
std
::
size_t
n
=
parent
.
size
();
// Node pass status
...
...
@@ -213,6 +223,8 @@ namespace mln::morpho::experimental
template
<
class
I
,
class
F
>
void
component_tree
<
void
>::
filter
(
ct_filtering
strategy
,
I
node_map
,
F
pred
)
{
mln_entering
(
"mln::morpho::component_tree::filter"
);
std
::
size_t
n
=
parent
.
size
();
// Node pass status
...
...
@@ -264,6 +276,8 @@ namespace mln::morpho::experimental
std
::
vector
<
typename
accu
::
result_of
<
Accu
,
image_point_t
<
I
>>::
type
>
component_tree
<
void
>::
compute_attribute_on_points
(
I
node_map
,
Accu
acc
)
{
mln_entering
(
"mln::morpho::component_tree::compute_attribute_on_points"
);
static_assert
(
mln
::
is_a
<
I
,
mln
::
experimental
::
Image
>
());
static_assert
(
mln
::
is_a
<
Accu
,
mln
::
AccumulatorLike
>
());
using
R
=
typename
accu
::
result_of
<
Accu
,
image_point_t
<
I
>>::
type
;
...
...
@@ -295,6 +309,8 @@ namespace mln::morpho::experimental
std
::
vector
<
typename
accu
::
result_of
<
Accu
,
image_value_t
<
J
>>::
type
>
//
component_tree
<
void
>::
compute_attribute_on_values
(
I
node_map
,
J
input
,
Accu
acc
)
{
mln_entering
(
"mln::morpho::component_tree::compute_attribute_on_values"
);
static_assert
(
mln
::
is_a
<
I
,
mln
::
experimental
::
Image
>
());
static_assert
(
mln
::
is_a
<
Accu
,
mln
::
AccumulatorLike
>
());
using
R
=
typename
accu
::
result_of
<
Accu
,
image_value_t
<
J
>>::
type
;
...
...
@@ -305,7 +321,7 @@ namespace mln::morpho::experimental
// Accumulate for each point
auto
zz
=
mln
::
view
::
zip
(
node_map
,
input
);
mln_foreach_new
((
auto
[
node_id
,
val
]),
zz
.
values
())
mln_foreach_new
((
auto
[
node_id
,
val
]),
zz
.
new_
values
())
attr
[
node_id
].
take
(
val
);
...
...
@@ -323,12 +339,46 @@ namespace mln::morpho::experimental
return
out
;
}
template
<
class
I
,
class
J
,
class
Accu
>
std
::
vector
<
typename
accu
::
result_of
<
Accu
,
image_pixel_t
<
J
>>::
type
>
//
component_tree
<
void
>::
compute_attribute_on_pixels
(
I
node_map
,
J
values
,
Accu
acc
)
{
mln_entering
(
"mln::morpho::component_tree::compute_attribute_on_pixels"
);
static_assert
(
mln
::
is_a
<
I
,
mln
::
experimental
::
Image
>
());
static_assert
(
mln
::
is_a
<
Accu
,
mln
::
AccumulatorLike
>
());
using
R
=
typename
accu
::
result_of
<
Accu
,
image_pixel_t
<
J
>>::
type
;
auto
a
=
accu
::
make_accumulator
(
acc
,
image_pixel_t
<
J
>
());
std
::
vector
<
decltype
(
a
)
>
attr
(
parent
.
size
(),
a
);
// Accumulate for each point
mln_foreach_new
(
auto
px
,
values
.
new_pixels
())
attr
[
node_map
(
px
.
point
())].
take
(
px
);
// Propgate to parent
std
::
size_t
n
=
parent
.
size
();
for
(
std
::
size_t
i
=
n
-
1
;
i
>
0
;
--
i
)
attr
[
parent
[
i
]].
take
(
attr
[
i
]);
// Extract values
std
::
vector
<
R
>
out
(
n
);
for
(
std
::
size_t
i
=
0
;
i
<
n
;
++
i
)
out
[
i
]
=
attr
[
i
].
to_result
();
return
out
;
}
template
<
class
I
,
class
V
>
image_ch_value_t
<
I
,
V
>
component_tree
<
void
>::
reconstruct_from
(
I
node_map
,
::
ranges
::
span
<
V
>
values
)
const
{
mln_entering
(
"mln::morpho::component_tree::reconstruction"
);
image_ch_value_t
<
I
,
V
>
out
=
imchvalue
<
V
>
(
node_map
);
auto
zz
=
mln
::
view
::
zip
(
node_map
,
out
);
...
...
pylene/include/mln/morpho/experimental/private/propagation.hpp
View file @
cf7233e9
...
...
@@ -16,7 +16,8 @@ namespace mln::morpho::experimental::details
{
/// Propagation
template
<
class
I
>
void
propagation
(
I
inf
,
I
sup
,
image_ch_value_t
<
I
,
int
>
out
,
image_point_t
<
I
>
pstart
,
int
&
max_depth
);
std
::
vector
<
image_value_t
<
I
>>
//
propagation
(
I
inf
,
I
sup
,
image_ch_value_t
<
I
,
int
>
out
,
image_point_t
<
I
>
pstart
,
int
&
max_depth
);
/******************************************/
...
...
@@ -44,14 +45,14 @@ namespace mln::morpho::experimental::details
template
<
class
I
>
void
propagation
(
I
inf
,
I
sup
,
image_ch_value_t
<
I
,
int
>
ord
,
image_point_t
<
I
>
pstart
,
int
&
max_depth
)
std
::
vector
<
image_value_t
<
I
>>
//
propagation
(
I
inf
,
I
sup
,
image_ch_value_t
<
I
,
int
>
ord
,
image_point_t
<
I
>
pstart
,
int
&
max_depth
)
{
mln_entering
(
"mln::morpho::details::propagation"
);
using
P
=
image_point_t
<
I
>
;
using
V
=
image_value_t
<
I
>
;
static_assert
(
P
::
ndim
==
2
||
P
::
ndim
==
3
,
"Invalid number of dimension"
);
assert
(
inf
.
domain
()
==
sup
.
domain
());
assert
(
inf
.
domain
()
==
ord
.
domain
());
...
...
@@ -78,9 +79,11 @@ namespace mln::morpho::experimental::details
// if (compute_indexes)
// sorted_indexes->reserve(ord.domain().size());
auto
F
=
to_infsup
(
inf
,
sup
);
pset
<
I
>
queue
(
inf
);
pset
<
I
>
queue
(
inf
);
std
::
vector
<
V
>
depth2lvl
;
auto
p
=
pstart
;
V
previous_level
=
inf
(
p
);
...
...
@@ -90,12 +93,16 @@ namespace mln::morpho::experimental::details
// sorted_indexes->push_back(p);
int
depth
=
0
;
depth2lvl
.
push_back
(
previous_level
);
while
(
!
queue
.
empty
())
{
auto
[
cur_level
,
p
]
=
queue
.
pop
(
previous_level
);
if
(
cur_level
!=
previous_level
)
{
++
depth
;
depth2lvl
.
push_back
(
cur_level
);
}
// if (compute_indexes)
// sorted_indexes->push_back(p);
...
...
@@ -139,6 +146,7 @@ namespace mln::morpho::experimental::details
previous_level
=
cur_level
;
}
max_depth
=
depth
;
return
depth2lvl
;
}
...
...
pylene/include/mln/morpho/experimental/tos.hpp
View file @
cf7233e9
...
...
@@ -6,6 +6,8 @@
#include <mln/morpho/experimental/private/propagation.hpp>
#include <mln/core/image/view/cast.hpp>
#include <range/v3/algorithm/transform.hpp>
namespace
mln
::
morpho
::
experimental
{
...
...
@@ -35,6 +37,7 @@ namespace mln::morpho::experimental
using
Domain
=
image_domain_t
<
I
>
;
using
P
=
image_point_t
<
I
>
;
using
V
=
image_value_t
<
I
>
;
static_assert
(
std
::
is_same_v
<
Domain
,
mln
::
experimental
::
box2d
>
||
std
::
is_same_v
<
Domain
,
mln
::
experimental
::
box3d
>
,
"Only 2D or 3D regular domain supported"
);
...
...
@@ -46,13 +49,21 @@ namespace mln::morpho::experimental
auto
[
inf
,
sup
]
=
details
::
immersion
(
input
);
image_ch_value_t
<
I
,
int
>
ord
=
imchvalue
<
int
>
(
inf
).
adjust
(
nbh
);
details
::
propagation
(
inf
,
sup
,
ord
,
pstart
,
max_depth
);
auto
depth2lvl
=
details
::
propagation
(
inf
,
sup
,
ord
,
pstart
,
max_depth
);
if
(
max_depth
>=
(
1
<<
16
))
throw
std
::
runtime_error
(
"The ToS is too deep (too many number of levels)"
);
auto
casted
=
mln
::
view
::
cast
<
uint16_t
>
(
ord
);
return
maxtree
(
casted
,
nbh
);
auto
[
t1
,
node_map
]
=
maxtree
(
casted
,
nbh
);
std
::
size_t
n
=
t1
.
parent
.
size
();
component_tree
<
V
>
t2
;
t2
.
parent
=
std
::
move
(
t1
.
parent
);
t2
.
values
.
resize
(
n
);
::
ranges
::
transform
(
t1
.
values
,
std
::
begin
(
t2
.
values
),
[
&
depth2lvl
](
int
l
)
->
V
{
return
depth2lvl
[
l
];
});
return
std
::
make_pair
(
std
::
move
(
t2
),
std
::
move
(
node_map
));
}
}
// namespace mln::morpho::experimental
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment