@@ -35,6 +35,8 @@ static inline bool readWrite(DetectorParameters ¶ms, const FileNode* readNod
3535 check |=readWriteParameter (" minMarkerDistanceRate" , params.minMarkerDistanceRate , readNode, writeStorage);
3636 check |=readWriteParameter (" cornerRefinementMethod" , params.cornerRefinementMethod , readNode, writeStorage);
3737 check |=readWriteParameter (" cornerRefinementWinSize" , params.cornerRefinementWinSize , readNode, writeStorage);
38+ check |=readWriteParameter (" relativeCornerRefinmentWinSize" , params.relativeCornerRefinmentWinSize , readNode,
39+ writeStorage);
3840 check |=readWriteParameter (" cornerRefinementMaxIterations" , params.cornerRefinementMaxIterations ,
3941 readNode, writeStorage);
4042 check |=readWriteParameter (" cornerRefinementMinAccuracy" , params.cornerRefinementMinAccuracy ,
@@ -847,6 +849,16 @@ struct ArucoDetector::ArucoDetectorImpl {
847849const RefineParameters& _refineParams): dictionary(_dictionary),
848850detectorParams (_detectorParams), refineParams(_refineParams) {}
849851
852+ float getAverageArucoPinSize (vector<Point2f> markerCorners) {
853+ float averageArucoModuleSize =0 .f ;
854+ int numPins = dictionary.markerSize + detectorParams.markerBorderBits *2 ;
855+ for (size_t i =0ull ; i < markerCorners.size (); i++) {
856+ averageArucoModuleSize +=sqrt (normL2Sqr<float >(Point2f (markerCorners[i] - markerCorners[(i+1ull )%markerCorners.size ()])));
857+ }
858+ averageArucoModuleSize /= ((float )markerCorners.size ()*numPins);
859+ return averageArucoModuleSize;
860+ }
861+
850862};
851863
852864ArucoDetector::ArucoDetector (const Dictionary &_dictionary,
@@ -951,13 +963,15 @@ void ArucoDetector::detectMarkers(InputArray _image, OutputArrayOfArrays _corner
951963const float scale_init = (float ) grey_pyramid[closest_pyr_image_idx].cols / grey.cols ;
952964findCornerInPyrImage (scale_init, closest_pyr_image_idx, grey_pyramid,Mat (candidates[i]), detectorParams);
953965 }
954- else
955- cornerSubPix (grey,Mat (candidates[i]),
956- Size (detectorParams.cornerRefinementWinSize , detectorParams.cornerRefinementWinSize ),
957- Size (-1 , -1 ),
958- TermCriteria (TermCriteria::MAX_ITER | TermCriteria::EPS,
959- detectorParams.cornerRefinementMaxIterations ,
960- detectorParams.cornerRefinementMinAccuracy ));
966+ else {
967+ int cornerRefinementWinSize =std::max (1 ,cvRound (detectorParams.relativeCornerRefinmentWinSize *
968+ arucoDetectorImpl->getAverageArucoPinSize (candidates[i])));
969+ cornerRefinementWinSize =min (cornerRefinementWinSize, detectorParams.cornerRefinementWinSize );
970+ cornerSubPix (grey,Mat (candidates[i]),Size (cornerRefinementWinSize, cornerRefinementWinSize),Size (-1 , -1 ),
971+ TermCriteria (TermCriteria::MAX_ITER | TermCriteria::EPS,
972+ detectorParams.cornerRefinementMaxIterations ,
973+ detectorParams.cornerRefinementMinAccuracy ));
974+ }
961975 }
962976 });
963977 }
@@ -1223,8 +1237,13 @@ void ArucoDetector::refineDetectedMarkers(InputArray _image, const Board& _board
12231237CV_Assert (detectorParams.cornerRefinementWinSize >0 &&
12241238 detectorParams.cornerRefinementMaxIterations >0 &&
12251239 detectorParams.cornerRefinementMinAccuracy >0 );
1240+
1241+ std::vector<Point2f>marker (closestRotatedMarker.begin <Point2f>(), closestRotatedMarker.end <Point2f>());
1242+ int cornerRefinementWinSize =std::max (1 ,cvRound (detectorParams.relativeCornerRefinmentWinSize *
1243+ arucoDetectorImpl->getAverageArucoPinSize (marker)));
1244+ cornerRefinementWinSize =min (cornerRefinementWinSize, detectorParams.cornerRefinementWinSize );
12261245cornerSubPix (grey, closestRotatedMarker,
1227- Size (detectorParams. cornerRefinementWinSize ,detectorParams. cornerRefinementWinSize ),
1246+ Size (cornerRefinementWinSize, cornerRefinementWinSize),
12281247Size (-1 , -1 ),TermCriteria (TermCriteria::MAX_ITER | TermCriteria::EPS,
12291248 detectorParams.cornerRefinementMaxIterations ,
12301249 detectorParams.cornerRefinementMinAccuracy ));