mirror of
https://github.com/opencv/opencv.git
synced 2025-08-05 22:19:14 +08:00
add dynamic window in aruco cornerRefinement
This commit is contained in:
parent
4e60392040
commit
fd4af21350
@ -36,6 +36,7 @@ struct CV_EXPORTS_W_SIMPLE DetectorParameters {
|
||||
minMarkerDistanceRate = 0.05;
|
||||
cornerRefinementMethod = (int)CORNER_REFINE_NONE;
|
||||
cornerRefinementWinSize = 5;
|
||||
relativeCornerRefinmentWinSize = 0.3f;
|
||||
cornerRefinementMaxIterations = 30;
|
||||
cornerRefinementMinAccuracy = 0.1;
|
||||
markerBorderBits = 1;
|
||||
@ -108,9 +109,27 @@ struct CV_EXPORTS_W_SIMPLE DetectorParameters {
|
||||
/** @brief default value CORNER_REFINE_NONE */
|
||||
CV_PROP_RW int cornerRefinementMethod;
|
||||
|
||||
/// window size for the corner refinement process (in pixels) (default 5).
|
||||
/** @brief maximum window size for the corner refinement process (in pixels) (default 5).
|
||||
*
|
||||
* The window size may decrease if the ArUco marker is too small, check relativeCornerRefinmentWinSize.
|
||||
* The final window size is calculated as:
|
||||
* min(cornerRefinementWinSize, averageArucoModuleSize*relativeCornerRefinmentWinSize),
|
||||
* where averageArucoModuleSize is average module size of ArUco marker in pixels.
|
||||
* (ArUco marker is composed of black and white modules)
|
||||
*/
|
||||
CV_PROP_RW int cornerRefinementWinSize;
|
||||
|
||||
/** @brief Dynamic window size for corner refinement relative to Aruco module size (default 0.3).
|
||||
*
|
||||
* The final window size is calculated as:
|
||||
* min(cornerRefinementWinSize, averageArucoModuleSize*relativeCornerRefinmentWinSize),
|
||||
* where averageArucoModuleSize is average module size of ArUco marker in pixels.
|
||||
* (ArUco marker is composed of black and white modules)
|
||||
* In the case of markers located far from each other, it may be useful to increase the value of the parameter to 0.4-0.5.
|
||||
* In the case of markers located close to each other, it may be useful to decrease the parameter value to 0.1-0.2.
|
||||
*/
|
||||
CV_PROP_RW float relativeCornerRefinmentWinSize;
|
||||
|
||||
/// maximum number of iterations for stop criteria of the corner refinement process (default 30).
|
||||
CV_PROP_RW int cornerRefinementMaxIterations;
|
||||
|
||||
|
@ -35,6 +35,8 @@ static inline bool readWrite(DetectorParameters ¶ms, const FileNode* readNod
|
||||
check |= readWriteParameter("minMarkerDistanceRate", params.minMarkerDistanceRate, readNode, writeStorage);
|
||||
check |= readWriteParameter("cornerRefinementMethod", params.cornerRefinementMethod, readNode, writeStorage);
|
||||
check |= readWriteParameter("cornerRefinementWinSize", params.cornerRefinementWinSize, readNode, writeStorage);
|
||||
check |= readWriteParameter("relativeCornerRefinmentWinSize", params.relativeCornerRefinmentWinSize, readNode,
|
||||
writeStorage);
|
||||
check |= readWriteParameter("cornerRefinementMaxIterations", params.cornerRefinementMaxIterations,
|
||||
readNode, writeStorage);
|
||||
check |= readWriteParameter("cornerRefinementMinAccuracy", params.cornerRefinementMinAccuracy,
|
||||
@ -847,6 +849,16 @@ struct ArucoDetector::ArucoDetectorImpl {
|
||||
const RefineParameters& _refineParams): dictionary(_dictionary),
|
||||
detectorParams(_detectorParams), refineParams(_refineParams) {}
|
||||
|
||||
float getAverageArucoPinSize(vector<Point2f> markerCorners) {
|
||||
float averageArucoModuleSize = 0.f;
|
||||
int numPins = dictionary.markerSize + detectorParams.markerBorderBits * 2;
|
||||
for (size_t i = 0ull; i < markerCorners.size(); i++) {
|
||||
averageArucoModuleSize += sqrt(normL2Sqr<float>(Point2f(markerCorners[i] - markerCorners[(i+1ull)%markerCorners.size()])));
|
||||
}
|
||||
averageArucoModuleSize /= ((float)markerCorners.size()*numPins);
|
||||
return averageArucoModuleSize;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
ArucoDetector::ArucoDetector(const Dictionary &_dictionary,
|
||||
@ -951,13 +963,15 @@ void ArucoDetector::detectMarkers(InputArray _image, OutputArrayOfArrays _corner
|
||||
const float scale_init = (float) grey_pyramid[closest_pyr_image_idx].cols / grey.cols;
|
||||
findCornerInPyrImage(scale_init, closest_pyr_image_idx, grey_pyramid, Mat(candidates[i]), detectorParams);
|
||||
}
|
||||
else
|
||||
cornerSubPix(grey, Mat(candidates[i]),
|
||||
Size(detectorParams.cornerRefinementWinSize, detectorParams.cornerRefinementWinSize),
|
||||
Size(-1, -1),
|
||||
TermCriteria(TermCriteria::MAX_ITER | TermCriteria::EPS,
|
||||
detectorParams.cornerRefinementMaxIterations,
|
||||
detectorParams.cornerRefinementMinAccuracy));
|
||||
else {
|
||||
int cornerRefinementWinSize = std::max(1, cvRound(detectorParams.relativeCornerRefinmentWinSize*
|
||||
arucoDetectorImpl->getAverageArucoPinSize(candidates[i])));
|
||||
cornerRefinementWinSize = min(cornerRefinementWinSize, detectorParams.cornerRefinementWinSize);
|
||||
cornerSubPix(grey, Mat(candidates[i]), Size(cornerRefinementWinSize, cornerRefinementWinSize), Size(-1, -1),
|
||||
TermCriteria(TermCriteria::MAX_ITER | TermCriteria::EPS,
|
||||
detectorParams.cornerRefinementMaxIterations,
|
||||
detectorParams.cornerRefinementMinAccuracy));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -1223,8 +1237,13 @@ void ArucoDetector::refineDetectedMarkers(InputArray _image, const Board& _board
|
||||
CV_Assert(detectorParams.cornerRefinementWinSize > 0 &&
|
||||
detectorParams.cornerRefinementMaxIterations > 0 &&
|
||||
detectorParams.cornerRefinementMinAccuracy > 0);
|
||||
|
||||
std::vector<Point2f> marker(closestRotatedMarker.begin<Point2f>(), closestRotatedMarker.end<Point2f>());
|
||||
int cornerRefinementWinSize = std::max(1, cvRound(detectorParams.relativeCornerRefinmentWinSize*
|
||||
arucoDetectorImpl->getAverageArucoPinSize(marker)));
|
||||
cornerRefinementWinSize = min(cornerRefinementWinSize, detectorParams.cornerRefinementWinSize);
|
||||
cornerSubPix(grey, closestRotatedMarker,
|
||||
Size(detectorParams.cornerRefinementWinSize, detectorParams.cornerRefinementWinSize),
|
||||
Size(cornerRefinementWinSize, cornerRefinementWinSize),
|
||||
Size(-1, -1), TermCriteria(TermCriteria::MAX_ITER | TermCriteria::EPS,
|
||||
detectorParams.cornerRefinementMaxIterations,
|
||||
detectorParams.cornerRefinementMinAccuracy));
|
||||
|
Loading…
Reference in New Issue
Block a user