1、生成aruco标定板
#include <opencv2/opencv.hpp>
#include <opencv2/aruco.hpp>
#include <opencv2/objdetect/aruco_detector.hpp>
#include <iostream>
#include <string>
using namespace cv;
using namespace std;
int main()
{
int markersX = 17;
int markersY = 12;
int markerLength = 200;
int markerSeparation = 44;
int margins = markerSeparation;
int borderBits = 1;
bool showImage = false;
String out = "aruco_board4.png";
Size imageSize;
imageSize.width = markersX * (markerLength + markerSeparation) - markerSeparation + 2 * margins;
imageSize.height = markersY * (markerLength + markerSeparation) - markerSeparation + 2 * margins;
aruco::Dictionary dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
aruco::GridBoard board(Size(markersX, markersY), float(markerLength), float(markerSeparation), dictionary);
Mat boardImage;
board.generateImage(imageSize, boardImage, margins, borderBits);
imwrite(out, boardImage);
return 0;
}
2、利用aruco标定板标定相机
#include <opencv2/opencv.hpp>
#include <opencv2/aruco.hpp>
#include <opencv2/objdetect/aruco_detector.hpp>
#include <iostream>
#include <string>
using namespace cv;
using namespace std;
int main()
{
int markersX = 17;
int markersY = 12;
float markerLength = 200;
float markerSeparation = 44;
string outputFile = "cam3.yml";
int calibrationFlags = 0;
float aspectRatio = 1;
aruco::Dictionary dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
aruco::DetectorParameters detectorParams;
bool refindStrategy = false;
int camId = 0;
aruco::GridBoard gridboard(Size(markersX, markersY), markerLength, markerSeparation, dictionary);
aruco::ArucoDetector detector(dictionary, detectorParams);
vector<vector<vector<Point2f>>> allMarkerCorners;
vector<vector<int>> allMarkerIds;
Size imageSize;
vector<string> imgPath;
glob("E:\\相机标定\\0723\\calib1_1\\*.jpg", imgPath);
for (int i = 0; i < 1; i++)
{
Mat image, imageCopy;
image = imread(imgPath[i]);
vector<int> markerIds;
vector<vector<Point2f>> markerCorners, rejectedMarkers;
detector.detectMarkers(image, markerCorners, markerIds, rejectedMarkers);
if (refindStrategy) {
detector.refineDetectedMarkers(image, gridboard, markerCorners, markerIds, rejectedMarkers);
}
image.copyTo(imageCopy);
if (!markerIds.empty()) {
aruco::drawDetectedMarkers(imageCopy, markerCorners, markerIds);
}
std::cout << "markerIds.size() = " << markerIds.size() << std::endl;
namedWindow("out", cv::WINDOW_NORMAL);
resizeWindow("out", imageCopy.cols * 0.4, imageCopy.rows * 0.4);
imshow("out", imageCopy);
waitKey(0);
cv::imwrite("draw.bmp", imageCopy);
if (!markerIds.empty()) {
allMarkerCorners.push_back(markerCorners);
allMarkerIds.push_back(markerIds);
imageSize = image.size();
}
}
if (allMarkerIds.empty()) {
throw std::runtime_error("Not enough captures for calibration\n");
}
Mat cameraMatrix, distCoeffs;
if (calibrationFlags & CALIB_FIX_ASPECT_RATIO) {
cameraMatrix = Mat::eye(3, 3, CV_64F);
cameraMatrix.at<double>(0, 0) = aspectRatio;
}
vector<Point3f> objectPoints;
vector<Point2f> imagePoints;
vector<Mat> processedObjectPoints, processedImagePoints;
size_t nFrames = allMarkerCorners.size();
for (size_t frame = 0; frame < nFrames; frame++) {
Mat currentImgPoints, currentObjPoints;
gridboard.matchImagePoints(allMarkerCorners[frame], allMarkerIds[frame], currentObjPoints, currentImgPoints);
if (currentImgPoints.total() > 0 && currentObjPoints.total() > 0) {
processedImagePoints.push_back(currentImgPoints);
processedObjectPoints.push_back(currentObjPoints);
}
}
double repError = calibrateCamera(processedObjectPoints, processedImagePoints, imageSize, cameraMatrix, distCoeffs,
noArray(), noArray(), noArray(), noArray(), noArray(), calibrationFlags);
bool saveOk = saveCameraParams(outputFile, imageSize, aspectRatio, calibrationFlags,
cameraMatrix, distCoeffs, repError);
std::cout << "Rep Error: " << repError << endl;
std::cout << "Calibration saved to " << outputFile << endl;
std::cout << "cameraMatrix = " << cameraMatrix << endl;
std::cout << "distCoeffs = " << distCoeffs << endl;
return 0;
}