Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
LEFEBVREJP email
radix
Commits
2f73167c
Commit
2f73167c
authored
Jun 20, 2018
by
LEFEBVREJP email
Browse files
Merge branch '19-iterative-ccl' into 'master'
Resolve "iterative ccl" Closes
#19
See merge request
!39
parents
8b4804f4
3d1a88c5
Pipeline
#13802
passed with stages
in 25 minutes and 21 seconds
Changes
3
Pipelines
1
Show whitespace changes
Inline
Side-by-side
radixalgorithm/marchingsquares.hh
View file @
2f73167c
...
...
@@ -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
row
,
int
col
,
size_t
label
,
data_type
wash_bit
);
public:
/**
...
...
radixalgorithm/marchingsquares.i.hh
View file @
2f73167c
#include
<array>
#include
<unordered_set>
#include
<set>
#include
<vector>
#include
"radixalgorithm/marchingsquares.hh"
...
...
@@ -9,36 +8,45 @@
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
row
,
int
col
,
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
;
if
(
row
<
0
||
row
==
mColumns
)
return
;
// out of bounds
if
(
col
<
0
||
col
==
mRows
)
return
;
// out of bounds
std
::
set
<
size_t
>
list
;
list
.
insert
(
mColumns
*
row
+
col
);
while
(
!
list
.
empty
())
{
const
auto
&
it
=
list
.
begin
();
size_t
c_i
=
*
it
;
// recursively mark the neighbors
// update the row
row
=
c_i
/
mColumns
;
// upate the column
col
=
c_i
%
mColumns
;
// clear data
mBit
[
c_i
]
=
0
;
mData
[
c_i
]
=
wash_bit
;
// search 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
)
{
// 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
);
size_t
nc
=
col
+
dx
[
direction
];
size_t
nr
=
row
+
dy
[
direction
];
if
(
nc
<
0
||
nc
==
mColumns
)
continue
;
// out of bounds
if
(
nr
<
0
||
nr
==
mRows
)
continue
;
// out of bounds
size_t
nc_i
=
mColumns
*
nr
+
nc
;
if
(
mBit
[
nc_i
]
==
label
)
{
// if we already have this cell in the list to look at
// don't add it again
if
(
list
.
find
(
nc_i
)
==
list
.
end
())
{
list
.
insert
(
nc_i
);
}
}
}
list
.
erase
(
it
);
}
}
...
...
@@ -74,33 +82,25 @@ 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
size_t
row
=
start
.
first
,
column
=
start
.
second
;
radix_tagged_line
(
"Starting ("
<<
row
<<
", "
<<
column
<<
")"
);
do
{
step
(
row
,
column
);
// If our current point is within our image
// add it to the list of points
if
(
column
>=
0
&&
column
<
mColumns
&&
row
>=
0
&&
row
<
mRows
)
// We have to allow for row and column being equal to the number
// of rows and columns to allow for traveling the boundaries
if
(
column
>=
0
&&
column
<=
mColumns
&&
row
>=
0
&&
row
<=
mRows
)
{
radix_tagged_line
(
"("
<<
row
<<
", "
<<
column
<<
") ="
<<
int
(
next_step
));
out
.
push_back
({
row
,
column
});
}
switch
(
next_step
)
{
...
...
@@ -121,19 +121,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
.
first
,
start
.
second
,
mBit
[
mColumns
*
start
.
first
+
start
.
second
],
wash_bit
);
return
out
;
}
// march
...
...
@@ -186,8 +177,8 @@ void MarchingSquares<data_type>::step(size_t r, size_t c)
if
(
u_left
)
state
|=
1
;
if
(
u_right
)
state
|=
2
;
if
(
l_
lef
t
)
state
|=
4
;
if
(
l_
righ
t
)
state
|=
8
;
if
(
l_
righ
t
)
state
|=
4
;
if
(
l_
lef
t
)
state
|=
8
;
// State now contains a number between 0 and 15
// representing our state.
// In binary, it looks like 0000-1111 (in binary)
...
...
@@ -212,60 +203,67 @@ void MarchingSquares<data_type>::step(size_t r, size_t c)
switch
(
state
)
{
case
1
:
next_step
=
StepDirection
::
Up
;
next_step
=
StepDirection
::
Left
;
break
;
case
2
:
if
(
prev_step
==
StepDirection
::
Left
)
next_step
=
StepDirection
::
Up
;
else
next_step
=
StepDirection
::
Right
;
break
;
case
3
:
next_step
=
StepDirection
::
Righ
t
;
next_step
=
StepDirection
::
Lef
t
;
break
;
case
4
:
next_step
=
StepDirection
::
Lef
t
;
next_step
=
StepDirection
::
Righ
t
;
break
;
case
5
:
next_step
=
StepDirection
::
Up
;
break
;
case
6
:
if
(
prev_step
==
StepDirection
::
Up
)
{
next_step
=
StepDirection
::
Left
;
}
if
(
prev_step
==
StepDirection
::
Down
)
next_step
=
StepDirection
::
Down
;
else
{
next_step
=
StepDirection
::
Right
;
}
next_step
=
StepDirection
::
Up
;
break
;
case
7
:
next_step
=
StepDirection
::
Right
;
if
(
prev_step
==
StepDirection
::
Up
)
next_step
=
StepDirection
::
Left
;
else
next_step
=
StepDirection
::
Down
;
break
;
case
8
:
next_step
=
StepDirection
::
Down
;
break
;
case
9
:
if
(
prev_step
==
StepDirection
::
Right
)
{
next_step
=
StepDirection
::
Up
;
}
else
{
if
(
prev_step
==
StepDirection
::
Down
)
next_step
=
StepDirection
::
Down
;
}
else
next_step
=
StepDirection
::
Up
;
break
;
case
10
:
next_step
=
StepDirection
::
Down
;
break
;
case
11
:
if
(
prev_step
==
StepDirection
::
Left
)
next_step
=
StepDirection
::
Down
;
else
next_step
=
StepDirection
::
Right
;
break
;
case
12
:
next_step
=
StepDirection
::
Lef
t
;
next_step
=
StepDirection
::
Righ
t
;
break
;
case
13
:
next_step
=
StepDirection
::
Up
;
if
(
prev_step
==
StepDirection
::
Down
)
next_step
=
StepDirection
::
Right
;
else
next_step
==
StepDirection
::
Up
;
break
;
case
14
:
if
(
prev_step
==
StepDirection
::
Down
)
next_step
=
StepDirection
::
Left
;
else
next_step
=
StepDirection
::
Up
;
break
;
default:
next_step
=
StepDirection
::
None
;
...
...
@@ -273,14 +271,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
radixalgorithm/tests/tstMarchingSquares.cc
View file @
2f73167c
...
...
@@ -39,14 +39,14 @@ TEST(MarchingSquares, Simple)
// std::cout << "}" << std::endl;
std
::
vector
<
std
::
pair
<
int
,
int
>>
blessed
{
{
1
,
2
},
{
2
,
2
},
{
3
,
2
},
{
4
,
2
},
{
5
,
2
},
{
6
,
2
},
{
7
,
2
},
{
8
,
2
},
{
8
,
3
},
{
8
,
4
},
{
8
,
5
},
{
8
,
6
},
{
8
,
7
},
{
8
,
8
},
{
8
,
9
},
{
8
,
10
},
{
8
,
1
1
},
{
8
,
1
2
},
{
8
,
1
3
},
{
7
,
1
3
},
{
6
,
1
3
},
{
5
,
13
},
{
5
,
12
},
{
5
,
11
},
{
4
,
11
},
{
4
,
10
},
{
4
,
9
},
{
3
,
9
},
{
3
,
8
},
{
3
,
7
},
{
2
,
7
},
{
2
,
6
},
{
2
,
5
},
{
3
,
5
},
{
3
,
6
},
{
4
,
6
},
{
4
,
7
},
{
4
,
8
},
{
5
,
8
},
{
5
,
9
},
{
5
,
1
0
},
{
6
,
1
0
},
{
6
,
1
1
},
{
7
,
1
1
},
{
7
,
1
0
},
{
7
,
9
},
{
7
,
8
},
{
7
,
7
},
{
7
,
6
},
{
7
,
5
},
{
7
,
4
},
{
7
,
3
},
{
6
,
3
},
{
5
,
3
},
{
4
,
3
},
{
4
,
4
},
{
3
,
4
},
{
2
,
4
},
{
1
,
4
},
{
1
,
3
}};
{
1
,
2
},
{
1
,
3
},
{
1
,
4
},
{
2
,
4
},
{
3
,
4
},
{
4
,
4
},
{
4
,
3
},
{
5
,
3
},
{
6
,
3
},
{
7
,
3
},
{
7
,
4
},
{
7
,
5
},
{
7
,
6
},
{
7
,
7
},
{
7
,
8
},
{
7
,
9
},
{
7
,
1
0
},
{
7
,
1
1
},
{
6
,
1
1
},
{
6
,
1
0
},
{
5
,
1
0
},
{
5
,
9
},
{
5
,
8
},
{
4
,
8
},
{
4
,
7
},
{
4
,
6
},
{
3
,
6
},
{
3
,
5
},
{
2
,
5
},
{
2
,
6
},
{
2
,
7
},
{
3
,
7
},
{
3
,
8
},
{
3
,
9
},
{
4
,
9
},
{
4
,
10
},
{
4
,
11
},
{
5
,
11
},
{
5
,
12
},
{
5
,
13
},
{
6
,
1
3
},
{
7
,
1
3
},
{
8
,
1
3
},
{
8
,
1
2
},
{
8
,
1
1
},
{
8
,
10
},
{
8
,
9
},
{
8
,
8
},
{
8
,
7
},
{
8
,
6
},
{
8
,
5
},
{
8
,
4
},
{
8
,
3
},
{
8
,
2
},
{
7
,
2
},
{
6
,
2
},
{
5
,
2
},
{
4
,
2
},
{
3
,
2
},
{
2
,
2
}};
ASSERT_EQ
(
blessed
.
size
(),
contour
.
size
());
for
(
size_t
i
=
0
;
i
<
blessed
.
size
();
++
i
)
...
...
@@ -77,15 +77,26 @@ TEST(MarchingSquares, TwoGroups)
std
::
vector
<
std
::
pair
<
int
,
int
>>
first_contour
=
ms
.
march
(
2.
);
std
::
vector
<
std
::
pair
<
int
,
int
>>
first_blessed
{
{
1
,
2
},
{
2
,
2
},
{
3
,
2
},
{
4
,
2
},
{
5
,
2
},
{
6
,
2
},
{
7
,
2
},
{
8
,
2
},
{
8
,
3
},
{
8
,
4
},
{
8
,
5
},
{
8
,
6
},
{
8
,
7
},
{
8
,
8
},
{
8
,
9
},
{
8
,
10
},
{
8
,
11
},
{
8
,
12
},
{
8
,
13
},
{
7
,
13
},
{
6
,
13
},
{
5
,
13
},
{
5
,
12
},
{
5
,
11
},
{
4
,
11
},
{
4
,
10
},
{
4
,
9
},
{
3
,
9
},
{
3
,
8
},
{
3
,
7
},
{
2
,
7
},
{
2
,
6
},
{
2
,
5
},
{
3
,
5
},
{
3
,
6
},
{
4
,
6
},
{
4
,
7
},
{
4
,
8
},
{
5
,
8
},
{
5
,
9
},
{
5
,
10
},
{
6
,
10
},
{
6
,
11
},
{
7
,
11
},
{
7
,
10
},
{
7
,
9
},
{
7
,
8
},
{
7
,
7
},
{
7
,
6
},
{
7
,
5
},
{
7
,
4
},
{
7
,
3
},
{
6
,
3
},
{
5
,
3
},
{
4
,
3
},
{
4
,
4
},
{
3
,
4
},
{
2
,
4
},
{
1
,
4
},
{
1
,
3
}};
{
1
,
2
},
{
1
,
3
},
{
1
,
4
},
{
2
,
4
},
{
3
,
4
},
{
4
,
4
},
{
4
,
3
},
{
5
,
3
},
{
6
,
3
},
{
7
,
3
},
{
7
,
4
},
{
7
,
5
},
{
7
,
6
},
{
7
,
7
},
{
7
,
8
},
{
7
,
9
},
{
7
,
10
},
{
7
,
11
},
{
6
,
11
},
{
6
,
10
},
{
5
,
10
},
{
5
,
9
},
{
5
,
8
},
{
4
,
8
},
{
4
,
7
},
{
4
,
6
},
{
3
,
6
},
{
3
,
5
},
{
2
,
5
},
{
2
,
6
},
{
2
,
7
},
{
3
,
7
},
{
3
,
8
},
{
3
,
9
},
{
4
,
9
},
{
4
,
10
},
{
4
,
11
},
{
5
,
11
},
{
5
,
12
},
{
5
,
13
},
{
6
,
13
},
{
7
,
13
},
{
8
,
13
},
{
8
,
12
},
{
8
,
11
},
{
8
,
10
},
{
8
,
9
},
{
8
,
8
},
{
8
,
7
},
{
8
,
6
},
{
8
,
5
},
{
8
,
4
},
{
8
,
3
},
{
8
,
2
},
{
7
,
2
},
{
6
,
2
},
{
5
,
2
},
{
4
,
2
},
{
3
,
2
},
{
2
,
2
}};
// std::cout << "{" << std::endl;
// for (size_t i = 0; i < first_contour.size(); ++i)
// {
// const auto& pixel = first_contour[i];
// std::cout << "{" << pixel.first << "," << pixel.second << "}";
// if (i != first_contour.size() - 1)
// {
// std::cout << ",";
// }
// std::cout << std::endl;
// }
// std::cout << "}" << std::endl;
ASSERT_EQ
(
first_blessed
.
size
(),
first_contour
.
size
());
for
(
size_t
i
=
0
;
i
<
first_blessed
.
size
();
++
i
)
{
...
...
@@ -95,7 +106,7 @@ TEST(MarchingSquares, TwoGroups)
{
// get the second grouping
std
::
vector
<
std
::
pair
<
int
,
int
>>
second_contour
=
ms
.
march
(
2.
);
//
std::cout << "[ row , col ]" << std::endl;
std
::
cout
<<
"[ row , col ]"
<<
std
::
endl
;
// std::cout << "{" << std::endl;
// for (size_t i = 0; i < second_contour.size(); ++i)
// {
...
...
@@ -109,7 +120,7 @@ TEST(MarchingSquares, TwoGroups)
// }
// std::cout << "}" << std::endl;
std
::
vector
<
std
::
pair
<
int
,
int
>>
second_blessed
{
{
7
,
16
},
{
8
,
1
6
},
{
9
,
1
6
},
{
9
,
1
7
},
{
9
,
18
},
{
8
,
1
8
},
{
7
,
1
8
},
{
7
,
1
7
}};
{
7
,
16
},
{
7
,
1
7
},
{
7
,
1
8
},
{
8
,
1
8
},
{
9
,
18
},
{
9
,
1
7
},
{
9
,
1
6
},
{
8
,
1
6
}};
ASSERT_EQ
(
second_blessed
.
size
(),
second_contour
.
size
());
for
(
size_t
i
=
0
;
i
<
second_blessed
.
size
();
++
i
)
{
...
...
@@ -141,7 +152,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)
// {
...
...
@@ -155,8 +165,8 @@ TEST(MarchingSquares, 4EdgeGroups)
// }
// std::cout << "}" << std::endl;
std
::
vector
<
std
::
pair
<
int
,
int
>>
blessed
{
{
2
,
0
},
{
3
,
0
},
{
4
,
0
},
{
5
,
0
},
{
6
,
0
},
{
7
,
0
},
{
8
,
0
},
{
8
,
1
},
{
8
,
2
},
{
7
,
2
},
{
6
,
2
},
{
5
,
2
},
{
4
,
2
},
{
3
,
2
},
{
2
,
2
},
{
2
,
1
}};
{
2
,
0
},
{
2
,
1
},
{
2
,
2
},
{
3
,
2
},
{
4
,
2
},
{
5
,
2
},
{
6
,
2
},
{
7
,
2
},
{
8
,
2
},
{
8
,
1
},
{
8
,
0
},
{
7
,
0
},
{
6
,
0
},
{
5
,
0
},
{
4
,
0
},
{
3
,
0
}};
ASSERT_EQ
(
blessed
.
size
(),
contour
.
size
());
for
(
size_t
i
=
0
;
i
<
blessed
.
size
();
++
i
)
...
...
@@ -168,7 +178,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)
// {
...
...
@@ -181,9 +190,10 @@ TEST(MarchingSquares, 4EdgeGroups)
// std::cout << std::endl;
// }
// std::cout << "}" << std::endl;
std
::
vector
<
std
::
pair
<
int
,
int
>>
blessed
{{
6
,
6
},
{
7
,
6
},
{
8
,
6
},
{
9
,
6
},
{
9
,
5
},
{
9
,
4
},
{
9
,
3
},
{
9
,
8
},
{
8
,
8
},
{
7
,
8
},
{
6
,
8
},
{
6
,
7
}};
std
::
vector
<
std
::
pair
<
int
,
int
>>
blessed
{
{
6
,
6
},
{
6
,
7
},
{
6
,
8
},
{
7
,
8
},
{
8
,
8
},
{
9
,
8
},
{
10
,
8
},
{
10
,
7
},
{
10
,
6
},
{
10
,
5
},
{
10
,
4
},
{
10
,
3
},
{
9
,
3
},
{
9
,
4
},
{
9
,
5
},
{
9
,
6
},
{
8
,
6
},
{
7
,
6
}};
ASSERT_EQ
(
blessed
.
size
(),
contour
.
size
());
for
(
size_t
i
=
0
;
i
<
blessed
.
size
();
++
i
)
...
...
@@ -195,7 +205,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)
// {
...
...
@@ -209,8 +218,9 @@ TEST(MarchingSquares, 4EdgeGroups)
// }
// std::cout << "}" << std::endl;
std
::
vector
<
std
::
pair
<
int
,
int
>>
blessed
{
{
4
,
18
},
{
5
,
18
},
{
5
,
17
},
{
6
,
17
},
{
7
,
17
},
{
8
,
17
},
{
8
,
18
},
{
9
,
18
},
{
9
,
19
},
{
8
,
19
},
{
7
,
19
},
{
6
,
19
},
{
4
,
19
}};
{
4
,
18
},
{
4
,
19
},
{
4
,
20
},
{
5
,
20
},
{
6
,
20
},
{
6
,
19
},
{
7
,
19
},
{
8
,
19
},
{
8
,
20
},
{
9
,
20
},
{
9
,
19
},
{
9
,
18
},
{
8
,
18
},
{
8
,
17
},
{
7
,
17
},
{
6
,
17
},
{
5
,
17
},
{
5
,
18
}};
ASSERT_EQ
(
blessed
.
size
(),
contour
.
size
());
for
(
size_t
i
=
0
;
i
<
blessed
.
size
();
++
i
)
...
...
@@ -222,7 +232,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)
// {
...
...
@@ -235,9 +244,9 @@ TEST(MarchingSquares, 4EdgeGroups)
// std::cout << std::endl;
// }
// std::cout << "}" << std::endl;
std
::
vector
<
std
::
pair
<
int
,
int
>>
blessed
{{
0
,
14
},
{
1
,
1
4
},
{
2
,
1
4
},
{
2
,
1
5
},
{
2
,
1
6
},
{
2
,
17
},
{
1
,
1
7
},
{
0
,
1
7
},
{
0
,
1
6
},
{
0
,
1
5
}};
std
::
vector
<
std
::
pair
<
int
,
int
>>
blessed
{{
0
,
14
},
{
0
,
1
5
},
{
0
,
1
6
},
{
0
,
1
7
},
{
1
,
1
7
},
{
2
,
17
},
{
2
,
1
6
},
{
2
,
1
5
},
{
2
,
1
4
},
{
1
,
1
4
}};
ASSERT_EQ
(
blessed
.
size
(),
contour
.
size
());
for
(
size_t
i
=
0
;
i
<
blessed
.
size
();
++
i
)
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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