Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv_contrib
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv_contrib
Commits
bb5dadd7
Commit
bb5dadd7
authored
Aug 30, 2019
by
Alexander Alekhin
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2236 from szk1509:invMarkerContourDetectionImproved
parents
bb1dee17
93f910e9
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
136 additions
and
163 deletions
+136
-163
aruco.cpp
modules/aruco/src/aruco.cpp
+136
-149
test_arucodetection.cpp
modules/aruco/test/test_arucodetection.cpp
+0
-14
No files found.
modules/aruco/src/aruco.cpp
View file @
bb5dadd7
...
@@ -212,17 +212,20 @@ static void _reorderCandidatesCorners(vector< vector< Point2f > > &candidates) {
...
@@ -212,17 +212,20 @@ static void _reorderCandidatesCorners(vector< vector< Point2f > > &candidates) {
/**
/**
* @brief Check candidates that are too close to each other and remove the smaller one
* @brief Check candidates that are too close to each other, save the potential candidates
* (i.e. biggest/smallest contour) and remove the rest
*/
*/
static
void
_filterTooCloseCandidates
(
const
vector
<
vector
<
Point2f
>
>
&
candidatesIn
,
static
void
_filterTooCloseCandidates
(
const
vector
<
vector
<
Point2f
>
>
&
candidatesIn
,
vector
<
vector
<
Point2f
>
>
&
candidates
Out
,
vector
<
vector
<
vector
<
Point2f
>
>
>
&
candidatesSet
Out
,
const
vector
<
vector
<
Point
>
>
&
contoursIn
,
const
vector
<
vector
<
Point
>
>
&
contoursIn
,
vector
<
vector
<
Point
>
>
&
contours
Out
,
vector
<
vector
<
vector
<
Point
>
>
>
&
contoursSet
Out
,
double
minMarkerDistanceRate
)
{
double
minMarkerDistanceRate
,
bool
detectInvertedMarker
)
{
CV_Assert
(
minMarkerDistanceRate
>=
0
);
CV_Assert
(
minMarkerDistanceRate
>=
0
);
vector
<
pair
<
int
,
int
>
>
nearCandidates
;
vector
<
int
>
candGroup
;
candGroup
.
resize
(
candidatesIn
.
size
(),
-
1
);
vector
<
vector
<
unsigned
int
>
>
groupedCandidates
;
for
(
unsigned
int
i
=
0
;
i
<
candidatesIn
.
size
();
i
++
)
{
for
(
unsigned
int
i
=
0
;
i
<
candidatesIn
.
size
();
i
++
)
{
for
(
unsigned
int
j
=
i
+
1
;
j
<
candidatesIn
.
size
();
j
++
)
{
for
(
unsigned
int
j
=
i
+
1
;
j
<
candidatesIn
.
size
();
j
++
)
{
...
@@ -244,39 +247,86 @@ static void _filterTooCloseCandidates(const vector< vector< Point2f > > &candida
...
@@ -244,39 +247,86 @@ static void _filterTooCloseCandidates(const vector< vector< Point2f > > &candida
// if mean square distance is too low, remove the smaller one of the two markers
// if mean square distance is too low, remove the smaller one of the two markers
double
minMarkerDistancePixels
=
double
(
minimumPerimeter
)
*
minMarkerDistanceRate
;
double
minMarkerDistancePixels
=
double
(
minimumPerimeter
)
*
minMarkerDistanceRate
;
if
(
distSq
<
minMarkerDistancePixels
*
minMarkerDistancePixels
)
{
if
(
distSq
<
minMarkerDistancePixels
*
minMarkerDistancePixels
)
{
nearCandidates
.
push_back
(
pair
<
int
,
int
>
(
i
,
j
));
break
;
// i and j are not related to a group
if
(
candGroup
[
i
]
<
0
&&
candGroup
[
j
]
<
0
){
// mark candidates with their corresponding group number
candGroup
[
i
]
=
candGroup
[
j
]
=
(
int
)
groupedCandidates
.
size
();
// create group
vector
<
unsigned
int
>
grouped
;
grouped
.
push_back
(
i
);
grouped
.
push_back
(
j
);
groupedCandidates
.
push_back
(
grouped
);
}
// i is related to a group
else
if
(
candGroup
[
i
]
>
-
1
&&
candGroup
[
j
]
==
-
1
){
int
group
=
candGroup
[
i
];
candGroup
[
j
]
=
group
;
// add to group
groupedCandidates
[
group
].
push_back
(
j
);
}
// j is related to a group
else
if
(
candGroup
[
j
]
>
-
1
&&
candGroup
[
i
]
==
-
1
){
int
group
=
candGroup
[
j
];
candGroup
[
i
]
=
group
;
// add to group
groupedCandidates
[
group
].
push_back
(
i
);
}
}
}
}
}
}
}
}
}
// mark smaller one in pairs to remove
// save possible candidates
vector
<
bool
>
toRemove
(
candidatesIn
.
size
(),
false
);
candidatesSetOut
.
clear
();
for
(
unsigned
int
i
=
0
;
i
<
nearCandidates
.
size
();
i
++
)
{
contoursSetOut
.
clear
();
// if one of the marker has been already markerd to removed, dont need to do anything
if
(
toRemove
[
nearCandidates
[
i
].
first
]
||
toRemove
[
nearCandidates
[
i
].
second
])
continue
;
vector
<
vector
<
Point2f
>
>
biggerCandidates
;
size_t
perimeter1
=
contoursIn
[
nearCandidates
[
i
].
first
].
size
();
vector
<
vector
<
Point
>
>
biggerContours
;
size_t
perimeter2
=
contoursIn
[
nearCandidates
[
i
].
second
].
size
();
vector
<
vector
<
Point2f
>
>
smallerCandidates
;
if
(
perimeter1
>
perimeter2
)
vector
<
vector
<
Point
>
>
smallerContours
;
toRemove
[
nearCandidates
[
i
].
second
]
=
true
;
else
// save possible candidates
toRemove
[
nearCandidates
[
i
].
first
]
=
true
;
for
(
unsigned
int
i
=
0
;
i
<
groupedCandidates
.
size
();
i
++
)
{
}
int
smallerIdx
=
groupedCandidates
[
i
][
0
];
int
biggerIdx
=
-
1
;
// remove extra candidates
candidatesOut
.
clear
();
// evaluate group elements
unsigned
long
totalRemaining
=
0
;
for
(
unsigned
int
j
=
1
;
j
<
groupedCandidates
[
i
].
size
();
j
++
)
{
for
(
unsigned
int
i
=
0
;
i
<
toRemove
.
size
();
i
++
)
size_t
currPerim
=
contoursIn
[
groupedCandidates
[
i
][
j
]
].
size
();
if
(
!
toRemove
[
i
])
totalRemaining
++
;
candidatesOut
.
resize
(
totalRemaining
);
// check if current contour is bigger
contoursOut
.
resize
(
totalRemaining
);
if
(
biggerIdx
<
0
)
for
(
unsigned
int
i
=
0
,
currIdx
=
0
;
i
<
candidatesIn
.
size
();
i
++
)
{
biggerIdx
=
groupedCandidates
[
i
][
j
];
if
(
toRemove
[
i
])
continue
;
else
if
(
currPerim
>=
contoursIn
[
biggerIdx
].
size
())
candidatesOut
[
currIdx
]
=
candidatesIn
[
i
];
biggerIdx
=
groupedCandidates
[
i
][
j
];
contoursOut
[
currIdx
]
=
contoursIn
[
i
];
currIdx
++
;
// check if current contour is smaller
if
(
currPerim
<
contoursIn
[
smallerIdx
].
size
()
&&
detectInvertedMarker
)
smallerIdx
=
groupedCandidates
[
i
][
j
];
}
// add contours und candidates
if
(
biggerIdx
>
-
1
){
biggerCandidates
.
push_back
(
candidatesIn
[
biggerIdx
]);
biggerContours
.
push_back
(
contoursIn
[
biggerIdx
]);
if
(
detectInvertedMarker
){
smallerCandidates
.
push_back
(
candidatesIn
[
smallerIdx
]);
smallerContours
.
push_back
(
contoursIn
[
smallerIdx
]);
}
}
}
}
// to preserve the structure :: candidateSet< defaultCandidates, whiteCandidates >
// default candidates
candidatesSetOut
.
push_back
(
biggerCandidates
);
contoursSetOut
.
push_back
(
biggerContours
);
// white candidates
candidatesSetOut
.
push_back
(
smallerCandidates
);
contoursSetOut
.
push_back
(
smallerContours
);
}
}
...
@@ -370,8 +420,8 @@ static void _detectInitialCandidates(const Mat &grey, vector< vector< Point2f >
...
@@ -370,8 +420,8 @@ static void _detectInitialCandidates(const Mat &grey, vector< vector< Point2f >
/**
/**
* @brief Detect square candidates in the input image
* @brief Detect square candidates in the input image
*/
*/
static
void
_detectCandidates
(
InputArray
_image
,
vector
<
vector
<
Point2f
>
>&
candidates
Out
,
static
void
_detectCandidates
(
InputArray
_image
,
vector
<
vector
<
vector
<
Point2f
>
>
>&
candidatesSet
Out
,
vector
<
vector
<
Point
>
>&
contours
Out
,
const
Ptr
<
DetectorParameters
>
&
_params
)
{
vector
<
vector
<
vector
<
Point
>
>
>&
contoursSet
Out
,
const
Ptr
<
DetectorParameters
>
&
_params
)
{
Mat
image
=
_image
.
getMat
();
Mat
image
=
_image
.
getMat
();
CV_Assert
(
image
.
total
()
!=
0
);
CV_Assert
(
image
.
total
()
!=
0
);
...
@@ -389,8 +439,9 @@ static void _detectCandidates(InputArray _image, vector< vector< Point2f > >& ca
...
@@ -389,8 +439,9 @@ static void _detectCandidates(InputArray _image, vector< vector< Point2f > >& ca
_reorderCandidatesCorners
(
candidates
);
_reorderCandidatesCorners
(
candidates
);
/// 4. FILTER OUT NEAR CANDIDATE PAIRS
/// 4. FILTER OUT NEAR CANDIDATE PAIRS
_filterTooCloseCandidates
(
candidates
,
candidatesOut
,
contours
,
contoursOut
,
// save the outter/inner border (i.e. potential candidates)
_params
->
minMarkerDistanceRate
);
_filterTooCloseCandidates
(
candidates
,
candidatesSetOut
,
contours
,
contoursSetOut
,
_params
->
minMarkerDistanceRate
,
_params
->
detectInvertedMarker
);
}
}
...
@@ -493,8 +544,11 @@ static int _getBorderErrors(const Mat &bits, int markerSize, int borderSize) {
...
@@ -493,8 +544,11 @@ static int _getBorderErrors(const Mat &bits, int markerSize, int borderSize) {
/**
/**
* @brief Tries to identify one candidate given the dictionary
* @brief Tries to identify one candidate given the dictionary
* @return candidate typ. zero if the candidate is not valid,
* 1 if the candidate is a black candidate (default candidate)
* 2 if the candidate is a white candidate
*/
*/
static
bool
_identifyOneCandidate
(
const
Ptr
<
Dictionary
>&
dictionary
,
InputArray
_image
,
static
uint8_t
_identifyOneCandidate
(
const
Ptr
<
Dictionary
>&
dictionary
,
InputArray
_image
,
vector
<
Point2f
>&
_corners
,
int
&
idx
,
vector
<
Point2f
>&
_corners
,
int
&
idx
,
const
Ptr
<
DetectorParameters
>&
params
)
const
Ptr
<
DetectorParameters
>&
params
)
{
{
...
@@ -502,6 +556,7 @@ static bool _identifyOneCandidate(const Ptr<Dictionary>& dictionary, InputArray
...
@@ -502,6 +556,7 @@ static bool _identifyOneCandidate(const Ptr<Dictionary>& dictionary, InputArray
CV_Assert
(
_image
.
getMat
().
total
()
!=
0
);
CV_Assert
(
_image
.
getMat
().
total
()
!=
0
);
CV_Assert
(
params
->
markerBorderBits
>
0
);
CV_Assert
(
params
->
markerBorderBits
>
0
);
uint8_t
typ
=
1
;
// get bits
// get bits
Mat
candidateBits
=
Mat
candidateBits
=
_extractBits
(
_image
,
_corners
,
dictionary
->
markerSize
,
params
->
markerBorderBits
,
_extractBits
(
_image
,
_corners
,
dictionary
->
markerSize
,
params
->
markerBorderBits
,
...
@@ -523,9 +578,10 @@ static bool _identifyOneCandidate(const Ptr<Dictionary>& dictionary, InputArray
...
@@ -523,9 +578,10 @@ static bool _identifyOneCandidate(const Ptr<Dictionary>& dictionary, InputArray
if
(
invBError
<
borderErrors
){
if
(
invBError
<
borderErrors
){
borderErrors
=
invBError
;
borderErrors
=
invBError
;
invertedImg
.
copyTo
(
candidateBits
);
invertedImg
.
copyTo
(
candidateBits
);
typ
=
2
;
}
}
}
}
if
(
borderErrors
>
maximumErrorsInBorder
)
return
false
;
if
(
borderErrors
>
maximumErrorsInBorder
)
return
0
;
// border is wrong
// take only inner bits
// take only inner bits
Mat
onlyBits
=
Mat
onlyBits
=
...
@@ -536,13 +592,13 @@ static bool _identifyOneCandidate(const Ptr<Dictionary>& dictionary, InputArray
...
@@ -536,13 +592,13 @@ static bool _identifyOneCandidate(const Ptr<Dictionary>& dictionary, InputArray
// try to indentify the marker
// try to indentify the marker
int
rotation
;
int
rotation
;
if
(
!
dictionary
->
identify
(
onlyBits
,
idx
,
rotation
,
params
->
errorCorrectionRate
))
if
(
!
dictionary
->
identify
(
onlyBits
,
idx
,
rotation
,
params
->
errorCorrectionRate
))
return
false
;
return
0
;
// shift corner positions to the correct rotation
// shift corner positions to the correct rotation
if
(
rotation
!=
0
)
{
if
(
rotation
!=
0
)
{
std
::
rotate
(
_corners
.
begin
(),
_corners
.
begin
()
+
4
-
rotation
,
_corners
.
end
());
std
::
rotate
(
_corners
.
begin
(),
_corners
.
begin
()
+
4
-
rotation
,
_corners
.
end
());
}
}
return
t
rue
;
return
t
yp
;
}
}
...
@@ -554,22 +610,24 @@ class IdentifyCandidatesParallel : public ParallelLoopBody {
...
@@ -554,22 +610,24 @@ class IdentifyCandidatesParallel : public ParallelLoopBody {
public
:
public
:
IdentifyCandidatesParallel
(
const
Mat
&
_grey
,
vector
<
vector
<
Point2f
>
>&
_candidates
,
IdentifyCandidatesParallel
(
const
Mat
&
_grey
,
vector
<
vector
<
Point2f
>
>&
_candidates
,
const
Ptr
<
Dictionary
>
&
_dictionary
,
const
Ptr
<
Dictionary
>
&
_dictionary
,
vector
<
int
>&
_idsTmp
,
vector
<
char
>&
_validCandidates
,
vector
<
int
>&
_idsTmp
,
vector
<
uint8_t
>&
_validCandidates
,
const
Ptr
<
DetectorParameters
>
&
_params
)
const
Ptr
<
DetectorParameters
>
&
_params
)
:
grey
(
_grey
),
candidates
(
_candidates
),
dictionary
(
_dictionary
),
:
grey
(
_grey
),
candidates
(
_candidates
),
dictionary
(
_dictionary
),
idsTmp
(
_idsTmp
),
validCandidates
(
_validCandidates
),
params
(
_params
)
{}
idsTmp
(
_idsTmp
),
validCandidates
(
_validCandidates
),
params
(
_params
)
{}
void
operator
()(
const
Range
&
range
)
const
CV_OVERRIDE
{
void
operator
()(
const
Range
&
range
)
const
CV_OVERRIDE
{
const
int
begin
=
range
.
start
;
const
int
begin
=
range
.
start
;
const
int
end
=
range
.
end
;
const
int
end
=
range
.
end
;
for
(
int
i
=
begin
;
i
<
end
;
i
++
)
{
for
(
int
i
=
begin
;
i
<
end
;
i
++
)
{
int
currId
;
int
currId
;
if
(
_identifyOneCandidate
(
dictionary
,
grey
,
candidates
[
i
],
currId
,
params
))
{
validCandidates
[
i
]
=
_identifyOneCandidate
(
dictionary
,
grey
,
candidates
[
i
],
currId
,
params
);
validCandidates
[
i
]
=
1
;
if
(
validCandidates
[
i
]
>
0
)
idsTmp
[
i
]
=
currId
;
idsTmp
[
i
]
=
currId
;
}
}
}
}
}
private
:
private
:
...
@@ -579,7 +637,7 @@ class IdentifyCandidatesParallel : public ParallelLoopBody {
...
@@ -579,7 +637,7 @@ class IdentifyCandidatesParallel : public ParallelLoopBody {
vector
<
vector
<
Point2f
>
>&
candidates
;
vector
<
vector
<
Point2f
>
>&
candidates
;
const
Ptr
<
Dictionary
>
&
dictionary
;
const
Ptr
<
Dictionary
>
&
dictionary
;
vector
<
int
>
&
idsTmp
;
vector
<
int
>
&
idsTmp
;
vector
<
char
>
&
validCandidates
;
vector
<
uint8_t
>
&
validCandidates
;
const
Ptr
<
DetectorParameters
>
&
params
;
const
Ptr
<
DetectorParameters
>
&
params
;
};
};
...
@@ -623,14 +681,13 @@ static void _copyVector2Output(vector< vector< Point2f > > &vec, OutputArrayOfAr
...
@@ -623,14 +681,13 @@ static void _copyVector2Output(vector< vector< Point2f > > &vec, OutputArrayOfAr
/**
/**
* @brief Identify square candidates according to a marker dictionary
* @brief Identify square candidates according to a marker dictionary
*/
*/
static
void
_identifyCandidates
(
InputArray
_image
,
vector
<
vector
<
Point2f
>
>&
_candidates
,
static
void
_identifyCandidates
(
InputArray
_image
,
vector
<
vector
<
vector
<
Point2f
>
>
>&
_candidatesSet
,
vector
<
vector
<
Point
>
>&
_contours
,
const
Ptr
<
Dictionary
>
&
_dictionary
,
vector
<
vector
<
vector
<
Point
>
>
>&
_contoursSet
,
const
Ptr
<
Dictionary
>
&
_dictionary
,
vector
<
vector
<
Point2f
>
>&
_accepted
,
vector
<
int
>&
ids
,
vector
<
vector
<
Point2f
>
>&
_accepted
,
vector
<
vector
<
Point
>
>&
_contours
,
vector
<
int
>&
ids
,
const
Ptr
<
DetectorParameters
>
&
params
,
const
Ptr
<
DetectorParameters
>
&
params
,
OutputArrayOfArrays
_rejected
=
noArray
())
{
OutputArrayOfArrays
_rejected
=
noArray
())
{
int
ncandidates
=
(
int
)
_candidates
.
size
();
int
ncandidates
=
(
int
)
_candidatesSet
[
0
].
size
();
vector
<
vector
<
Point2f
>
>
accepted
;
vector
<
vector
<
Point2f
>
>
accepted
;
vector
<
vector
<
Point2f
>
>
rejected
;
vector
<
vector
<
Point2f
>
>
rejected
;
...
@@ -642,32 +699,33 @@ static void _identifyCandidates(InputArray _image, vector< vector< Point2f > >&
...
@@ -642,32 +699,33 @@ static void _identifyCandidates(InputArray _image, vector< vector< Point2f > >&
_convertToGrey
(
_image
.
getMat
(),
grey
);
_convertToGrey
(
_image
.
getMat
(),
grey
);
vector
<
int
>
idsTmp
(
ncandidates
,
-
1
);
vector
<
int
>
idsTmp
(
ncandidates
,
-
1
);
vector
<
char
>
validCandidates
(
ncandidates
,
0
);
vector
<
uint8_t
>
validCandidates
(
ncandidates
,
0
);
//// Analyze each of the candidates
//// Analyze each of the candidates
// for (int i = 0; i < ncandidates; i++) {
// int currId = i;
// Mat currentCandidate = _candidates.getMat(i);
// if (_identifyOneCandidate(dictionary, grey, currentCandidate, currId, params)) {
// validCandidates[i] = 1;
// idsTmp[i] = currId;
// }
//}
// this is the parallel call for the previous commented loop (result is equivalent)
parallel_for_
(
Range
(
0
,
ncandidates
),
parallel_for_
(
Range
(
0
,
ncandidates
),
IdentifyCandidatesParallel
(
grey
,
_candidates
,
_dictionary
,
idsTmp
,
IdentifyCandidatesParallel
(
grey
,
params
->
detectInvertedMarker
?
_candidatesSet
[
1
]
:
_candidatesSet
[
0
],
_dictionary
,
idsTmp
,
validCandidates
,
params
));
validCandidates
,
params
));
for
(
int
i
=
0
;
i
<
ncandidates
;
i
++
)
{
for
(
int
i
=
0
;
i
<
ncandidates
;
i
++
)
{
if
(
validCandidates
[
i
]
==
1
)
{
if
(
validCandidates
[
i
]
>
0
)
{
accepted
.
push_back
(
_candidates
[
i
]);
// add the white valid candidate
if
(
params
->
detectInvertedMarker
&&
validCandidates
[
i
]
==
2
){
accepted
.
push_back
(
_candidatesSet
[
1
][
i
]);
ids
.
push_back
(
idsTmp
[
i
]);
contours
.
push_back
(
_contoursSet
[
1
][
i
]);
continue
;
}
// add the default (black) valid candidate
accepted
.
push_back
(
_candidatesSet
[
0
][
i
]);
ids
.
push_back
(
idsTmp
[
i
]);
ids
.
push_back
(
idsTmp
[
i
]);
contours
.
push_back
(
_contours
[
i
]);
contours
.
push_back
(
_contours
Set
[
0
]
[
i
]);
}
else
{
}
else
{
rejected
.
push_back
(
_candidates
[
i
]);
rejected
.
push_back
(
_candidates
Set
[
0
]
[
i
]);
}
}
}
}
...
@@ -682,80 +740,6 @@ static void _identifyCandidates(InputArray _image, vector< vector< Point2f > >&
...
@@ -682,80 +740,6 @@ static void _identifyCandidates(InputArray _image, vector< vector< Point2f > >&
}
}
/**
* @brief Final filter of markers after its identification
*/
static
void
_filterDetectedMarkers
(
vector
<
vector
<
Point2f
>
>&
_corners
,
vector
<
int
>&
_ids
,
vector
<
vector
<
Point
>
>&
_contours
)
{
CV_Assert
(
_corners
.
size
()
==
_ids
.
size
());
if
(
_corners
.
empty
())
return
;
// mark markers that will be removed
vector
<
bool
>
toRemove
(
_corners
.
size
(),
false
);
bool
atLeastOneRemove
=
false
;
// remove repeated markers with same id, if one contains the other (doble border bug)
for
(
unsigned
int
i
=
0
;
i
<
_corners
.
size
()
-
1
;
i
++
)
{
for
(
unsigned
int
j
=
i
+
1
;
j
<
_corners
.
size
();
j
++
)
{
if
(
_ids
[
i
]
!=
_ids
[
j
])
continue
;
// check if first marker is inside second
bool
inside
=
true
;
for
(
unsigned
int
p
=
0
;
p
<
4
;
p
++
)
{
Point2f
point
=
_corners
[
j
][
p
];
if
(
pointPolygonTest
(
_corners
[
i
],
point
,
false
)
<
0
)
{
inside
=
false
;
break
;
}
}
if
(
inside
)
{
toRemove
[
j
]
=
true
;
atLeastOneRemove
=
true
;
continue
;
}
// check the second marker
inside
=
true
;
for
(
unsigned
int
p
=
0
;
p
<
4
;
p
++
)
{
Point2f
point
=
_corners
[
i
][
p
];
if
(
pointPolygonTest
(
_corners
[
j
],
point
,
false
)
<
0
)
{
inside
=
false
;
break
;
}
}
if
(
inside
)
{
toRemove
[
i
]
=
true
;
atLeastOneRemove
=
true
;
continue
;
}
}
}
// parse output
if
(
atLeastOneRemove
)
{
vector
<
vector
<
Point2f
>
>::
iterator
filteredCorners
=
_corners
.
begin
();
vector
<
int
>::
iterator
filteredIds
=
_ids
.
begin
();
vector
<
vector
<
Point
>
>::
iterator
filteredContours
=
_contours
.
begin
();
for
(
unsigned
int
i
=
0
;
i
<
toRemove
.
size
();
i
++
)
{
if
(
!
toRemove
[
i
])
{
*
filteredCorners
++
=
_corners
[
i
];
*
filteredIds
++
=
_ids
[
i
];
*
filteredContours
++
=
_contours
[
i
];
}
}
_ids
.
erase
(
filteredIds
,
_ids
.
end
());
_corners
.
erase
(
filteredCorners
,
_corners
.
end
());
_contours
.
erase
(
filteredContours
,
_contours
.
end
());
}
}
/**
/**
* @brief Return object points for the system centered in a single marker, given the marker length
* @brief Return object points for the system centered in a single marker, given the marker length
*/
*/
...
@@ -1127,26 +1111,29 @@ void detectMarkers(InputArray _image, const Ptr<Dictionary> &_dictionary, Output
...
@@ -1127,26 +1111,29 @@ void detectMarkers(InputArray _image, const Ptr<Dictionary> &_dictionary, Output
vector
<
vector
<
Point
>
>
contours
;
vector
<
vector
<
Point
>
>
contours
;
vector
<
int
>
ids
;
vector
<
int
>
ids
;
vector
<
vector
<
vector
<
Point2f
>
>
>
candidatesSet
;
vector
<
vector
<
vector
<
Point
>
>
>
contoursSet
;
/// STEP 1.a Detect marker candidates :: using AprilTag
/// STEP 1.a Detect marker candidates :: using AprilTag
if
(
_params
->
cornerRefinementMethod
==
CORNER_REFINE_APRILTAG
)
if
(
_params
->
cornerRefinementMethod
==
CORNER_REFINE_APRILTAG
)
{
_apriltag
(
grey
,
_params
,
candidates
,
contours
);
_apriltag
(
grey
,
_params
,
candidates
,
contours
);
candidatesSet
.
push_back
(
candidates
);
contoursSet
.
push_back
(
contours
);
}
/// STEP 1.b Detect marker candidates :: traditional way
/// STEP 1.b Detect marker candidates :: traditional way
else
else
_detectCandidates
(
grey
,
candidates
,
contours
,
_params
);
_detectCandidates
(
grey
,
candidates
Set
,
contoursSet
,
_params
);
/// STEP 2: Check candidate codification (identify markers)
/// STEP 2: Check candidate codification (identify markers)
_identifyCandidates
(
grey
,
candidates
,
contours
,
_dictionary
,
candidate
s
,
ids
,
_params
,
_identifyCandidates
(
grey
,
candidates
Set
,
contoursSet
,
_dictionary
,
candidates
,
contour
s
,
ids
,
_params
,
_rejectedImgPoints
);
_rejectedImgPoints
);
/// STEP 3: Filter detected markers;
_filterDetectedMarkers
(
candidates
,
ids
,
contours
);
// copy to output arrays
// copy to output arrays
_copyVector2Output
(
candidates
,
_corners
);
_copyVector2Output
(
candidates
,
_corners
);
Mat
(
ids
).
copyTo
(
_ids
);
Mat
(
ids
).
copyTo
(
_ids
);
/// STEP
4
: Corner refinement :: use corner subpix
/// STEP
3
: Corner refinement :: use corner subpix
if
(
_params
->
cornerRefinementMethod
==
CORNER_REFINE_SUBPIX
)
{
if
(
_params
->
cornerRefinementMethod
==
CORNER_REFINE_SUBPIX
)
{
CV_Assert
(
_params
->
cornerRefinementWinSize
>
0
&&
_params
->
cornerRefinementMaxIterations
>
0
&&
CV_Assert
(
_params
->
cornerRefinementWinSize
>
0
&&
_params
->
cornerRefinementMaxIterations
>
0
&&
_params
->
cornerRefinementMinAccuracy
>
0
);
_params
->
cornerRefinementMinAccuracy
>
0
);
...
@@ -1165,7 +1152,7 @@ void detectMarkers(InputArray _image, const Ptr<Dictionary> &_dictionary, Output
...
@@ -1165,7 +1152,7 @@ void detectMarkers(InputArray _image, const Ptr<Dictionary> &_dictionary, Output
MarkerSubpixelParallel
(
&
grey
,
_corners
,
_params
));
MarkerSubpixelParallel
(
&
grey
,
_corners
,
_params
));
}
}
/// STEP
4
, Optional : Corner refinement :: use contour container
/// STEP
3
, Optional : Corner refinement :: use contour container
if
(
_params
->
cornerRefinementMethod
==
CORNER_REFINE_CONTOUR
){
if
(
_params
->
cornerRefinementMethod
==
CORNER_REFINE_CONTOUR
){
if
(
!
_ids
.
empty
()){
if
(
!
_ids
.
empty
()){
...
...
modules/aruco/test/test_arucodetection.cpp
View file @
bb5dadd7
...
@@ -322,19 +322,6 @@ void CV_ArucoDetectionPerspective::run(int tryWith) {
...
@@ -322,19 +322,6 @@ void CV_ArucoDetectionPerspective::run(int tryWith) {
}
}
for
(
int
c
=
0
;
c
<
4
;
c
++
)
{
for
(
int
c
=
0
;
c
<
4
;
c
++
)
{
double
dist
=
cv
::
norm
(
groundTruthCorners
[
c
]
-
corners
[
0
][
c
]);
// TODO cvtest
double
dist
=
cv
::
norm
(
groundTruthCorners
[
c
]
-
corners
[
0
][
c
]);
// TODO cvtest
if
(
CV_ArucoDetectionPerspective
::
DETECT_INVERTED_MARKER
==
tryWith
){
if
(
szEnclosed
&&
dist
>
3
){
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Incorrect marker corners position"
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_BAD_ACCURACY
);
return
;
}
if
(
!
szEnclosed
&&
dist
>
15
){
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Incorrect marker corners position"
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_BAD_ACCURACY
);
return
;
}
}
else
{
if
(
dist
>
5
)
{
if
(
dist
>
5
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Incorrect marker corners position"
);
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Incorrect marker corners position"
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_BAD_ACCURACY
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_BAD_ACCURACY
);
...
@@ -343,7 +330,6 @@ void CV_ArucoDetectionPerspective::run(int tryWith) {
...
@@ -343,7 +330,6 @@ void CV_ArucoDetectionPerspective::run(int tryWith) {
}
}
}
}
}
}
}
// change the state :: to detect an enclosed inverted marker
// change the state :: to detect an enclosed inverted marker
if
(
CV_ArucoDetectionPerspective
::
DETECT_INVERTED_MARKER
==
tryWith
&&
distance
==
0.1
){
if
(
CV_ArucoDetectionPerspective
::
DETECT_INVERTED_MARKER
==
tryWith
&&
distance
==
0.1
){
distance
-=
0.1
;
distance
-=
0.1
;
...
...
Write
Preview
Markdown
is supported
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