Skip to content

Commit a89f104

Browse files
committed
Merge pull request #2374 from alalek:backport_contrib_2372
2 parents cde48f4 + 5efd1e2 commit a89f104

File tree

1 file changed

+41
-21
lines changed

1 file changed

+41
-21
lines changed

modules/aruco/src/aruco.cpp

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,22 @@ static void _reorderCandidatesCorners(vector< vector< Point2f > > &candidates) {
210210
}
211211
}
212212

213+
/**
214+
* @brief to make sure that the corner's order of both candidates (default/white) is the same
215+
*/
216+
static vector< Point2f > alignContourOrder( Point2f corner, vector< Point2f > candidate){
217+
uint8_t r=0;
218+
double min = cv::norm( Vec2f( corner - candidate[0] ), NORM_L2SQR);
219+
for(uint8_t pos=1; pos < 4; pos++) {
220+
double nDiff = cv::norm( Vec2f( corner - candidate[pos] ), NORM_L2SQR);
221+
if(nDiff < min){
222+
r = pos;
223+
min =nDiff;
224+
}
225+
}
226+
std::rotate(candidate.begin(), candidate.begin() + r, candidate.end());
227+
return candidate;
228+
}
213229

214230
/**
215231
* @brief Check candidates that are too close to each other, save the potential candidates
@@ -315,7 +331,7 @@ static void _filterTooCloseCandidates(const vector< vector< Point2f > > &candida
315331
biggerContours.push_back(contoursIn[biggerIdx]);
316332

317333
if( detectInvertedMarker ){
318-
smallerCandidates.push_back(candidatesIn[smallerIdx]);
334+
smallerCandidates.push_back(alignContourOrder(candidatesIn[biggerIdx][0], candidatesIn[smallerIdx]));
319335
smallerContours.push_back(contoursIn[smallerIdx]);
320336
}
321337
}
@@ -550,7 +566,7 @@ static int _getBorderErrors(const Mat &bits, int markerSize, int borderSize) {
550566
*/
551567
static uint8_t _identifyOneCandidate(const Ptr<Dictionary>& dictionary, InputArray _image,
552568
vector<Point2f>& _corners, int& idx,
553-
const Ptr<DetectorParameters>& params)
569+
const Ptr<DetectorParameters>& params, int& rotation)
554570
{
555571
CV_Assert(_corners.size() == 4);
556572
CV_Assert(_image.getMat().total() != 0);
@@ -590,14 +606,9 @@ static uint8_t _identifyOneCandidate(const Ptr<Dictionary>& dictionary, InputArr
590606
.colRange(params->markerBorderBits, candidateBits.rows - params->markerBorderBits);
591607

592608
// try to indentify the marker
593-
int rotation;
594609
if(!dictionary->identify(onlyBits, idx, rotation, params->errorCorrectionRate))
595610
return 0;
596611

597-
// shift corner positions to the correct rotation
598-
if(rotation != 0) {
599-
std::rotate(_corners.begin(), _corners.begin() + 4 - rotation, _corners.end());
600-
}
601612
return typ;
602613
}
603614

@@ -611,9 +622,10 @@ class IdentifyCandidatesParallel : public ParallelLoopBody {
611622
IdentifyCandidatesParallel(const Mat& _grey, vector< vector< Point2f > >& _candidates,
612623
const Ptr<Dictionary> &_dictionary,
613624
vector< int >& _idsTmp, vector< uint8_t >& _validCandidates,
614-
const Ptr<DetectorParameters> &_params)
625+
const Ptr<DetectorParameters> &_params,
626+
vector< int > &_rotated)
615627
: grey(_grey), candidates(_candidates), dictionary(_dictionary),
616-
idsTmp(_idsTmp), validCandidates(_validCandidates), params(_params) {}
628+
idsTmp(_idsTmp), validCandidates(_validCandidates), params(_params), rotated(_rotated) {}
617629

618630
void operator()(const Range &range) const CV_OVERRIDE
619631
{
@@ -622,7 +634,7 @@ class IdentifyCandidatesParallel : public ParallelLoopBody {
622634

623635
for(int i = begin; i < end; i++) {
624636
int currId;
625-
validCandidates[i] = _identifyOneCandidate(dictionary, grey, candidates[i], currId, params);
637+
validCandidates[i] = _identifyOneCandidate(dictionary, grey, candidates[i], currId, params, rotated[i]);
626638

627639
if(validCandidates[i] > 0)
628640
idsTmp[i] = currId;
@@ -639,6 +651,7 @@ class IdentifyCandidatesParallel : public ParallelLoopBody {
639651
vector< int > &idsTmp;
640652
vector< uint8_t > &validCandidates;
641653
const Ptr<DetectorParameters> &params;
654+
vector< int > &rotated;
642655
};
643656

644657

@@ -676,7 +689,12 @@ static void _copyVector2Output(vector< vector< Point2f > > &vec, OutputArrayOfAr
676689
}
677690
}
678691

679-
692+
/**
693+
* @brief rotate the initial corner to get to the right position
694+
*/
695+
static void correctCornerPosition( vector< Point2f >& _candidate, int rotate){
696+
std::rotate(_candidate.begin(), _candidate.begin() + 4 - rotate, _candidate.end());
697+
}
680698

681699
/**
682700
* @brief Identify square candidates according to a marker dictionary
@@ -699,30 +717,32 @@ static void _identifyCandidates(InputArray _image, vector< vector< vector< Point
699717
_convertToGrey(_image.getMat(), grey);
700718

701719
vector< int > idsTmp(ncandidates, -1);
720+
vector< int > rotated(ncandidates, 0);
702721
vector< uint8_t > validCandidates(ncandidates, 0);
703722

704723
//// Analyze each of the candidates
705724
parallel_for_(Range(0, ncandidates),
706725
IdentifyCandidatesParallel(grey,
707726
params->detectInvertedMarker ? _candidatesSet[1] : _candidatesSet[0],
708727
_dictionary, idsTmp,
709-
validCandidates, params));
728+
validCandidates, params, rotated));
710729

711730
for(int i = 0; i < ncandidates; i++) {
712731
if(validCandidates[i] > 0) {
713-
// add the white valid candidate
714-
if( params->detectInvertedMarker && validCandidates[i] == 2 ){
715-
accepted.push_back(_candidatesSet[1][i]);
716-
ids.push_back(idsTmp[i]);
732+
// to choose the right set of candidates :: 0 for default, 1 for white markers
733+
uint8_t set = validCandidates[i]-1;
717734

718-
contours.push_back(_contoursSet[1][i]);
735+
// shift corner positions to the correct rotation
736+
correctCornerPosition(_candidatesSet[set][i], rotated[i]);
737+
738+
if( !params->detectInvertedMarker && validCandidates[i] == 2 )
719739
continue;
720-
}
721-
// add the default (black) valid candidate
722-
accepted.push_back(_candidatesSet[0][i]);
740+
741+
// add valid candidate
742+
accepted.push_back(_candidatesSet[set][i]);
723743
ids.push_back(idsTmp[i]);
724744

725-
contours.push_back(_contoursSet[0][i]);
745+
contours.push_back(_contoursSet[set][i]);
726746

727747
} else {
728748
rejected.push_back(_candidatesSet[0][i]);

0 commit comments

Comments
 (0)