【相機標定】OpenCV 相機標定中的重投影誤差與角點三維坐標計算詳解

摘要:
本文將從以下幾個方面展開,結合典型代碼深入解析 OpenCV 中的相機標定過程,重點闡述重投影誤差的計算方法與實際意義,并通過一個 calcBoardCornerPositions() 函數詳細講解棋盤格角點三維坐標的構建邏輯。


在計算機視覺領域,相機標定(Camera Calibration)是獲取相機內參數和畸變參數的關鍵步驟。而重投影誤差(Reprojection Error)則是衡量標定精度的重要指標。在使用 OpenCV 進行標定時,我們經常會接觸到一個名為 computeReprojectionErrors() 的函數,它用于計算重投影誤差,幫助我們評估標定結果的準確性。



↓↓↓↓↓↓ 以下正文 ↓↓↓↓↓↓


一、重投影誤差是什么?

在相機標定中,我們使用一個帶有已知幾何尺寸的標定板(如棋盤格)進行拍攝,通過提取圖像中的角點并與其在世界坐標系中的真實三維位置進行比較,來擬合相機的內參(焦距、主點)與畸變參數。

重投影誤差定義為:

將三維點通過估計得到的相機內參、外參投影回圖像平面后,與實際檢測到的二維圖像點之間的距離。

重投影誤差越小,說明標定模型與實際相機系統越吻合。

在 OpenCV 中,這個誤差通常用像素為單位來表示,計算結果常用于衡量整個標定質量的好壞。

OpenCV 中的計算方式

computeReprojectionErrors(objectPoints, rvecs, tvecs, reprojectionErrors);
  • objectPoints: 世界坐標系中的三維點數組
  • rvecs: 每一張標定圖像的旋轉向量
  • tvecs: 每一張標定圖像的平移向量
  • reprojectionErrors: 輸出每張圖像的重投影誤差

重投影誤差一般多大算合理?

一般經驗值如下:

  • 小于 0.5 像素:標定質量非常好,適用于高精度需求。
  • 0.5 ~ 1.0 像素:精度良好,適用于大部分應用。
  • 1.0 ~ 2.0 像素:仍可接受,但存在優化空間。
  • 大于 5 像素:標定可能存在錯誤或數據異常。

因此,如果你得到的誤差值為 20.5 像素,就需要對標定流程和輸入數據進行徹底排查。


二、重投影誤差異常的原因分析

當我們遇到過大的重投影誤差(比如 10 像素以上)時,很可能是以下幾個方面出現了問題:

1. 棋盤格角點檢測不準確

  • 照片模糊、曝光不均、反光嚴重導致角點提取失敗或偏移。
  • 建議使用 drawChessboardCorners() 顯示檢測結果,手動驗證角點匹配質量。

2. 標定板尺寸設置錯誤

  • 如果你的標定板上一個格子的實際物理大小是 25mm,而你誤填為 1mm 或 100mm,都會導致估計的相機矩陣出現異常。

3. 數據單位不統一

  • 確保所有物理坐標(如角點位置)單位一致,且以米或毫米為準。

4. 輸入圖像質量差或數量太少

  • 用于標定的圖片最好在 10 張以上,覆蓋不同視角與姿態。
  • 圖像需保證清晰、沒有嚴重的畸變或遮擋。

5. 相機模型選擇不當

  • OpenCV 支持多種畸變模型,如 CV_CALIB_RATIONAL_MODEL。錯誤的模型可能造成擬合能力下降。

三、異常相機矩陣的常見原因

相機矩陣的一般形式如下:

[ fx   0   cx ]
[  0  fy   cy ]
[  0   0    1 ]
  • fx, fy: 焦距,單位為像素
  • cx, cy: 圖像主點(通常為圖像中心)

如果你得到了一個如下的相機矩陣:

[42880.11, 0, 959.5;0, 42880.11, 539.5;0, 0, 1]

說明焦距異常大,很可能是以下問題導致的:

1. 標定板單位或格子大小設置錯誤

  • 如果設定了極小的格子大小,比如 0.01(但實際是 10mm),那么焦距會被放大一千倍。

2. 視角變化不足

  • 如果所有標定圖片角度過于一致,優化過程無法正確擬合真實焦距。

3. 初始估計參數錯誤

  • 有些標定代碼會使用初始猜測值進行非線性優化。如果初始估計離實際值相差太遠,會導致最終估計錯誤。

建議檢查棋盤格實際物理尺寸,并可嘗試使用 OpenCV 的 calibrateCamera() 函數中的 CALIB_USE_INTRINSIC_GUESS 標志手動輸入初值。


四、棋盤格角點三維坐標構造

在相機標定時,我們需要構造真實世界中棋盤格角點的位置(objectPoints),這組點是在一個統一世界坐標系中的固定值,是整個標定過程的關鍵輸入。

下面是一段典型的構造函數:

private void calcBoardCornerPositions(Mat corners) {final int cn = 3;float[] positions = new float[mCornersSize * cn];for (int i = 0; i < mPatternSize.height; i++) {for (int j = 0; j < mPatternSize.width * cn; j += cn) {positions[(int) (i * mPatternSize.width * cn + j + 0)] =(2 * (j / cn) + i % 2) * (float) mSquareSize;positions[(int) (i * mPatternSize.width * cn + j + 1)] =i * (float) mSquareSize;positions[(int) (i * mPatternSize.width * cn + j + 2)] = 0;}}corners.create(mCornersSize, 1, CvType.CV_32FC3);corners.put(0, 0, positions);
}

關鍵參數說明:

  • mPatternSize: 表示棋盤格的寬度(列數)和高度(行數)。
  • mCornersSize: 所有角點的總數,等于 rows * cols
  • mSquareSize: 每個格子的邊長(單位應與物理一致,比如毫米或米)
  • positions: 一維數組,存儲所有角點的三維坐標(X, Y, Z)
  • Mat corners: 輸出結果,一個 OpenCV 的矩陣,每一行為一個三維坐標點(CV_32FC3)

坐標構造邏輯分析

(2 * (j / cn) + i % 2) * mSquareSize

這表示 x 軸的坐標,注意 (j / cn) 得到的是列索引 col,乘以2再加上偶數行偏移 i % 2,可能是為了構建某種 錯位網格或蜂窩形圖案,而不是標準矩形棋盤格。

i * mSquareSize

表示 y 軸坐標,也就是所在行數乘以邊長。

z = 0

說明所有角點都在 z=0 的平面上,即假設標定板是平的、位于 XY 平面。


五、實踐建議與調試技巧

  1. 統一單位: 確保 mSquareSize 和 objectPoints 的單位統一,并與實際物理尺寸一致。

  2. 角點可視化: 使用 drawChessboardCorners() 函數確認每張圖像角點是否準確。

  3. 圖像多樣性: 包括不同角度、遠近、旋轉的圖片,有利于提高擬合精度。

  4. 重投影誤差判斷標準:

    • 如果誤差 > 2px,應考慮重新標定或排查數據。
    • 5px 時大概率是數據異常或邏輯錯誤。

  5. 參數初始化: 可嘗試為 calibrateCamera() 提供初始猜測值,防止最優化陷入局部極值。


結語

OpenCV 的相機標定流程雖然成熟,但對輸入數據質量和邏輯嚴謹性要求較高。重投影誤差是衡量標定質量的重要指標,若遇到過大數值,往往意味著標定邏輯、數據精度或單位設定存在問題。同時,正確構造棋盤格角點的三維坐標對于整個流程至關重要。

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

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

相關文章

RabbitMQ-運維

文章目錄 前言運維-集群介紹多機多節點單機多節點 多機多節點下載配置hosts?件配置Erlang Cookie啟動節點構建集群查看集群狀態 單機多節點安裝啟動兩個節點再啟動兩個節點驗證RabbitMQ啟動成功搭建集群把rabbit2, rabbit3添加到集群 宕機演示仲裁隊列介紹raft算法協議 raft基…

JVM之內存管理(一)

部分內容來源&#xff1a;JavaGuide二哥Java 圖解JVM內存結構 內存管理快速復習 棧幀&#xff1a;局部變量表&#xff0c;動態鏈接&#xff08;符號引用轉為真實引用&#xff09;&#xff0c;操作數棧&#xff08;存儲中間結算結果&#xff09;&#xff0c;方法返回地址 運行時…

無線射頻模塊如何通過CE RED認證?關鍵規范與準備策略詳解

隨著無線通信設備在歐洲市場的廣泛應用&#xff0c;CE RED認證已成為模塊類產品進入歐盟的強制通行證。作為專注于LoRa模塊、對講模塊與FSK射頻模塊研發的技術企業&#xff0c;我們深知從設計、測試到量產&#xff0c;每一個環節都需緊扣合規底線。本文將圍繞CE RED認證核心要求…

Golang中集合相關的庫

一切編程語言的底層結構都是數組&#xff0c;其它復雜數據結構如Map, Stack&#xff0c;Heap和Queue都是基于數組建立起來的。 Go語言主流工具庫推薦&#xff08;含常用數據結構實現&#xff09; 以下是目前Go生態中最主流且活躍的工具庫&#xff0c;包含隊列、棧、優先級隊列…

ABAP 導入Excel形成內表

文章目錄 創建導入模板程序實現代碼代碼解析運行結果 創建導入模板 程序實現 代碼 *&---------------------------------------------------------------------* *& Report Z_EXCEL_UPLOAD_LHY *&--------------------------------------------------------------…

特殊配合力(SCA)作為全基因組關聯分析(GWAS)的表型,其生物學意義和應用價值

生物學意義 解析非加性遺傳效應 特殊配合力(SCA)主要反映特定親本組合的雜交優勢,由非加性遺傳效應(如顯性、超顯性、上位性)驅動。顯性效應涉及等位基因間的顯性互作,上位性效應則涉及不同位點間的基因互作。通過SCA-GWAS,可以定位調控這些非加性效應的關鍵基因組區域…

應急響應基礎模擬靶機-security1

PS:杰克創建在流量包(result.pcap)在根目錄下&#xff0c;請根據已有信息進行分析 1、攻擊者使用的端口掃描工具是? 2、通過流量及日志審計&#xff0c;攻擊者上傳shell的時訪問web使用IP地址是多少? 3、審計流量日志&#xff0c;攻擊者反彈shell的地址及端口? 4、攻擊者…

uniapp-商城-47-后臺 分類數據的生成(通過數據)

在第46章節中&#xff0c;我們為后臺數據創建了分類的數據表結構schema&#xff0c;使得可以通過后臺添加數據并保存&#xff0c;同時使用云函數進行數據庫數據的讀取。文章詳細介紹了如何通過前端代碼實現分類管理功能&#xff0c;包括獲取數據、添加、更新和刪除分類。主要代…

ClickHouse的基本操作說明

說明 文章內容包括數據庫管理、表操作及查詢等核心功能 創建數據庫 -- 默認引擎&#xff08;Atomic&#xff09; CREATE DATABASE IF NOT EXISTS test_db; -- MySQL引擎&#xff08;映射外部MySQL數據庫&#xff09; CREATE DATABASE mysql_db ENGINE MySQL(host:port, m…

Nacos源碼—7.Nacos升級gRPC分析四

大綱 5.服務變動時如何通知訂閱的客戶端 6.微服務實例信息如何同步集群節點 6.微服務實例信息如何同步集群節點 (1)服務端處理服務注冊時會發布一個ClientChangedEvent事件 (2)ClientChangedEvent事件的處理源碼 (3)集群節點處理數據同步請求的源碼 (1)服務端處理服務注冊…

《Overlapping Experiment Infrastructure: More, Better, Faster》論文閱讀筆記

文章目錄 1 背景2 三個核心概念3 Launch層&#xff1a;特性發布的專用機制4 流量分發策略和條件篩選4.1 四種流量分發類型4.2 條件篩選機制 5 工具鏈與監控體系6 實驗設計原則7 培訓參考與推薦 1 背景 谷歌&#xff08;Google&#xff09;以數據驅動著稱&#xff0c;幾乎所有可…

國芯思辰| 醫療AED可使用2通道24位模擬前端SC2946(ADS1292)

生物電信號監測技術在醫療健康行業中發展迅速&#xff0c;成為評估人體生理健康狀況的關鍵手段。心電&#xff08;ECG&#xff09;、腦電&#xff08;EEG&#xff09;和肌電&#xff08;EMG&#xff09;等信號&#xff0c;通過精密模擬前端芯片捕捉和處理&#xff0c;對醫療診斷…

數據結構【二叉搜索樹(BST)】

二叉搜索樹 1. 二叉搜索樹的概念2. 二叉搜索樹的性能分析3.二叉搜索樹的插入4. 二叉搜索樹的查找5. 二叉搜索樹的刪除6.二叉搜索樹的實現代碼7. 二叉搜索樹key和key/value使用場景7.1 key搜索場景&#xff1a;7.2 key/value搜索場景&#xff1a; 1. 二叉搜索樹的概念 二叉搜索…

RDMA高性能網絡通信實踐

RDMA高性能網絡通信實踐 一、背景介紹二、方法設計A.實現方案B.關鍵技術點 三、代碼及注釋四、注意事項 一、背景介紹 遠程直接內存訪問&#xff08;RDMA&#xff09;技術通過繞過操作系統內核和CPU直接訪問遠程內存&#xff0c;實現了超低延遲、高吞吐量的網絡通信。該技術廣…

ndarray數組掩碼操作,True和False獲取數據

#數組掩碼的表示方法 def testht05():a np.arange(1,10)mask [True,False,True,True,False,True,False,True,True]print(a[mask]) 另外的用法&#xff1a; #掩碼操作獲取子集 def testht06():a np.arange(1,100)print(a[a%3 0 & (a%7 0)] )b np.array([A,"B&qu…

索引工具explain

EXPLAIN 是 MySQL 中一個非常有用的工具,用于分析查詢的執行計劃。通過 EXPLAIN,你可以了解 MySQL 是如何執行查詢的,包括它如何使用索引、表的掃描方式等。這有助于優化查詢性能。以下是 EXPLAIN 輸出的各個字段的詳細解釋: 基本用法 EXPLAIN SELECT * FROM table_name …

Git回顧

參考視頻:【GeekHour】一小時Git教程 一句話定義&#xff1a;Git是一個免費開源的分布式版本控制系統。 版本控制系統可以分為兩種&#xff0c;1.集中式&#xff08;SVN&#xff0c;CVS&#xff09;&#xff1b;2.分布式&#xff08;git&#xff09; git的工作區域和文件狀態…

python打卡day20

特征降維------特征組合&#xff08;以SVD為例&#xff09; 知識點回顧&#xff1a; 奇異值的應用&#xff1a; 特征降維&#xff1a;對高維數據減小計算量、可視化數據重構&#xff1a;比如重構信號、重構圖像&#xff08;可以實現有損壓縮&#xff0c;k 越小壓縮率越高&#…

GuPPy-v1.2.0安裝與使用-生信工具52

GuPPy&#xff1a;Python中用于光纖光度數據分析的免費開源工具 01 背景 Basecalling 是將原始測序信號轉換為堿基序列的過程&#xff0c;通俗地說&#xff0c;就是“把堿基識別出來”。這一過程在不同代測序技術中各不相同&#xff1a; 一代測序是通過解析峰圖實現&#xff1…

47. 全排列 II

題目 給定一個可包含重復數字的序列 nums &#xff0c;按任意順序 返回所有不重復的全排列。 示例 1&#xff1a; 輸入&#xff1a;nums [1,1,2] 輸出&#xff1a; [[1,1,2],[1,2,1],[2,1,1]] 示例 2&#xff1a; 輸入&#xff1a;nums [1,2,3] 輸出&#xff1a;[[1,2,3…