利用aruco标定板标定相机
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;
}