remove camParams and add cornerIndex check

pull/3186/head
Aleksandr Panov 3 years ago
parent ed0094c7b3
commit ef980e7b4e
  1. 10
      modules/aruco/include/opencv2/aruco.hpp
  2. 43
      modules/aruco/src/aruco.cpp

@ -206,21 +206,19 @@ struct CV_EXPORTS_W DetectorParameters {
* @param parameters marker detection parameters * @param parameters marker detection parameters
* @param rejectedImgPoints contains the imgPoints of those squares whose inner code has not a * @param rejectedImgPoints contains the imgPoints of those squares whose inner code has not a
* correct codification. Useful for debugging purposes. * correct codification. Useful for debugging purposes.
* @param cameraMatrix optional input 3x3 floating-point camera matrix
* \f$A = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$
* @param distCoeff optional vector of distortion coefficients
* \f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6],[s_1, s_2, s_3, s_4]])\f$ of 4, 5, 8 or 12 elements
* *
* Performs marker detection in the input image. Only markers included in the specific dictionary * Performs marker detection in the input image. Only markers included in the specific dictionary
* are searched. For each detected marker, it returns the 2D position of its corner in the image * are searched. For each detected marker, it returns the 2D position of its corner in the image
* and its corresponding identifier. * and its corresponding identifier.
* Note that this function does not perform pose estimation. * Note that this function does not perform pose estimation.
* @sa estimatePoseSingleMarkers, estimatePoseBoard * @note The function does not correct lens distortion or takes it into account. It's recommended to undistort
* input image with corresponging camera model, if camera parameters are known
* @sa undistort, estimatePoseSingleMarkers, estimatePoseBoard
* *
*/ */
CV_EXPORTS_W void detectMarkers(InputArray image, const Ptr<Dictionary> &dictionary, OutputArrayOfArrays corners, CV_EXPORTS_W void detectMarkers(InputArray image, const Ptr<Dictionary> &dictionary, OutputArrayOfArrays corners,
OutputArray ids, const Ptr<DetectorParameters> &parameters = DetectorParameters::create(), OutputArray ids, const Ptr<DetectorParameters> &parameters = DetectorParameters::create(),
OutputArrayOfArrays rejectedImgPoints = noArray(), InputArray cameraMatrix= noArray(), InputArray distCoeff= noArray()); OutputArrayOfArrays rejectedImgPoints = noArray());

@ -857,6 +857,7 @@ class MarkerSubpixelParallel : public ParallelLoopBody {
* @param nContours, contour-container * @param nContours, contour-container
*/ */
static Point3f _interpolate2Dline(const std::vector<cv::Point2f>& nContours){ static Point3f _interpolate2Dline(const std::vector<cv::Point2f>& nContours){
CV_Assert(nContours.size() >= 2);
float minX, minY, maxX, maxY; float minX, minY, maxX, maxY;
minX = maxX = nContours[0].x; minX = maxX = nContours[0].x;
minY = maxY = nContours[0].y; minY = maxY = nContours[0].y;
@ -907,21 +908,6 @@ static Point2f _getCrossPoint(Point3f nLine1, Point3f nLine2){
return Vec2f(A.solve(B).val); return Vec2f(A.solve(B).val);
} }
static void _distortPoints(vector<cv::Point2f>& in, const Mat& camMatrix, const Mat& distCoeff) {
// trivial extrinsics
Matx31f Rvec(0,0,0);
Matx31f Tvec(0,0,0);
// calculate 3d points and then reproject, so opencv makes the distortion internally
vector<cv::Point3f> cornersPoints3d;
for (unsigned int i = 0; i < in.size(); i++){
float x= (in[i].x - float(camMatrix.at<double>(0, 2))) / float(camMatrix.at<double>(0, 0));
float y= (in[i].y - float(camMatrix.at<double>(1, 2))) / float(camMatrix.at<double>(1, 1));
cornersPoints3d.push_back(Point3f(x,y,1));
}
cv::projectPoints(cornersPoints3d, Rvec, Tvec, camMatrix, distCoeff, in);
}
/** /**
* Refine Corners using the contour vector :: Called from function detectMarkers * Refine Corners using the contour vector :: Called from function detectMarkers
* @param nContours, contour-container * @param nContours, contour-container
@ -929,13 +915,8 @@ static void _distortPoints(vector<cv::Point2f>& in, const Mat& camMatrix, const
* @param camMatrix, cameraMatrix input 3x3 floating-point camera matrix * @param camMatrix, cameraMatrix input 3x3 floating-point camera matrix
* @param distCoeff, distCoeffs vector of distortion coefficient * @param distCoeff, distCoeffs vector of distortion coefficient
*/ */
static void _refineCandidateLines(std::vector<Point>& nContours, std::vector<Point2f>& nCorners, const Mat& camMatrix, const Mat& distCoeff){ static void _refineCandidateLines(std::vector<Point>& nContours, std::vector<Point2f>& nCorners){
vector<Point2f> contour2f(nContours.begin(), nContours.end()); vector<Point2f> contour2f(nContours.begin(), nContours.end());
if(!camMatrix.empty() && !distCoeff.empty()){
undistortPoints(contour2f, contour2f, camMatrix, distCoeff);
}
/* 5 groups :: to group the edges /* 5 groups :: to group the edges
* 4 - classified by its corner * 4 - classified by its corner
* extra group - (temporary) if contours do not begin with a corner * extra group - (temporary) if contours do not begin with a corner
@ -953,10 +934,10 @@ static void _refineCandidateLines(std::vector<Point>& nContours, std::vector<Poi
} }
cntPts[group].push_back(contour2f[i]); cntPts[group].push_back(contour2f[i]);
} }
for (int i = 0; i < 4; i++)
CV_Assert(cornerIndex[i] != -1);
// saves extra group into corresponding // saves extra group into corresponding
if( !cntPts[4].empty() ){ if( !cntPts[4].empty() ){
CV_CheckLT(group, 4, "FIXIT: avoiding infinite loop: implementation should be revised: https://github.com/opencv/opencv_contrib/issues/2738");
for( unsigned int i=0; i < cntPts[4].size() ; i++ ) for( unsigned int i=0; i < cntPts[4].size() ; i++ )
cntPts[group].push_back(cntPts[4].at(i)); cntPts[group].push_back(cntPts[4].at(i));
cntPts[4].clear(); cntPts[4].clear();
@ -989,10 +970,6 @@ static void _refineCandidateLines(std::vector<Point>& nContours, std::vector<Poi
else else
nCorners[i] = _getCrossPoint(lines[ i ], lines[ (i+3)%4 ]); // 30 01 12 23 nCorners[i] = _getCrossPoint(lines[ i ], lines[ (i+3)%4 ]); // 30 01 12 23
} }
if(!camMatrix.empty() && !distCoeff.empty()){
_distortPoints(nCorners, camMatrix, distCoeff);
}
} }
@ -1002,13 +979,13 @@ static void _refineCandidateLines(std::vector<Point>& nContours, std::vector<Poi
*/ */
class MarkerContourParallel : public ParallelLoopBody { class MarkerContourParallel : public ParallelLoopBody {
public: public:
MarkerContourParallel( vector< vector< Point > >& _contours, vector< vector< Point2f > >& _candidates, const Mat& _camMatrix, const Mat& _distCoeff) MarkerContourParallel( vector< vector< Point > >& _contours, vector< vector< Point2f > >& _candidates)
: contours(_contours), candidates(_candidates), camMatrix(_camMatrix), distCoeff(_distCoeff){} : contours(_contours), candidates(_candidates){}
void operator()(const Range &range) const CV_OVERRIDE { void operator()(const Range &range) const CV_OVERRIDE {
for(int i = range.start; i < range.end; i++) { for(int i = range.start; i < range.end; i++) {
_refineCandidateLines(contours[i], candidates[i], camMatrix, distCoeff); _refineCandidateLines(contours[i], candidates[i]);
} }
} }
@ -1019,8 +996,6 @@ class MarkerContourParallel : public ParallelLoopBody {
vector< vector< Point > >& contours; vector< vector< Point > >& contours;
vector< vector< Point2f > >& candidates; vector< vector< Point2f > >& candidates;
const Mat& camMatrix;
const Mat& distCoeff;
}; };
#ifdef APRIL_DEBUG #ifdef APRIL_DEBUG
@ -1162,7 +1137,7 @@ static void _apriltag(Mat im_orig, const Ptr<DetectorParameters> & _params, std:
*/ */
void detectMarkers(InputArray _image, const Ptr<Dictionary> &_dictionary, OutputArrayOfArrays _corners, void detectMarkers(InputArray _image, const Ptr<Dictionary> &_dictionary, OutputArrayOfArrays _corners,
OutputArray _ids, const Ptr<DetectorParameters> &_params, OutputArray _ids, const Ptr<DetectorParameters> &_params,
OutputArrayOfArrays _rejectedImgPoints, InputArrayOfArrays camMatrix, InputArrayOfArrays distCoeff) { OutputArrayOfArrays _rejectedImgPoints) {
CV_Assert(!_image.empty()); CV_Assert(!_image.empty());
@ -1221,7 +1196,7 @@ 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()), MarkerContourParallel(contours, candidates));
// copy the corners to the output array // copy the corners to the output array
_copyVector2Output(candidates, _corners); _copyVector2Output(candidates, _corners);

Loading…
Cancel
Save