用單目相機和apriltag二維碼aruco實現單目定位

目錄

一、核心流程與代碼框架

1. ?環境準備?

2. ?ArUco定位實現

3. ?AprilTag定位實現(需額外安裝Apriltag庫)

二、關鍵優化點

1?.亞像素角點優化

2??多標簽聯合定位

三、性能指標(實測)

四、常見問題

?檢測失敗?

?位姿抖動?


ArUco在OpenCV中已經集成,而AprilTag可能需要額外的庫,比如Apriltag庫或者apriltag_ros,需要提前標定相機,獲取camera_matrix和dist_coeffs,并在代碼中加載這些參數

大致步驟是:

  1. 加載相機參數。
  2. 初始化二維碼檢測器(ArUco或AprilTag)。
  3. 捕獲圖像幀。
  4. 檢測二維碼并獲取角點。
  5. 使用solvePnP計算位姿。
  6. 可視化結果,比如繪制坐標系或邊界框

對于ArUco,可以使用detectMarkers函數來檢測,然后估計位姿。

對于AprilTag,需要調用特定的檢測函數,比如detector.detect().

一、核心流程與代碼框架

1. ?環境準備?

  • ?依賴庫?:OpenCV >=4.0(需包含aruco模塊)
    apriltag庫(可選,若需AprilTag支持)
  • ?相機標定?
    通過棋盤格標定獲取相機內參(cameraMatrix)和畸變系數(distCoeffs),存儲為YAML文件:
# camera_params.yaml示例
camera_matrix: !!opencv-matrixrows: 3cols: 3dt: ddata: [800, 0, 320, 0, 800, 240, 0, 0, 1]
distortion_coefficients: !!opencv-matrixrows: 1cols: 5dt: ddata: [0.1, -0.2, 0, 0, 0]

2. ?ArUco定位實現

#include <opencv2/opencv.hpp>
#include <opencv2/aruco.hpp>int main() {// 加載相機參數cv::FileStorage fs("camera_params.yaml", cv::FileStorage::READ);cv::Mat cameraMatrix, distCoeffs;fs["camera_matrix"] >> cameraMatrix;fs["distortion_coefficients"] >> distCoeffs;// 初始化ArUco檢測器cv::aruco::Dictionary dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);cv::aruco::ArucoDetector detector(dictionary);// 打開攝像頭cv::VideoCapture cap(0);cv::Mat frame;while (cap.read(frame)) {// 檢測Markerstd::vector<int> ids;std::vector<std::vector<cv::Point2f>> corners;detector.detectMarkers(frame, corners, ids);if (!ids.empty()) {// 定義Marker物理尺寸(單位:米)float markerLength = 0.05; std::vector<cv::Vec3d> rvecs, tvecs;// 解算位姿cv::aruco::estimatePoseSingleMarkers(corners, markerLength, cameraMatrix, distCoeffs, rvecs, tvecs);// 可視化cv::aruco::drawDetectedMarkers(frame, corners, ids);for (size_t i=0; i<ids.size(); i++) {cv::drawFrameAxes(frame, cameraMatrix, distCoeffs, rvecs[i], tvecs[i], 0.05);std::cout << "ID: " << ids[i] << " tvec: " << tvecs[i] << " rvec: " << rvecs[i] << std::endl;}}cv::imshow("ArUco定位", frame);if (cv::waitKey(10) == 27) break;}return 0;
}

3. ?AprilTag定位實現(需額外安裝Apriltag庫)

#include <apriltag/apriltag.h>
#include <apriltag/tag36h11.h>// AprilTag檢測邏輯
void detectAprilTags(cv::Mat &gray, apriltag_detector_t *td, const cv::Mat &cameraMatrix, const cv::Mat &distCoeffs) {image_u8_t im = { .width = gray.cols, .height = gray.rows, .stride = gray.cols, .buf = gray.data };zarray_t *detections = apriltag_detector_detect(td, &im);for (int i = 0; i < zarray_size(detections); i++) {apriltag_detection_t *det;zarray_get(detections, i, &det);// 提取角點std::vector<cv::Point2f> corners;for (int j = 0; j < 4; j++) {corners.emplace_back(det->p[j][0], det->p[j][1]);}// 定義3D坐標(假設標簽邊長為0.1米)std::vector<cv::Point3f> objPoints = {{-0.05f, -0.05f, 0}, {0.05f, -0.05f, 0},{0.05f, 0.05f, 0}, {-0.05f, 0.05f, 0}};// PnP解算cv::Mat rvec, tvec;cv::solvePnP(objPoints, corners, cameraMatrix, distCoeffs, rvec, tvec);// 繪制坐標系cv::drawFrameAxes(gray, cameraMatrix, distCoeffs, rvec, tvec, 0.1);}apriltag_detections_destroy(detections);
}

二、關鍵優化點

1?.亞像素角點優化

cv::cornerSubPix(gray, corners, cv::Size(5,5), cv::Size(-1,-1),?
? ? ? ? ? ? ? ? ?cv::TermCriteria(cv::TermCriteria::EPS + cv::TermCriteria::MAX_ITER, 30, 0.01));

?

2??多標簽聯合定位

// 加權平均所有檢測到的標簽位姿 cv::Mat avgRvec, avgTvec; for (auto &rvec : rvecs)?

三、性能指標(實測)

場景精度(平移誤差)角度誤差處理速度(FPS)
靜態標簽(1m)<1cm<0.5°60
動態跟蹤(2m)<2cm<1°30

四、常見問題

  1. ?檢測失敗?

    • 確保標簽尺寸與代碼中markerLength參數一致13
    • 調整圖像對比度或添加直方圖均衡化
  2. ?位姿抖動?

    • 對連續幀的tvec/rvec應用卡爾曼濾波27
    • 增加標簽物理尺寸以提高角點檢測精度

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/81948.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/81948.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/81948.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

tinyrenderer筆記(透視矯正)

tinyrenderer個人代碼倉庫&#xff1a;tinyrenderer個人練習代碼 引言 還要從上一節知識說起&#xff0c;在上一節中我為了調試代碼&#xff0c;換了一個很簡單的正方形 obj 模型&#xff0c;配上紋理貼圖與法線貼圖進行渲染&#xff0c;得了下面的結果&#xff1a; what&…

MySQL的內置函數與復雜查詢

目錄 前言 一、聚合函數 1.1日期函數 1.2字符串函數 1.3數學函數 1.4其它函數 二、關鍵字周邊 2.1關鍵字的生效順序 2.2數據源 2.3可以使用聚合函數的關鍵字 前言 在前面幾篇文章中&#xff0c;講解了有關MySQL數據庫、數據庫表的創建、數據庫表的數據操作等等。本文我…

見多識廣4:Buffer與Cache,神經網絡加速器的Buffer

目錄 前言傳統意義上的Buffer與Cache一言以蔽之定義與主要功能BufferCache 數據存儲策略二者對比 神經網絡加速器的bufferInput BufferWeight BufferOutput Buffer與傳統buffer的核心區別總結 前言 知識主要由Qwen和Kimi提供&#xff0c;我主要做筆記。 參考文獻&#xff1a; …

內存的位運算

示例&#xff1a;提取和設置標志位 假設我們有一個32位的整數&#xff0c;其中不同的位代表不同的標志。例如&#xff1a; 位0&#xff1a;是否開啟日志&#xff08;0表示關閉&#xff0c;1表示開啟&#xff09; 位1&#xff1a;是否啟用調試模式&#xff08;0表示禁用&#…

linux -shell原理與運用

1---shell的工作方式和功能 shell的工作方式: shell本身也是一個應用程序,存儲在/bin 或者是/user/bin中 登錄的時候 會根據/etc/passwd文件載入shell默認執行 shell啟動后,就會顯示命令提示符,等待用戶輸入命令 命令的邏輯: 首先會判斷時內部命令還是外部命令,如果是內部…

js獲取uniapp獲取webview內容高度

js獲取uniapp獲取webview內容高度 在uni-app中&#xff0c;如果你想要獲取webview的內容高度&#xff0c;可以使用uni-app提供的bindload事件來監聽webview的加載&#xff0c;然后通過調用webview的invokeMethod方法來獲取內容的高度。 以下是一個示例代碼&#xff1a; <te…

Windows系統升級Nodejs版本

什么是nodejs Node.js 是一個免費、開源、跨平臺的 JavaScript 運行時環境, 它讓開發人員能夠創建服務器 Web 應用、命令行工具和腳本。 NodeJs官網 網址&#xff1a;Node.js — 在任何地方運行 JavaScript 可以通過網址下載安裝&#xff0c;通過官網可以看到現在最新版本為22…

Relay算子注冊(在pytorch.py端調用)

1. Relay算子注冊 (C層) (a) 算子屬性注冊 路徑: src/relay/op/nn/nn.cc RELAY_REGISTER_OP("hardswish").set_num_inputs(1).add_argument("data", "Tensor", "Input tensor.").set_support_level(3).add_type_rel("Identity…

【JavaEE】網絡原理之初識(1.0)

目錄 ?編輯 局域網與廣域網 IP地址和端口號 實現簡單的服務器客戶端交互 簡單理解socket TCP和UDP的差別&#xff08;初識&#xff09; socket面對udp DatagramSocket API DatagramSocket 構造方法 DatagramSocket 方法&#xff1a; DatagramPacket API Data…

Redis數據結構ZipList,QuickList,SkipList

目錄 1.ZipList 1.2.解析Entry&#xff1a; 1.3Encoding編碼 1.4.ZipList連鎖更新問題 2.QuickList SkipList跳表 RedisObject 五種數據類型 1.ZipList redis中的ZipList是一種緊湊的內存儲存結構&#xff0c;主要可以節省內存空間儲存小規模數據。是一種特殊的雙端鏈表…

laravel 12 監聽syslog消息,并將消息格式化后存入mongodb

在Laravel 12中實現監聽Syslog消息并格式化存儲到MongoDB&#xff0c;需結合日志通道配置、Syslog解析和MongoDB存儲操作。以下是具體實現方案&#xff1a; 一、環境配置 安裝MongoDB擴展包 執行以下命令安裝必要的依賴&#xff1a; composer require jenssegers/mongodb ^4.0確…

【STM32項目實戰】一文了解單片機的SPI驅動外設功能

前言&#xff1a;在前面我有文章介紹了關于單片機的SPI外設CUBEMX配置&#xff0c;但是要想使用好SPI這個外設我們還必須對其原理性的時序有一個詳細的了解&#xff0c;所以這篇文章就補充一下SPI比較偏向底層的時序性的邏輯。 1&#xff0c;SPI簡介 SPI是MCU最常見的對外通信…

【挖洞利器】GobyAwvs解放雙手

【滲透測試工具】解放雙手&Goby配合Awvs滲透測試利器\x0a通過Goby和Awvs 解放雙手https://mp.weixin.qq.com/s/SquRK8C5cRpWmfGbIOqxoQ

LangChain4j(15)——RAG高級之跳過檢索

之前的文章中&#xff0c;我們介紹了RAG的使用&#xff0c;但是&#xff0c;每次提問時&#xff0c;都會通過RAG進行檢索。有時&#xff0c;檢索是不必要執行的&#xff0c;比如&#xff0c;當用戶只是說“你好”時。于是&#xff0c;我們需要有條件的跳過檢索過程。 跳過決策…

【SDRS】面向多模態情感分析的情感感知解糾纏表征轉移

abstract 多模態情感分析(MSA)旨在利用多模態的互補信息對用戶生成的視頻進行情感理解。現有的方法主要集中在設計復雜的特征融合策略來整合單獨提取的多模態表示,忽略了與情感無關的信息的干擾。在本文中,我們提出將單模表征分解為情感特定特征和情感獨立特征,并將前者融…

Sui 上線兩周年,掀起增長「海嘯」

兩年前的 5 月 3 日&#xff0c;Sui 的主網正式發布&#xff0c;將在開發網和測試網上驗證過的下一代技術承諾變為現實。這一新興網絡旨在優化現有區塊鏈技術&#xff0c;結合高性能計算環境與安全性、可驗證性及韌性。 隨著 Sui 迎來兩周年&#xff0c;這股浪潮已成長為「海嘯…

深入理解 mapper-locations

mybatis-plus.mapper-locations: classpath*:/mapper/**/*.xml 是 MyBatis/MyBatis-Plus 在 Spring Boot 配置文件&#xff08;如 application.yml 或 application.properties&#xff09;中的一項關鍵配置&#xff0c;用于指定 MyBatis Mapper XML 文件的存放路徑。以下是詳細…

電容的作用

使用多個電容是從電容的實際等效模型去考慮的(也就是從SI&#xff0c;信號完整性方面&#xff09;。只考慮一個實際電容時&#xff0c;它的阻抗曲線是一個類似于倒三角形的形狀&#xff0c;只在諧振頻率點(與等效串聯電感形成)處的阻抗最小。因此相當于只在這一個頻率點處及附近…

移植的本質是什么

有斷時間我就在想&#xff0c;為什么freertos&#xff0c;lvgl等等的移植都是把庫文件放進來&#xff0c;直接點擊編譯&#xff0c;然后把bug都處理完成就移植成功了&#xff0c;為什么呢&#xff1f; 明明我一個函數都沒調用&#xff0c;為什么會有一堆錯誤&#xff0c;莫名其…

廣告場景下的檢索平臺技術

檢索方向概述 數據檢索領域技術選型大體分為SQL事務數據庫、NoSQL數據庫、分析型數據庫三個類型。 SQL數據庫的設計思路是采用關系模型組織數據&#xff0c;注重讀寫操作的一致性&#xff0c;注重數據的絕對安全。為了實現這一思路&#xff0c;SQL數據庫往往會犧牲部分性能&…