Commit d72ab3b6 authored by Baptiste Esteban's avatar Baptiste Esteban
Browse files

More doc + small fixes

parent 21cf5ccd
Pipeline #30574 passed with stages
in 18 minutes and 36 seconds
......@@ -21,8 +21,8 @@ Pylene.
Notes
-----
* Before computing the MToS, the user should add a border to the image, with the values of this border set to the median value of the border of the original image
* The resulting nodemap is sixteen times bigger than the original image. The user is advised to reduce the nodemap before doing any processing. (**FIXME** to keep ?)
* Before computing the MToS, the user should add a border to the image, with the values of this border set to the median value of the border of the original image.
* The MToS not having values related to the nodes, the user has to compute a value.
Example
-------
......@@ -45,16 +45,14 @@ This example computes a grain filter, which removes all the node which have an a
// Function to remove the border
mln::image2d<int> remove_border(mln::image2d<int> n);
// Accumulator to compute the mean of each node, without taking into account the values of the holes
// (it only takes into account the value of the connected component related to a node)
// Accumulator to compute the mean of the pixel values of each node, without taking into account the values of the holes
struct mean_node_accu : mln::Accumulator<mean_node_accu>
{
using result_type = decltype(std::declval<mln::rgb8>() + std::declval<mln::rgb8>());
public:
template <typename Pix>
void take(const Pix& pix)
void take(const mln::rgb8& v)
{
m_sum += pix.val();
m_sum += v;
m_count++;
}
......@@ -91,7 +89,7 @@ This example computes a grain filter, which removes all the node which have an a
t.filter(mln::morpho::CT_FILTER_DIRECT, nm, [&area](int n) { return area[n] >= 100; });
// Compute the mean of the connected component of each nodes
auto mean = t.compute_attribute_on_pixels(nm, ima, mean_node_accu());
auto mean = t.compute_attribute_on_values(nm, ima, mean_node_accu());
// Reconstruct the tree
auto rec = t.reconstruct_from(nm, ranges::make_span(mean.data(), mean.size()));
......
......@@ -21,10 +21,9 @@ namespace
{
using result_type = decltype(std::declval<mln::rgb8>() + std::declval<mln::rgb8>());
public:
template <typename Pix>
void take(const Pix& pix)
void take(const mln::rgb8& v)
{
m_sum += pix.val();
m_sum += v;
m_count++;
}
......@@ -149,12 +148,12 @@ int main(int argc, char* argv[])
mln::io::imsave(heat_depth, argv[2]);
}
auto [t, nm] = mln::morpho::details::satmaxtree(depth_map);
auto [t, nm] = mln::morpho::details::satmaxtree(depth_map, {0, 0});
nm = reduce_nodemap(nm);
nm = remove_border(nm);
auto area = t.compute_attribute_on_points(nm, mln::accu::accumulators::count<int>());
t.filter(mln::morpho::CT_FILTER_DIRECT, nm, [&area](int n) { return area[n] >= 100; });
auto mean = t.compute_attribute_on_pixels(nm, ima, mean_node_accu());
t.filter(mln::morpho::CT_FILTER_DIRECT, nm, [&area](int n) { return area[n] >= 200; });
auto mean = t.compute_attribute_on_values(nm, ima, mean_node_accu());
auto rec = t.reconstruct_from(nm, ranges::make_span(mean.data(), mean.size()));
mln::io::imsave(mln::view::cast<mln::rgb8>(rec), argv[3]);
......
......@@ -6,5 +6,10 @@
namespace mln::morpho::details
{
std::pair<component_tree<>, image2d<int>> satmaxtree(image2d<std::uint16_t> depth_map);
/// \brief Compute the hole-filled maxtree of a depth map
/// \param depth_map The input depth map
/// \param pstart The rooting point of the satmaxtree
/// \return A pair (tree, nodemap) where tree is the resulting satmaxtree (values are not kept)
/// and a map image point -> tree node
std::pair<component_tree<>, image2d<int>> satmaxtree(image2d<std::uint16_t> depth_map, point2d pstart);
}
\ No newline at end of file
......@@ -8,9 +8,24 @@
namespace mln::morpho::details
{
/// \brief Compute the inclusion graph of the trees given in input
/// \param trees The input trees
/// \param nodemaps The nodemaps related to each tree
/// \param depths The depths attribute of each tree
/// \param The number of tree given in argument
/// \return A pair (graph, tree_to_graph) where graph is the inclusion graph and tree_to_graph
/// is a map (tree_index, tree_node) -> graph_node
std::pair<std::vector<std::set<int>>, std::vector<std::vector<int>>>
compute_inclusion_graph(component_tree<>* trees, image2d<int>* nodemaps, std::vector<int>* depths, int ntrees);
/// \brief Compute the depth map of an inclusion graph
/// \param graph The inclusion graph
/// \param tree_to_graph A map (tree_index, tree_node) -> graph_node
/// \param nodemaps The nodemaps of each tree which built the inclusion graph
/// \return The depth map of the inclusion graph (The depth should not exceed 2^16)
/// FIXME: For future optimization, the arguments should be change to
/// (const std::vector<std::set<int>>& graph, const std::vector<int>& tree_to_graph, image2d<int>* nodemaps, const
/// std::vector<int>& tree_shapes)
image2d<std::uint16_t> compute_depth_map(const std::vector<std::set<int>>& graph,
const std::vector<std::vector<int>>& tree_to_graph, image2d<int>* nodemaps);
} // namespace mln::morpho::details
\ No newline at end of file
......@@ -21,7 +21,7 @@ namespace mln::morpho
const auto [gos, tree_to_graph] = mln::morpho::details::compute_inclusion_graph(trees, nodemaps, depths, 3);
auto depth_map = mln::morpho::details::compute_depth_map(gos, tree_to_graph, nodemaps);
auto [t, nm] = mln::morpho::details::satmaxtree(depth_map);
auto [t, nm] = mln::morpho::details::satmaxtree(depth_map, pstart);
return {std::move(t), std::move(nm)};
}
......
......@@ -4,9 +4,9 @@
namespace mln::morpho::details
{
std::pair<component_tree<>, image2d<int>> satmaxtree(image2d<std::uint16_t> depth_map)
std::pair<component_tree<>, image2d<int>> satmaxtree(image2d<std::uint16_t> depth_map, point2d pstart)
{
auto [t, nm] = mln::morpho::tos(depth_map, {0, 0});
auto [t, nm] = mln::morpho::tos(depth_map, pstart);
const int num_node = static_cast<int>(t.parent.size());
std::vector<std::uint16_t> delta(num_node, 0);
......
......@@ -208,7 +208,7 @@ namespace mln::morpho::details
std::vector<int> graph_depth(graph.size(), -1);
graph_depth[0] = 0;
// FIXME : Optimization removing the transpose (modify topo_sort)
/// FIXME: Optimization removing the transpose (modify topo_sort)
std::vector<std::set<int>> gT(graph.size());
for (int v = 0; v < (int)graph.size(); v++)
{
......
......@@ -112,9 +112,6 @@ TEST(Morpho, DepthMap)
TEST(Morpho, Satmaxtree)
{
// Test satmaxtree computation from depth map
auto [t, nm] = mln::morpho::details::satmaxtree(depth_map_ref);
std::vector<int> parent_ref = {-1, 0, 1, 1, 3, 3, 3, 3, 3, 3, 1, 10, 10,
10, 10, 10, 10, 10, 10, 10, 10, 10, 21, 21, 10};
......@@ -138,6 +135,9 @@ TEST(Morpho, Satmaxtree)
{20, 10, 10, 10, 17, 10, 10, 10, 10, 10, 10, 10, 16, 10, 10, 10, 18}, //
};
// Test satmaxtree computation from depth map
auto [t, nm] = mln::morpho::details::satmaxtree(depth_map_ref, {0, 0});
ASSERT_EQ(t.parent.size(), parent_ref.size());
for (int i = 0; i < (int)parent_ref.size(); i++)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment