当前位置: 首页 > 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.dtcms.com/a/293616.html

相关文章:

  • 电商通用话术模板搭建指南:高效转化,服务升级
  • macOS配置maven及报错处理:zsh: permission denied: mvn
  • Transformer输入部分实现
  • 学习 Flutter(五):玩安卓项目实战 - 下
  • springcloud环境和工程搭建
  • 数组算法之【数组中第K个最大元素】
  • RK3568笔记九十:基于web显示RTSP流
  • 【第三章自定义检视面板_创建自定义编辑器_如何创建自定义PropertyDrawer(9/9)】
  • SQL 中 CASE WHEN 及 SELECT CASE WHEN 的用法
  • HF86611_VB1/HF86611Q_VB1:多通道USB HiFi音频解码器固件技术解析
  • CLI 与 IDE 编码代理比较:提升开发效率的两种路径
  • docker安装minio及配置禁止列出目录文件
  • 解决Node 17+版本与Metro、Webpack等兼容性问题(500)
  • 【计算机网络】正/反向代理服务器,有状态/无状态应用
  • 构建高性能推荐系统:MixerService架构解析与核心实现
  • Spring-IoCDI
  • VPS海外部署Linux分布式计算任务调度-跨国资源整合方案
  • Git 常用的提交类型
  • Object Sense (OSE):一款从编辑器脚本发展起来的编程语言
  • 【数学建模 | Matlab】二维绘图 和 三维绘图
  • 2025年7月一区SCI-投影迭代优化算法Projection Iterative Methods-附Matlab免费代码
  • kotlin基础【1】
  • MATLAB 2024b深度学习新特性全面解析与DeepSeek大模型集成开发技术
  • android studio(NewsApiDemo)100%kotlin
  • 如何在 npm 上发布 Element Plus 二次封装组件
  • Oracle 常用 SQL 命令集合
  • 将 `knife4j` 和 `springdoc-openapi` 集成到你的 Spring Boot 应用
  • 微软Fabric重塑数据管理:Forrester报告揭示高ROI
  • 一次Oracle集群脑裂问题分析处理
  • 前端实现类浏览器的 Ctrl+F 全局搜索功能(Vue2 + mark.js,用于Electron 、QT等没有浏览器Ctrl+F全局搜索功能的壳子中)