目前在学习圆心标定,opencv库有一个findCirclesGrid函数用来检测圆心,看不太懂,求原理(代码)分析!
```c++
bool findCirclesGrid( InputArray _image, Size patternSize,
OutputArray _centers, int flags, const Ptr<FeatureDetector> &blobDetector,
const CirclesGridFinderParameters& parameters_)
{
CV_INSTRUMENT_REGION();
CirclesGridFinderParameters parameters = parameters_; // parameters.gridType is amended below
bool isAsymmetricGrid = (flags & CALIB_CB_ASYMMETRIC_GRID) ? true : false;
bool isSymmetricGrid = (flags & CALIB_CB_SYMMETRIC_GRID ) ? true : false;
CV_Assert(isAsymmetricGrid ^ isSymmetricGrid);
std::vector<Point2f> centers;
std::vector<Point2f> points;
if (blobDetector)
{
std::vector<KeyPoint> keypoints;
blobDetector->detect(_image, keypoints);
for (size_t i = 0; i < keypoints.size(); i++)
{
points.push_back(keypoints[i].pt);
}
}
else
{
CV_CheckTypeEQ(_image.type(), CV_32FC2, "blobDetector must be provided or image must contains Point2f array (std::vector<Point2f>) with candidates");
_image.copyTo(points);
}
if(flags & CALIB_CB_ASYMMETRIC_GRID)
parameters.gridType = CirclesGridFinderParameters::ASYMMETRIC_GRID;
if(flags & CALIB_CB_SYMMETRIC_GRID)
parameters.gridType = CirclesGridFinderParameters::SYMMETRIC_GRID;
if(flags & CALIB_CB_CLUSTERING)
{
CirclesGridClusterFinder circlesGridClusterFinder(parameters);
circlesGridClusterFinder.findGrid(points, patternSize, centers);
Mat(centers).copyTo(_centers);
return !centers.empty();
}
bool isValid = false;
const int attempts = 2;
const size_t minHomographyPoints = 4;
Mat H;
for (int i = 0; i < attempts; i++)
{
centers.clear();
CirclesGridFinder boxFinder(patternSize, points, parameters);
try
{
bool isFound = boxFinder.findHoles();
if (isFound)
{
switch(parameters.gridType)
{
case CirclesGridFinderParameters::SYMMETRIC_GRID:
boxFinder.getHoles(centers);
break;
case CirclesGridFinderParameters::ASYMMETRIC_GRID:
boxFinder.getAsymmetricHoles(centers);
break;
default:
CV_Error(Error::StsBadArg, "Unknown pattern type");
}
isValid = true;
break; // done, return result
}
}
catch (const cv::Exception& e)
{
CV_UNUSED(e);
CV_LOG_DEBUG(NULL, "findCirclesGrid2: attempt=" << i << ": " << e.what());
// nothing, next attempt
}
boxFinder.getHoles(centers);
if (i != attempts - 1)
{
if (centers.size() < minHomographyPoints)
break;
H = CirclesGridFinder::rectifyGrid(boxFinder.getDetectedGridSize(), centers, points, points);
}
}
if (!centers.empty() && !H.empty()) // undone rectification
{
Mat orgPointsMat;
transform(centers, orgPointsMat, H.inv());
convertPointsFromHomogeneous(orgPointsMat, centers);
}
Mat(centers).copyTo(_centers);
return isValid;
}
bool CirclesGridFinder::findHoles()
{
switch (parameters.gridType)
{
case CirclesGridFinderParameters::SYMMETRIC_GRID:
{
std::vector<Point2f> vectors, filteredVectors, basis;
Graph rng(0);
computeRNG(rng, vectors);
filterOutliersByDensity(vectors, filteredVectors);
std::vector<Graph> basisGraphs;
findBasis(filteredVectors, basis, basisGraphs);
findMCS(basis, basisGraphs);
break;
}
case CirclesGridFinderParameters::ASYMMETRIC_GRID:
{
std::vector<Point2f> vectors, tmpVectors, filteredVectors, basis;
Graph rng(0);
computeRNG(rng, tmpVectors);
rng2gridGraph(rng, vectors);
filterOutliersByDensity(vectors, filteredVectors);
std::vector<Graph> basisGraphs;
findBasis(filteredVectors, basis, basisGraphs);
findMCS(basis, basisGraphs);
eraseUsedGraph(basisGraphs);
holes2 = holes;
holes.clear();
findMCS(basis, basisGraphs);
break;
}
default:
CV_Error(Error::StsBadArg, "Unknown pattern type");
}
return (isDetectionCorrect());
//CV_Error( 0, "Detection is not correct" );
}
Camera Calibration and 3D Reconstruction
https://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html