当前位置: 首页 > news >正文

利用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;
}

http://www.lryc.cn/news/597001.html

相关文章:

  • EDoF-ToF: extended depth of field time-of-flight imaging解读, OE 2021
  • C Primer Plus 第6版 编程练习——第10章(上)
  • 2025暑期—05神经网络-BP网络
  • 深入解析预训练语言模型在文本生成中的革命性应用:技术全景与未来挑战
  • 工业微控制器的启动过程以及安全设计所面临的挑战
  • TODAY()-WEEKDAY(TODAY(),2)+1
  • 数据结构系列之二叉搜索树
  • 关于针对 DT_REG 出现红色波浪线的问题(编译错误/IDE警告),以下是 精准解决方案,保持你的代码功能完全不变:
  • LeetCode11~20题解
  • 动态递归之正则表达式
  • 西安电子科技大学金融学431考研经历分享
  • 分布式任务调度实战:XXL-JOB与Elastic-Job深度解析
  • 一次Oracle集群脑裂问题分析处理
  • PetaLinux 使用技巧与缓存配置
  • Oracle迁移到高斯,查询字段默认小写,解决办法
  • Zookeeper学习专栏(七):集群监控与管理
  • MySQL binlog解析
  • IDEA maven加载依赖失败不展示Dependencies项
  • 华为云数据库 GaussDB的 nvarchar2隐式类型转换的坑
  • Tomcat与JDK版本对照全解析:避坑指南与生产环境选型最佳实践
  • 【矩阵专题】Leetcode73.矩阵置零
  • 华为云开发者空间 × DeepSeek-R1 智能融合测评:云端开发与AI客服的协同进化
  • (46)elasticsearch-华为云CCE无状态负载部署
  • 基于Dapr Sidecar的微服务通信框架设计与性能优化实践
  • python学智能算法(二十九)|SVM-拉格朗日函数求解中-KKT条件
  • 华为云中,列表中的镜像无法删除可能由多种原因导致
  • MybatisPlus操作方法详细总结
  • CNN实战案例:从图像识别到医疗诊断
  • 19-动态路由
  • QEMU RISCV TCG 详解二 -- RISCV CPU Representation