利用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.pswp.cn/pingmian/90587.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/90587.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C/C++语言程序使用三种主要的内存分配方式,和python语言一样么?

这是一个很好的比较问题&#xff01;C/C 和 Python 在内存分配方式上有本质的区别&#xff0c;虽然它们最终使用的都是计算机的物理内存&#xff08;堆、栈等&#xff09;&#xff0c;但语言层面提供的抽象和管理机制完全不同。核心区别&#xff1a;控制权&#xff1a; C/C 程序…

小电流驱动大电流:原理、实现方式与应用前景

目录 一、什么是“小电流驱动大电流”&#xff1f; 举个例子&#xff1a; 二、核心原理与实现方式 1. 电流放大原理 2. 电子开关元件 3. 控制电路设计 4. 附加保护措施 三、为什么采用“小电流驱动大电流”&#xff1f; 1. 提高安全性 2. 降低能耗 3. 改善效率 4. …

【DM数据守护集群搭建-读写分离】

DM数据守护集群搭建-读写分离 读写分离集群由一个主库以及一个或者多个配置了即时&#xff08;Timely&#xff09;归档或实时&#xff08;Realtime&#xff09;归档的备库组成&#xff0c;其主要目标是在保障数据库可用性基础上&#xff0c;实现读、写操作的自动分离&#xff0…

earth靶场

1、找ip和端口主机是192.168.6.213&#xff0c;因此靶场ip就是192.168.6.34&#xff0c;三个端口开放&#xff0c;我们去访问一下页面。三个端口都无法访问。我们使用nmap进行dns解析。nmap -A -p- -T4 -sV 192.168.6.34把这两条解析添加到hosts文件中去&#xff0c;这样我们才…

Kafka——Java消费者是如何管理TCP连接的?

引言在分布式消息系统中&#xff0c;网络连接是数据流转的"血管"&#xff0c;其管理效率直接决定了系统的吞吐量、延迟与稳定性。作为Kafka生态中负责数据消费的核心组件&#xff0c;Java消费者&#xff08;KafkaConsumer&#xff09;的TCP连接管理机制一直是开发者理…

idea监控本地堆栈

idea 安装插件 VisualVM Launcher重启idea后&#xff0c;配置 VisualVM 属性选择自己jdk的 jvisualvm启动时&#xff0c;选择监控&#xff0c;会自动弹出 VisualVM

系统性提升大模型回复准确率:从 RAG 到多层 Chunk 策略

大语言模型&#xff08;LLM&#xff09;在问答、搜索、对话等任务中展现出强大的生成能力&#xff0c;但它并不具备真实世界知识的完全记忆与对齐能力&#xff0c;尤其在涉及复杂信息、长文档引用或领域细节时&#xff0c;其“幻觉”问题&#xff08;hallucination&#xff09;…

【神经网络概述】从感知机到深度神经网络(CNN RNN)

文章目录1. 神经网络基础1.1 感知器&#xff08;Perceptron)1.2 深度神经网络&#xff08;DNN&#xff09;2. 卷积神经网络&#xff08;CNN&#xff09;2.1 核心思想2.2 典型结构2.3 ⾥程碑模型:2.4 卷积层 - CNN 核心2.5 池化层3. 循环神经网络&#xff08;RNN&#xff09;3.1…

界面规范3-列表下

4、内容文字有链接的采用蓝色字体<font colorblue></font>重要内容采用红字字体&#xff0c;如状态<font colorred></font>一般字体使用color: #3232325、行高height: 40px;line-height: 40px;6、其他表格占满界面空间&#xff0c;内容多时&#xff0c…

中文语音识别与偏误检测系统开发

中文语音识别与偏误检测系统开发 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff0c;觉得好请收藏。点击跳转到网站。 1. 系统概述 本系统旨在开发一个基于Paraformer模型的中文语音识别与偏误检…

MySQL创建普通用户并为其分配相关权限的操作步骤

1. 登录MySQL服务器 首先&#xff0c;你需要以管理员身份登录MySQL服务器。可以使用以下命令&#xff1a; mysql -u root -p 输入密码后&#xff0c;即可进入MySQL命令行界面。 2. 创建新用户 使用CREATE USER语句创建新用户。语法如下&#xff1a; CREATE USER usernamehost I…

OSPF 路由协议多区域

一、课程目标本课程旨在帮助学习者掌握 OSPF 多区域的核心知识&#xff0c;具体包括&#xff1a;掌握 OSPF 各种 LSA 的内容和传递过程、了解普通区域与特殊区域的特点、掌握 OSPF 多区域的配置。二、OSPF 多区域划分的必要性单区域存在的问题单区域 OSPF 网络中&#xff0c;存…

小程序的客服咨询(与企业微信建立沟通)

背景&#xff1a;小程序是面向群众的。需要提供与企业的聊天窗口。 一、连接方式。 使用组件的方式最佳wx.openCustomerServiceChat 二、接入小程序 链接

解码3D格式转换

三维图形与可视化领域&#xff0c;3D模型格式作为数据交换与存储的基石&#xff0c;承载着模型结构、几何形状、纹理以及材质等多重信息。不同的3D模型格式在支持材质的方式上各有差异&#xff0c;这些差异不仅影响模型的外观表现&#xff0c;还在格式转换过程中带来了特定的挑…

HarmonyOS学习记录5

HarmonyOS学习记录5 本文为个人学习记录&#xff0c;仅供参考&#xff0c;如有错误请指出。本文主要记录网络请求的开发知识。 参考文档&#xff1a;HTTP和RCP访问网络 网络连接 概述 网络连接管理提供管理网络一些基础能力&#xff0c;包括WiFi/蜂窝/Ethernet等多网络连接优…

【C/C++】explicit_bzero

explicit_bzero explicit_bzero 是一个为了解决 memset 在安全清除内存场景中可能被优化器移除的问题而设计的函数&#xff0c;广泛用于安全编程中&#xff0c;比如密码、密钥清除等。Introduce 头文件 #include <string.h>函数原型 void explicit_bzero(void *s, size_t…

MySQL 链接方法思考

代码: import subprocess import os from dotenv import load_dotenv import pymysql from sqlalchemy import create_enginedef check_mysql_service():"""检查 MySQL 服务是否运行"""try:result = subprocess.run(["systemctl", &…

jxORM--查询数据

jxORM提供了丰富的数据查询功能。在jxORM中&#xff0c;有两种数据查询方式&#xff1a; 通过数据类执行查询直接使用SQL的select语句查询 数据类查询 数据类查询的优势&#xff1a; 可以根据数据类的定义&#xff0c;自动完成查询条件中的条件值和查询到的数据的类型转换直接获…

详解力扣高频SQL50题之1084. 销售分析 III【简单】

传送门&#xff1a;1084. 销售分析 III 题目 表&#xff1a; Product --------------------- | Column Name | Type | --------------------- | product_id | int | | product_name | varchar | | unit_price | int | --------------------- product_id 是该表的主键&#x…

Kafka入门指南:从零开始掌握分布式消息队列

为什么要有消息队列 生活中有这样的场景快递员将包裹送给买家。 我记得在小时候&#xff0c;收快递是需要快递员电话联系上门时间的。这非常不方便&#xff0c;一方面快递员手中可能有多个包裹&#xff0c;另一方面买家可能在上班时间抽不出身。 后来有了驿站&#xff0c;快递员…