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
b2f08277
Commit
b2f08277
authored
Jun 06, 2019
by
Pavel Rojtberg
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
aruco: simplify code by using lambdas
parent
250bcd9f
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
77 additions
and
291 deletions
+77
-291
aruco.cpp
modules/aruco/src/aruco.cpp
+58
-230
charuco.cpp
modules/aruco/src/charuco.cpp
+19
-61
No files found.
modules/aruco/src/aruco.cpp
View file @
b2f08277
...
...
@@ -279,49 +279,6 @@ static void _filterTooCloseCandidates(const vector< vector< Point2f > > &candida
}
}
/**
* ParallelLoopBody class for the parallelization of the basic candidate detections using
* different threhold window sizes. Called from function _detectInitialCandidates()
*/
class
DetectInitialCandidatesParallel
:
public
ParallelLoopBody
{
public
:
DetectInitialCandidatesParallel
(
const
Mat
*
_grey
,
vector
<
vector
<
vector
<
Point2f
>
>
>
*
_candidatesArrays
,
vector
<
vector
<
vector
<
Point
>
>
>
*
_contoursArrays
,
const
Ptr
<
DetectorParameters
>
&
_params
)
:
grey
(
_grey
),
candidatesArrays
(
_candidatesArrays
),
contoursArrays
(
_contoursArrays
),
params
(
_params
)
{}
void
operator
()(
const
Range
&
range
)
const
CV_OVERRIDE
{
const
int
begin
=
range
.
start
;
const
int
end
=
range
.
end
;
for
(
int
i
=
begin
;
i
<
end
;
i
++
)
{
int
currScale
=
params
->
adaptiveThreshWinSizeMin
+
i
*
params
->
adaptiveThreshWinSizeStep
;
// threshold
Mat
thresh
;
_threshold
(
*
grey
,
thresh
,
currScale
,
params
->
adaptiveThreshConstant
);
// detect rectangles
_findMarkerContours
(
thresh
,
(
*
candidatesArrays
)[
i
],
(
*
contoursArrays
)[
i
],
params
->
minMarkerPerimeterRate
,
params
->
maxMarkerPerimeterRate
,
params
->
polygonalApproxAccuracyRate
,
params
->
minCornerDistanceRate
,
params
->
minDistanceToBorder
);
}
}
private
:
DetectInitialCandidatesParallel
&
operator
=
(
const
DetectInitialCandidatesParallel
&
);
const
Mat
*
grey
;
vector
<
vector
<
vector
<
Point2f
>
>
>
*
candidatesArrays
;
vector
<
vector
<
vector
<
Point
>
>
>
*
contoursArrays
;
const
Ptr
<
DetectorParameters
>
&
params
;
};
/**
* @brief Initial steps on finding square candidates
*/
...
...
@@ -341,21 +298,23 @@ static void _detectInitialCandidates(const Mat &grey, vector< vector< Point2f >
vector
<
vector
<
vector
<
Point
>
>
>
contoursArrays
((
size_t
)
nScales
);
////for each value in the interval of thresholding window sizes
// for(int i = 0; i < nScales; i++) {
// int currScale = params.adaptiveThreshWinSizeMin + i*params.adaptiveThreshWinSizeStep;
// // treshold
// Mat thresh;
// _threshold(grey, thresh, currScale, params.adaptiveThreshConstant);
// // detect rectangles
// _findMarkerContours(thresh, candidatesArrays[i], contoursArrays[i],
// params.minMarkerPerimeterRate,
// params.maxMarkerPerimeterRate, params.polygonalApproxAccuracyRate,
// params.minCornerDistance, params.minDistanceToBorder);
//}
// this is the parallel call for the previous commented loop (result is equivalent)
parallel_for_
(
Range
(
0
,
nScales
),
DetectInitialCandidatesParallel
(
&
grey
,
&
candidatesArrays
,
&
contoursArrays
,
params
));
parallel_for_
(
Range
(
0
,
nScales
),
[
&
](
const
Range
&
range
)
{
const
int
begin
=
range
.
start
;
const
int
end
=
range
.
end
;
for
(
int
i
=
begin
;
i
<
end
;
i
++
)
{
int
currScale
=
params
->
adaptiveThreshWinSizeMin
+
i
*
params
->
adaptiveThreshWinSizeStep
;
// threshold
Mat
thresh
;
_threshold
(
grey
,
thresh
,
currScale
,
params
->
adaptiveThreshConstant
);
// detect rectangles
_findMarkerContours
(
thresh
,
candidatesArrays
[
i
],
contoursArrays
[
i
],
params
->
minMarkerPerimeterRate
,
params
->
maxMarkerPerimeterRate
,
params
->
polygonalApproxAccuracyRate
,
params
->
minCornerDistanceRate
,
params
->
minDistanceToBorder
);
}
});
// join candidates
for
(
int
i
=
0
;
i
<
nScales
;
i
++
)
{
...
...
@@ -545,46 +504,6 @@ static bool _identifyOneCandidate(const Ptr<Dictionary>& dictionary, InputArray
return
true
;
}
/**
* ParallelLoopBody class for the parallelization of the marker identification step
* Called from function _identifyCandidates()
*/
class
IdentifyCandidatesParallel
:
public
ParallelLoopBody
{
public
:
IdentifyCandidatesParallel
(
const
Mat
&
_grey
,
vector
<
vector
<
Point2f
>
>&
_candidates
,
const
Ptr
<
Dictionary
>
&
_dictionary
,
vector
<
int
>&
_idsTmp
,
vector
<
char
>&
_validCandidates
,
const
Ptr
<
DetectorParameters
>
&
_params
)
:
grey
(
_grey
),
candidates
(
_candidates
),
dictionary
(
_dictionary
),
idsTmp
(
_idsTmp
),
validCandidates
(
_validCandidates
),
params
(
_params
)
{}
void
operator
()(
const
Range
&
range
)
const
CV_OVERRIDE
{
const
int
begin
=
range
.
start
;
const
int
end
=
range
.
end
;
for
(
int
i
=
begin
;
i
<
end
;
i
++
)
{
int
currId
;
if
(
_identifyOneCandidate
(
dictionary
,
grey
,
candidates
[
i
],
currId
,
params
))
{
validCandidates
[
i
]
=
1
;
idsTmp
[
i
]
=
currId
;
}
}
}
private
:
IdentifyCandidatesParallel
&
operator
=
(
const
IdentifyCandidatesParallel
&
);
// to quiet MSVC
const
Mat
&
grey
;
vector
<
vector
<
Point2f
>
>&
candidates
;
const
Ptr
<
Dictionary
>
&
dictionary
;
vector
<
int
>
&
idsTmp
;
vector
<
char
>
&
validCandidates
;
const
Ptr
<
DetectorParameters
>
&
params
;
};
/**
* @brief Copy the contents of a corners vector to an OutputArray, settings its size.
*/
...
...
@@ -645,19 +564,18 @@ static void _identifyCandidates(InputArray _image, vector< vector< Point2f > >&
vector
<
char
>
validCandidates
(
ncandidates
,
0
);
//// 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
),
IdentifyCandidatesParallel
(
grey
,
_candidates
,
_dictionary
,
idsTmp
,
validCandidates
,
params
));
parallel_for_
(
Range
(
0
,
ncandidates
),
[
&
](
const
Range
&
range
)
{
const
int
begin
=
range
.
start
;
const
int
end
=
range
.
end
;
for
(
int
i
=
begin
;
i
<
end
;
i
++
)
{
int
currId
;
if
(
_identifyOneCandidate
(
_dictionary
,
grey
,
_candidates
[
i
],
currId
,
params
))
{
validCandidates
[
i
]
=
1
;
idsTmp
[
i
]
=
currId
;
}
}
});
for
(
int
i
=
0
;
i
<
ncandidates
;
i
++
)
{
if
(
validCandidates
[
i
]
==
1
)
{
...
...
@@ -772,40 +690,6 @@ static void _getSingleMarkerObjectPoints(float markerLength, OutputArray _objPoi
objPoints
.
ptr
<
Vec3f
>
(
0
)[
3
]
=
Vec3f
(
-
markerLength
/
2.
f
,
-
markerLength
/
2.
f
,
0
);
}
/**
* ParallelLoopBody class for the parallelization of the marker corner subpixel refinement
* Called from function detectMarkers()
*/
class
MarkerSubpixelParallel
:
public
ParallelLoopBody
{
public
:
MarkerSubpixelParallel
(
const
Mat
*
_grey
,
OutputArrayOfArrays
_corners
,
const
Ptr
<
DetectorParameters
>
&
_params
)
:
grey
(
_grey
),
corners
(
_corners
),
params
(
_params
)
{}
void
operator
()(
const
Range
&
range
)
const
CV_OVERRIDE
{
const
int
begin
=
range
.
start
;
const
int
end
=
range
.
end
;
for
(
int
i
=
begin
;
i
<
end
;
i
++
)
{
cornerSubPix
(
*
grey
,
corners
.
getMat
(
i
),
Size
(
params
->
cornerRefinementWinSize
,
params
->
cornerRefinementWinSize
),
Size
(
-
1
,
-
1
),
TermCriteria
(
TermCriteria
::
MAX_ITER
|
TermCriteria
::
EPS
,
params
->
cornerRefinementMaxIterations
,
params
->
cornerRefinementMinAccuracy
));
}
}
private
:
MarkerSubpixelParallel
&
operator
=
(
const
MarkerSubpixelParallel
&
);
// to quiet MSVC
const
Mat
*
grey
;
OutputArrayOfArrays
corners
;
const
Ptr
<
DetectorParameters
>
&
params
;
};
/**
* Line fitting A * B = C :: Called from function refineCandidateLines
* @param nContours, contour-container
...
...
@@ -948,34 +832,6 @@ static void _refineCandidateLines(std::vector<Point>& nContours, std::vector<Poi
}
}
/**
* ParallelLoopBody class for the parallelization of the marker corner contour refinement
* Called from function detectMarkers()
*/
class
MarkerContourParallel
:
public
ParallelLoopBody
{
public
:
MarkerContourParallel
(
vector
<
vector
<
Point
>
>&
_contours
,
vector
<
vector
<
Point2f
>
>&
_candidates
,
const
Mat
&
_camMatrix
,
const
Mat
&
_distCoeff
)
:
contours
(
_contours
),
candidates
(
_candidates
),
camMatrix
(
_camMatrix
),
distCoeff
(
_distCoeff
){}
void
operator
()(
const
Range
&
range
)
const
CV_OVERRIDE
{
for
(
int
i
=
range
.
start
;
i
<
range
.
end
;
i
++
)
{
_refineCandidateLines
(
contours
[
i
],
candidates
[
i
],
camMatrix
,
distCoeff
);
}
}
private
:
MarkerContourParallel
&
operator
=
(
const
MarkerContourParallel
&
){
return
*
this
;
}
vector
<
vector
<
Point
>
>&
contours
;
vector
<
vector
<
Point2f
>
>&
candidates
;
const
Mat
&
camMatrix
;
const
Mat
&
distCoeff
;
};
#ifdef APRIL_DEBUG
static
void
_darken
(
const
Mat
&
im
){
for
(
int
y
=
0
;
y
<
im
.
rows
;
y
++
)
{
...
...
@@ -1152,17 +1008,19 @@ void detectMarkers(InputArray _image, const Ptr<Dictionary> &_dictionary, Output
_params
->
cornerRefinementMinAccuracy
>
0
);
//// do corner refinement for each of the detected markers
// for (unsigned int i = 0; i < _corners.cols(); i++) {
// cornerSubPix(grey, _corners.getMat(i),
// Size(params.cornerRefinementWinSize, params.cornerRefinementWinSize),
// Size(-1, -1), TermCriteria(TermCriteria::MAX_ITER | TermCriteria::EPS,
// params.cornerRefinementMaxIterations,
// params.cornerRefinementMinAccuracy));
//}
// this is the parallel call for the previous commented loop (result is equivalent)
parallel_for_
(
Range
(
0
,
_corners
.
cols
()),
MarkerSubpixelParallel
(
&
grey
,
_corners
,
_params
));
parallel_for_
(
Range
(
0
,
_corners
.
cols
()),
[
&
](
const
Range
&
range
)
{
const
int
begin
=
range
.
start
;
const
int
end
=
range
.
end
;
for
(
int
i
=
begin
;
i
<
end
;
i
++
)
{
cornerSubPix
(
grey
,
_corners
.
getMat
(
i
),
Size
(
_params
->
cornerRefinementWinSize
,
_params
->
cornerRefinementWinSize
),
Size
(
-
1
,
-
1
),
TermCriteria
(
TermCriteria
::
MAX_ITER
|
TermCriteria
::
EPS
,
_params
->
cornerRefinementMaxIterations
,
_params
->
cornerRefinementMinAccuracy
));
}
});
}
/// STEP 4, Optional : Corner refinement :: use contour container
...
...
@@ -1171,7 +1029,12 @@ void detectMarkers(InputArray _image, const Ptr<Dictionary> &_dictionary, Output
if
(
!
_ids
.
empty
()){
// do corner refinement using the contours for each detected markers
parallel_for_
(
Range
(
0
,
_corners
.
cols
()),
MarkerContourParallel
(
contours
,
candidates
,
camMatrix
.
getMat
(),
distCoeff
.
getMat
()));
parallel_for_
(
Range
(
0
,
_corners
.
cols
()),
[
&
](
const
Range
&
range
)
{
for
(
int
i
=
range
.
start
;
i
<
range
.
end
;
i
++
)
{
_refineCandidateLines
(
contours
[
i
],
candidates
[
i
],
camMatrix
.
getMat
(),
distCoeff
.
getMat
());
}
});
// copy the corners to the output array
_copyVector2Output
(
candidates
,
_corners
);
...
...
@@ -1179,42 +1042,6 @@ void detectMarkers(InputArray _image, const Ptr<Dictionary> &_dictionary, Output
}
}
/**
* ParallelLoopBody class for the parallelization of the single markers pose estimation
* Called from function estimatePoseSingleMarkers()
*/
class
SinglePoseEstimationParallel
:
public
ParallelLoopBody
{
public
:
SinglePoseEstimationParallel
(
Mat
&
_markerObjPoints
,
InputArrayOfArrays
_corners
,
InputArray
_cameraMatrix
,
InputArray
_distCoeffs
,
Mat
&
_rvecs
,
Mat
&
_tvecs
)
:
markerObjPoints
(
_markerObjPoints
),
corners
(
_corners
),
cameraMatrix
(
_cameraMatrix
),
distCoeffs
(
_distCoeffs
),
rvecs
(
_rvecs
),
tvecs
(
_tvecs
)
{}
void
operator
()(
const
Range
&
range
)
const
CV_OVERRIDE
{
const
int
begin
=
range
.
start
;
const
int
end
=
range
.
end
;
for
(
int
i
=
begin
;
i
<
end
;
i
++
)
{
solvePnP
(
markerObjPoints
,
corners
.
getMat
(
i
),
cameraMatrix
,
distCoeffs
,
rvecs
.
at
<
Vec3d
>
(
i
),
tvecs
.
at
<
Vec3d
>
(
i
));
}
}
private
:
SinglePoseEstimationParallel
&
operator
=
(
const
SinglePoseEstimationParallel
&
);
// to quiet MSVC
Mat
&
markerObjPoints
;
InputArrayOfArrays
corners
;
InputArray
cameraMatrix
,
distCoeffs
;
Mat
&
rvecs
,
tvecs
;
};
/**
*/
void
estimatePoseSingleMarkers
(
InputArrayOfArrays
_corners
,
float
markerLength
,
...
...
@@ -1232,15 +1059,16 @@ void estimatePoseSingleMarkers(InputArrayOfArrays _corners, float markerLength,
Mat
rvecs
=
_rvecs
.
getMat
(),
tvecs
=
_tvecs
.
getMat
();
//// for each marker, calculate its pose
// for (int i = 0; i < nMarkers; i++) {
// solvePnP(markerObjPoints, _corners.getMat(i), _cameraMatrix, _distCoeffs,
// _rvecs.getMat(i), _tvecs.getMat(i));
//}
// this is the parallel call for the previous commented loop (result is equivalent)
parallel_for_
(
Range
(
0
,
nMarkers
),
SinglePoseEstimationParallel
(
markerObjPoints
,
_corners
,
_cameraMatrix
,
_distCoeffs
,
rvecs
,
tvecs
));
parallel_for_
(
Range
(
0
,
nMarkers
),
[
&
](
const
Range
&
range
)
{
const
int
begin
=
range
.
start
;
const
int
end
=
range
.
end
;
for
(
int
i
=
begin
;
i
<
end
;
i
++
)
{
solvePnP
(
markerObjPoints
,
_corners
.
getMat
(
i
),
_cameraMatrix
,
_distCoeffs
,
rvecs
.
at
<
Vec3d
>
(
i
),
tvecs
.
at
<
Vec3d
>
(
i
));
}
});
if
(
_objPoints
.
needed
()){
markerObjPoints
.
convertTo
(
_objPoints
,
-
1
);
}
...
...
modules/aruco/src/charuco.cpp
View file @
b2f08277
...
...
@@ -270,50 +270,6 @@ static int _filterCornersWithoutMinMarkers(const Ptr<CharucoBoard> &_board,
return
(
int
)
_filteredCharucoIds
.
total
();
}
/**
* ParallelLoopBody class for the parallelization of the charuco corners subpixel refinement
* Called from function _selectAndRefineChessboardCorners()
*/
class
CharucoSubpixelParallel
:
public
ParallelLoopBody
{
public
:
CharucoSubpixelParallel
(
const
Mat
*
_grey
,
vector
<
Point2f
>
*
_filteredChessboardImgPoints
,
vector
<
Size
>
*
_filteredWinSizes
,
const
Ptr
<
DetectorParameters
>
&
_params
)
:
grey
(
_grey
),
filteredChessboardImgPoints
(
_filteredChessboardImgPoints
),
filteredWinSizes
(
_filteredWinSizes
),
params
(
_params
)
{}
void
operator
()(
const
Range
&
range
)
const
CV_OVERRIDE
{
const
int
begin
=
range
.
start
;
const
int
end
=
range
.
end
;
for
(
int
i
=
begin
;
i
<
end
;
i
++
)
{
vector
<
Point2f
>
in
;
in
.
push_back
((
*
filteredChessboardImgPoints
)[
i
]);
Size
winSize
=
(
*
filteredWinSizes
)[
i
];
if
(
winSize
.
height
==
-
1
||
winSize
.
width
==
-
1
)
winSize
=
Size
(
params
->
cornerRefinementWinSize
,
params
->
cornerRefinementWinSize
);
cornerSubPix
(
*
grey
,
in
,
winSize
,
Size
(),
TermCriteria
(
TermCriteria
::
MAX_ITER
|
TermCriteria
::
EPS
,
params
->
cornerRefinementMaxIterations
,
params
->
cornerRefinementMinAccuracy
));
(
*
filteredChessboardImgPoints
)[
i
]
=
in
[
0
];
}
}
private
:
CharucoSubpixelParallel
&
operator
=
(
const
CharucoSubpixelParallel
&
);
// to quiet MSVC
const
Mat
*
grey
;
vector
<
Point2f
>
*
filteredChessboardImgPoints
;
vector
<
Size
>
*
filteredWinSizes
;
const
Ptr
<
DetectorParameters
>
&
params
;
};
/**
* @brief From all projected chessboard corners, select those inside the image and apply subpixel
* refinement. Returns number of valid corners.
...
...
@@ -353,23 +309,25 @@ static int _selectAndRefineChessboardCorners(InputArray _allCorners, InputArray
const
Ptr
<
DetectorParameters
>
params
=
DetectorParameters
::
create
();
// use default params for corner refinement
//// For each of the charuco corners, apply subpixel refinement using its correspondind winSize
// for(unsigned int i=0; i<filteredChessboardImgPoints.size(); i++) {
// vector<Point2f> in;
// in.push_back(filteredChessboardImgPoints[i]);
// Size winSize = filteredWinSizes[i];
// if(winSize.height == -1 || winSize.width == -1)
// winSize = Size(params.cornerRefinementWinSize, params.cornerRefinementWinSize);
// cornerSubPix(grey, in, winSize, Size(),
// TermCriteria(TermCriteria::MAX_ITER | TermCriteria::EPS,
// params->cornerRefinementMaxIterations,
// params->cornerRefinementMinAccuracy));
// filteredChessboardImgPoints[i] = in[0];
//}
// this is the parallel call for the previous commented loop (result is equivalent)
parallel_for_
(
Range
(
0
,
(
int
)
filteredChessboardImgPoints
.
size
()),
CharucoSubpixelParallel
(
&
grey
,
&
filteredChessboardImgPoints
,
&
filteredWinSizes
,
params
));
parallel_for_
(
Range
(
0
,
(
int
)
filteredChessboardImgPoints
.
size
()),
[
&
](
const
Range
&
range
)
{
const
int
begin
=
range
.
start
;
const
int
end
=
range
.
end
;
for
(
int
i
=
begin
;
i
<
end
;
i
++
)
{
vector
<
Point2f
>
in
;
in
.
push_back
(
filteredChessboardImgPoints
[
i
]);
Size
winSize
=
filteredWinSizes
[
i
];
if
(
winSize
.
height
==
-
1
||
winSize
.
width
==
-
1
)
winSize
=
Size
(
params
->
cornerRefinementWinSize
,
params
->
cornerRefinementWinSize
);
cornerSubPix
(
grey
,
in
,
winSize
,
Size
(),
TermCriteria
(
TermCriteria
::
MAX_ITER
|
TermCriteria
::
EPS
,
params
->
cornerRefinementMaxIterations
,
params
->
cornerRefinementMinAccuracy
));
filteredChessboardImgPoints
[
i
]
=
in
[
0
];
}
});
// parse output
Mat
(
filteredChessboardImgPoints
).
copyTo
(
_selectedCorners
);
...
...
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