@@ -210,6 +210,22 @@ static void _reorderCandidatesCorners(vector< vector< Point2f > > &candidates) {
210
210
}
211
211
}
212
212
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
+ }
213
229
214
230
/* *
215
231
* @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
315
331
biggerContours.push_back (contoursIn[biggerIdx]);
316
332
317
333
if ( detectInvertedMarker ){
318
- smallerCandidates.push_back (candidatesIn[smallerIdx]);
334
+ smallerCandidates.push_back (alignContourOrder ( candidatesIn[biggerIdx][ 0 ], candidatesIn[ smallerIdx]) );
319
335
smallerContours.push_back (contoursIn[smallerIdx]);
320
336
}
321
337
}
@@ -509,7 +525,7 @@ static int _getBorderErrors(const Mat &bits, int markerSize, int borderSize) {
509
525
*/
510
526
static uint8_t _identifyOneCandidate (const Ptr<Dictionary>& dictionary, InputArray _image,
511
527
vector<Point2f>& _corners, int & idx,
512
- const Ptr<DetectorParameters>& params)
528
+ const Ptr<DetectorParameters>& params, int & rotation )
513
529
{
514
530
CV_Assert (_corners.size () == 4 );
515
531
CV_Assert (_image.getMat ().total () != 0 );
@@ -549,14 +565,9 @@ static uint8_t _identifyOneCandidate(const Ptr<Dictionary>& dictionary, InputArr
549
565
.colRange (params->markerBorderBits , candidateBits.rows - params->markerBorderBits );
550
566
551
567
// try to indentify the marker
552
- int rotation;
553
568
if (!dictionary->identify (onlyBits, idx, rotation, params->errorCorrectionRate ))
554
569
return 0 ;
555
570
556
- // shift corner positions to the correct rotation
557
- if (rotation != 0 ) {
558
- std::rotate (_corners.begin (), _corners.begin () + 4 - rotation, _corners.end ());
559
- }
560
571
return typ;
561
572
}
562
573
@@ -593,7 +604,12 @@ static void _copyVector2Output(vector< vector< Point2f > > &vec, OutputArrayOfAr
593
604
}
594
605
}
595
606
596
-
607
+ /* *
608
+ * @brief rotate the initial corner to get to the right position
609
+ */
610
+ static void correctCornerPosition ( vector< Point2f >& _candidate, int rotate){
611
+ std::rotate (_candidate.begin (), _candidate.begin () + 4 - rotate, _candidate.end ());
612
+ }
597
613
598
614
/* *
599
615
* @brief Identify square candidates according to a marker dictionary
@@ -616,6 +632,7 @@ static void _identifyCandidates(InputArray _image, vector< vector< vector< Point
616
632
_convertToGrey (_image.getMat (), grey);
617
633
618
634
vector< int > idsTmp (ncandidates, -1 );
635
+ vector< int > rotated (ncandidates, 0 );
619
636
vector< uint8_t > validCandidates (ncandidates, 0 );
620
637
621
638
// // Analyze each of the candidates
@@ -627,7 +644,7 @@ static void _identifyCandidates(InputArray _image, vector< vector< vector< Point
627
644
628
645
for (int i = begin; i < end; i++) {
629
646
int currId;
630
- validCandidates[i] = _identifyOneCandidate (_dictionary, grey, candidates[i], currId, params);
647
+ validCandidates[i] = _identifyOneCandidate (_dictionary, grey, candidates[i], currId, params, rotated[i] );
631
648
632
649
if (validCandidates[i] > 0 )
633
650
idsTmp[i] = currId;
@@ -636,19 +653,20 @@ static void _identifyCandidates(InputArray _image, vector< vector< vector< Point
636
653
637
654
for (int i = 0 ; i < ncandidates; i++) {
638
655
if (validCandidates[i] > 0 ) {
639
- // add the white valid candidate
640
- if ( params->detectInvertedMarker && validCandidates[i] == 2 ){
641
- accepted.push_back (_candidatesSet[1 ][i]);
642
- ids.push_back (idsTmp[i]);
656
+ // to choose the right set of candidates :: 0 for default, 1 for white markers
657
+ uint8_t set = validCandidates[i]-1 ;
643
658
644
- contours.push_back (_contoursSet[1 ][i]);
659
+ // shift corner positions to the correct rotation
660
+ correctCornerPosition (_candidatesSet[set][i], rotated[i]);
661
+
662
+ if ( !params->detectInvertedMarker && validCandidates[i] == 2 )
645
663
continue ;
646
- }
647
- // add the default (black) valid candidate
648
- accepted.push_back (_candidatesSet[0 ][i]);
664
+
665
+ // add valid candidate
666
+ accepted.push_back (_candidatesSet[set ][i]);
649
667
ids.push_back (idsTmp[i]);
650
668
651
- contours.push_back (_contoursSet[0 ][i]);
669
+ contours.push_back (_contoursSet[set ][i]);
652
670
653
671
} else {
654
672
rejected.push_back (_candidatesSet[0 ][i]);
0 commit comments