Commit fb54bef4 authored by Jordan P. Lefebvre's avatar Jordan P. Lefebvre
Browse files

Resolving #19. Implementing a hybrid solution using dfs for the selected component.

parent 8b4804f4
Pipeline #13791 passed with stages
in 17 minutes and 45 seconds
......@@ -21,8 +21,7 @@ class MarchingSquares
protected:
std::vector<data_type> mData;
std::vector<int> mBit;
std::vector<int> mComponent;
std::vector<short> mBit;
size_t mRows;
size_t mColumns;
......@@ -51,8 +50,8 @@ class MarchingSquares
*/
void step(size_t r, size_t c);
bool accepts(size_t r, size_t c) const;
void find_components();
void dfs(int x, int y, size_t current_label);
void clear_connected_component(int x, int y, size_t label,
data_type wash_bit);
public:
/**
......
......@@ -9,36 +9,21 @@
namespace radix
{
template <typename data_type>
void MarchingSquares<data_type>::dfs(int x, int y, size_t current_label)
void MarchingSquares<data_type>::clear_connected_component(int x, int y,
size_t label,
data_type wash_bit)
{
if (x < 0 || x == mColumns) return; // out of bounds
if (y < 0 || y == mRows) return; // out of bounds
size_t c_i = mColumns * y + x;
if (mComponent[c_i] || !mBit[c_i])
return; // already labeled or not marked with 1 in m
// mark the current cell
mComponent[c_i] = current_label;
// recursively mark the neighbors
for (int direction = 0; direction < 4; ++direction)
dfs(x + dx[direction], y + dy[direction], current_label);
}
template <typename data_type>
void MarchingSquares<data_type>::find_components()
{
mComponent.resize(mBit.size(), 0);
size_t component = 0;
for (size_t c_i = 0; c_i < mComponent.size(); ++c_i)
if (mBit[c_i] == label)
{
// save the row
size_t y = c_i / mColumns;
// save the column
size_t x = c_i % mColumns;
// check if it is already labeled
if (!mComponent[c_i] && mBit[c_i]) dfs(x, y, ++component);
// clear the data
mBit[c_i] = 0;
mData[c_i] = wash_bit;
for (int direction = 0; direction < 4; ++direction)
clear_connected_component(x + dx[direction], y + dy[direction], label,
wash_bit);
}
}
......@@ -74,22 +59,7 @@ std::vector<std::pair<int, int>> MarchingSquares<data_type>::march(
{
mBit[p_i] = 2;
}
else
{
mBit[p_i] = 0;
}
}
//
// connected component labeling is required for multiple groups
if (mComponent.empty()) find_components();
size_t group_i = mColumns * start.first + start.second;
radix_line("Starting point is a member of component(" << mComponent[group_i]
<< ")");
std::cerr << std::endl;
radix_block(
std::unordered_set<int> groups(mComponent.begin(), mComponent.end()));
radix_tagged_line("Number of groups(" << groups.size() << ")");
//
// Walk the perimeter
......@@ -100,7 +70,9 @@ std::vector<std::pair<int, int>> MarchingSquares<data_type>::march(
// If our current point is within our image
// add it to the list of points
if (column >= 0 && column < mColumns && row >= 0 && row < mRows)
{
out.push_back({row, column});
}
switch (next_step)
{
......@@ -121,19 +93,10 @@ std::vector<std::pair<int, int>> MarchingSquares<data_type>::march(
}
} while (row != start.first || column != start.second);
//
// Now we need to wash out selected group within contour, leaving those at or
// above threhold
// Get the group the starting point is a member of
for (size_t i = 0; i < mData.size(); ++i)
{
if (mComponent[i] == mComponent[group_i])
{
mData[i] = wash_bit;
}
}
//
// TODO: Simply polygon being returned with Ramer-Douglas-Peuker algorithm
clear_connected_component(start.second, start.first,
mBit[mColumns * start.first + start.second],
wash_bit);
return out;
} // march
......@@ -273,14 +236,4 @@ void MarchingSquares<data_type>::step(size_t r, size_t c)
}
}
template <typename data_type>
void MarchingSquares<data_type>::dump_component_map(std::ostream& os) const
{
for (size_t i = 0; i < mComponent.size(); ++i)
{
os << std::setw(4) << mComponent[i] << ", ";
if (((i + 1) % mColumns) == 0) os << std::endl;
}
os << std::endl;
}
} // namespace radix
......@@ -141,7 +141,6 @@ TEST(MarchingSquares, 4EdgeGroups)
{
std::vector<std::pair<int, int>> contour = ms.march(2., 0., 3.);
// ms.dump_component_map(std::cout);
// std::cout << "{" << std::endl;
// for (size_t i = 0; i < contour.size(); ++i)
// {
......@@ -168,7 +167,6 @@ TEST(MarchingSquares, 4EdgeGroups)
}
{
std::vector<std::pair<int, int>> contour = ms.march(3., 0., 4.);
// ms.dump_component_map(std::cout);
// std::cout << "{" << std::endl;
// for (size_t i = 0; i < contour.size(); ++i)
// {
......@@ -195,7 +193,6 @@ TEST(MarchingSquares, 4EdgeGroups)
}
{
std::vector<std::pair<int, int>> contour = ms.march(4., 0., 5.);
// ms.dump_component_map(std::cout);
// std::cout << "{" << std::endl;
// for (size_t i = 0; i < contour.size(); ++i)
// {
......@@ -222,7 +219,6 @@ TEST(MarchingSquares, 4EdgeGroups)
}
{
std::vector<std::pair<int, int>> contour = ms.march(5.);
// ms.dump_component_map(std::cout);
// std::cout << "{" << std::endl;
// for (size_t i = 0; i < contour.size(); ++i)
// {
......
Supports Markdown
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