Commit b2f08277 authored by Pavel Rojtberg's avatar Pavel Rojtberg

aruco: simplify code by using lambdas

parent 250bcd9f
...@@ -279,49 +279,6 @@ static void _filterTooCloseCandidates(const vector< vector< Point2f > > &candida ...@@ -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 * @brief Initial steps on finding square candidates
*/ */
...@@ -341,21 +298,23 @@ static void _detectInitialCandidates(const Mat &grey, vector< vector< Point2f > ...@@ -341,21 +298,23 @@ static void _detectInitialCandidates(const Mat &grey, vector< vector< Point2f >
vector< vector< vector< Point > > > contoursArrays((size_t) nScales); vector< vector< vector< Point > > > contoursArrays((size_t) nScales);
////for each value in the interval of thresholding window sizes ////for each value in the interval of thresholding window sizes
// for(int i = 0; i < nScales; i++) { parallel_for_(Range(0, nScales), [&](const Range& range) {
// int currScale = params.adaptiveThreshWinSizeMin + i*params.adaptiveThreshWinSizeStep; const int begin = range.start;
// // treshold const int end = range.end;
// Mat thresh;
// _threshold(grey, thresh, currScale, params.adaptiveThreshConstant); for (int i = begin; i < end; i++) {
// // detect rectangles int currScale = params->adaptiveThreshWinSizeMin + i * params->adaptiveThreshWinSizeStep;
// _findMarkerContours(thresh, candidatesArrays[i], contoursArrays[i], // threshold
// params.minMarkerPerimeterRate, Mat thresh;
// params.maxMarkerPerimeterRate, params.polygonalApproxAccuracyRate, _threshold(grey, thresh, currScale, params->adaptiveThreshConstant);
// params.minCornerDistance, params.minDistanceToBorder);
//} // detect rectangles
_findMarkerContours(thresh, candidatesArrays[i], contoursArrays[i],
// this is the parallel call for the previous commented loop (result is equivalent) params->minMarkerPerimeterRate, params->maxMarkerPerimeterRate,
parallel_for_(Range(0, nScales), DetectInitialCandidatesParallel(&grey, &candidatesArrays, params->polygonalApproxAccuracyRate, params->minCornerDistanceRate,
&contoursArrays, params)); params->minDistanceToBorder);
}
});
// join candidates // join candidates
for(int i = 0; i < nScales; i++) { for(int i = 0; i < nScales; i++) {
...@@ -545,46 +504,6 @@ static bool _identifyOneCandidate(const Ptr<Dictionary>& dictionary, InputArray ...@@ -545,46 +504,6 @@ static bool _identifyOneCandidate(const Ptr<Dictionary>& dictionary, InputArray
return true; 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. * @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 > >& ...@@ -645,19 +564,18 @@ static void _identifyCandidates(InputArray _image, vector< vector< Point2f > >&
vector< char > validCandidates(ncandidates, 0); vector< char > validCandidates(ncandidates, 0);
//// Analyze each of the candidates //// Analyze each of the candidates
// for (int i = 0; i < ncandidates; i++) { parallel_for_(Range(0, ncandidates), [&](const Range &range) {
// int currId = i; const int begin = range.start;
// Mat currentCandidate = _candidates.getMat(i); const int end = range.end;
// if (_identifyOneCandidate(dictionary, grey, currentCandidate, currId, params)) {
// validCandidates[i] = 1; for(int i = begin; i < end; i++) {
// idsTmp[i] = currId; int currId;
// } if(_identifyOneCandidate(_dictionary, grey, _candidates[i], 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));
for(int i = 0; i < ncandidates; i++) { for(int i = 0; i < ncandidates; i++) {
if(validCandidates[i] == 1) { if(validCandidates[i] == 1) {
...@@ -772,40 +690,6 @@ static void _getSingleMarkerObjectPoints(float markerLength, OutputArray _objPoi ...@@ -772,40 +690,6 @@ static void _getSingleMarkerObjectPoints(float markerLength, OutputArray _objPoi
objPoints.ptr< Vec3f >(0)[3] = Vec3f(-markerLength / 2.f, -markerLength / 2.f, 0); 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 * Line fitting A * B = C :: Called from function refineCandidateLines
* @param nContours, contour-container * @param nContours, contour-container
...@@ -948,34 +832,6 @@ static void _refineCandidateLines(std::vector<Point>& nContours, std::vector<Poi ...@@ -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 #ifdef APRIL_DEBUG
static void _darken(const Mat &im){ static void _darken(const Mat &im){
for (int y = 0; y < im.rows; y++) { for (int y = 0; y < im.rows; y++) {
...@@ -1152,17 +1008,19 @@ void detectMarkers(InputArray _image, const Ptr<Dictionary> &_dictionary, Output ...@@ -1152,17 +1008,19 @@ void detectMarkers(InputArray _image, const Ptr<Dictionary> &_dictionary, Output
_params->cornerRefinementMinAccuracy > 0); _params->cornerRefinementMinAccuracy > 0);
//// do corner refinement for each of the detected markers //// do corner refinement for each of the detected markers
// for (unsigned int i = 0; i < _corners.cols(); i++) { parallel_for_(Range(0, _corners.cols()), [&](const Range& range) {
// cornerSubPix(grey, _corners.getMat(i), const int begin = range.start;
// Size(params.cornerRefinementWinSize, params.cornerRefinementWinSize), const int end = range.end;
// Size(-1, -1), TermCriteria(TermCriteria::MAX_ITER | TermCriteria::EPS,
// params.cornerRefinementMaxIterations, for (int i = begin; i < end; i++) {
// params.cornerRefinementMinAccuracy)); cornerSubPix(grey, _corners.getMat(i),
//} Size(_params->cornerRefinementWinSize, _params->cornerRefinementWinSize),
Size(-1, -1),
// this is the parallel call for the previous commented loop (result is equivalent) TermCriteria(TermCriteria::MAX_ITER | TermCriteria::EPS,
parallel_for_(Range(0, _corners.cols()), _params->cornerRefinementMaxIterations,
MarkerSubpixelParallel(&grey, _corners, _params)); _params->cornerRefinementMinAccuracy));
}
});
} }
/// STEP 4, Optional : Corner refinement :: use contour container /// STEP 4, Optional : Corner refinement :: use contour container
...@@ -1171,7 +1029,12 @@ void detectMarkers(InputArray _image, const Ptr<Dictionary> &_dictionary, Output ...@@ -1171,7 +1029,12 @@ void detectMarkers(InputArray _image, const Ptr<Dictionary> &_dictionary, Output
if(! _ids.empty()){ if(! _ids.empty()){
// do corner refinement using the contours for each detected markers // 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 // copy the corners to the output array
_copyVector2Output(candidates, _corners); _copyVector2Output(candidates, _corners);
...@@ -1179,42 +1042,6 @@ void detectMarkers(InputArray _image, const Ptr<Dictionary> &_dictionary, Output ...@@ -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, void estimatePoseSingleMarkers(InputArrayOfArrays _corners, float markerLength,
...@@ -1232,15 +1059,16 @@ void estimatePoseSingleMarkers(InputArrayOfArrays _corners, float markerLength, ...@@ -1232,15 +1059,16 @@ void estimatePoseSingleMarkers(InputArrayOfArrays _corners, float markerLength,
Mat rvecs = _rvecs.getMat(), tvecs = _tvecs.getMat(); Mat rvecs = _rvecs.getMat(), tvecs = _tvecs.getMat();
//// for each marker, calculate its pose //// for each marker, calculate its pose
// for (int i = 0; i < nMarkers; i++) { parallel_for_(Range(0, nMarkers), [&](const Range& range) {
// solvePnP(markerObjPoints, _corners.getMat(i), _cameraMatrix, _distCoeffs, const int begin = range.start;
// _rvecs.getMat(i), _tvecs.getMat(i)); const int end = range.end;
//}
for (int i = begin; i < end; i++) {
// this is the parallel call for the previous commented loop (result is equivalent) solvePnP(markerObjPoints, _corners.getMat(i), _cameraMatrix, _distCoeffs, rvecs.at<Vec3d>(i),
parallel_for_(Range(0, nMarkers), tvecs.at<Vec3d>(i));
SinglePoseEstimationParallel(markerObjPoints, _corners, _cameraMatrix, }
_distCoeffs, rvecs, tvecs)); });
if(_objPoints.needed()){ if(_objPoints.needed()){
markerObjPoints.convertTo(_objPoints, -1); markerObjPoints.convertTo(_objPoints, -1);
} }
......
...@@ -270,50 +270,6 @@ static int _filterCornersWithoutMinMarkers(const Ptr<CharucoBoard> &_board, ...@@ -270,50 +270,6 @@ static int _filterCornersWithoutMinMarkers(const Ptr<CharucoBoard> &_board,
return (int)_filteredCharucoIds.total(); 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 * @brief From all projected chessboard corners, select those inside the image and apply subpixel
* refinement. Returns number of valid corners. * refinement. Returns number of valid corners.
...@@ -353,23 +309,25 @@ static int _selectAndRefineChessboardCorners(InputArray _allCorners, InputArray ...@@ -353,23 +309,25 @@ static int _selectAndRefineChessboardCorners(InputArray _allCorners, InputArray
const Ptr<DetectorParameters> params = DetectorParameters::create(); // use default params for corner refinement 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 each of the charuco corners, apply subpixel refinement using its correspondind winSize
// for(unsigned int i=0; i<filteredChessboardImgPoints.size(); i++) { parallel_for_(Range(0, (int)filteredChessboardImgPoints.size()), [&](const Range& range) {
// vector<Point2f> in; const int begin = range.start;
// in.push_back(filteredChessboardImgPoints[i]); const int end = range.end;
// Size winSize = filteredWinSizes[i];
// if(winSize.height == -1 || winSize.width == -1) for (int i = begin; i < end; i++) {
// winSize = Size(params.cornerRefinementWinSize, params.cornerRefinementWinSize); vector<Point2f> in;
// cornerSubPix(grey, in, winSize, Size(), in.push_back(filteredChessboardImgPoints[i]);
// TermCriteria(TermCriteria::MAX_ITER | TermCriteria::EPS, Size winSize = filteredWinSizes[i];
// params->cornerRefinementMaxIterations, if (winSize.height == -1 || winSize.width == -1)
// params->cornerRefinementMinAccuracy)); winSize = Size(params->cornerRefinementWinSize, params->cornerRefinementWinSize);
// filteredChessboardImgPoints[i] = in[0];
//} cornerSubPix(grey, in, winSize, Size(),
TermCriteria(TermCriteria::MAX_ITER | TermCriteria::EPS,
// this is the parallel call for the previous commented loop (result is equivalent) params->cornerRefinementMaxIterations,
parallel_for_( params->cornerRefinementMinAccuracy));
Range(0, (int)filteredChessboardImgPoints.size()),
CharucoSubpixelParallel(&grey, &filteredChessboardImgPoints, &filteredWinSizes, params)); filteredChessboardImgPoints[i] = in[0];
}
});
// parse output // parse output
Mat(filteredChessboardImgPoints).copyTo(_selectedCorners); Mat(filteredChessboardImgPoints).copyTo(_selectedCorners);
......
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