單目標定:從理論到OpenCV實踐


單目標定:從理論到OpenCV實踐

一、針 孔攝像機模型    2

1.1 優缺點    2

1.2 孔攝像機模型圖與公式    2

1.2.1 理想情況    2

1.2.2 實際情況    2

1.3 基本投影幾何    3

1.3.1 投影變換的定義    3

1.3.2 攝像機內參數矩陣    3

二、透鏡攝像機    5

2.1 優缺點    5

2.2 透鏡畸變    5

2.2.1 畸變產生原因    5

2.2.2 徑向畸變    5

2.2.3 切向畸變    6

2.2.4 其他畸變    7

三、旋轉矩陣和平移向量    8

四、攝像機內外參數總結    8

五、攝像機標定    9

5.1 標定目的    9

5.2 單應性矩陣    9

5.3 棋盤    10

5.3.1 棋盤大小    10

5.3.2 角點數量與棋盤圖片數量要求    11

5.4 OpenCV的求解理論方法    11

六、矯正    11

七、OpenCV1.1主要相關函數    12

參考文獻    13

 

 

 

一、針 孔攝像機模型

1.1 優缺點

優點:簡單好用。

缺點:真實的針孔由於不能為快速曝光收集足夠的光線,因此不是得到圖像的好方法。

1.2 針 孔攝像機模型圖與公式

1.2.1 理想情況

描述:芯片是正方形,芯片中心在光軸上

f:攝像機焦距

Z:攝像機到物體的距離

X:物理物體長度

x:圖像上的物體長度

1.2.2 實際情況

描述:芯片是矩形(長寬不同),芯片中心不在光軸上

實際上,芯片的中心通常不在光軸上,因此引入新的參數cx和cy;

物理世界中的點Q(X,Y,Z),以某些偏移的方式投影為點(x_srceen,y_srceen):

1.3 基本投影幾何

1.3.1 投影變換的定義

1.3.2 攝像機內參數矩陣

【重要概念】

定義攝像機的參數(fx,fy,cx,cy)重新排列為3X3的矩陣,稱為攝像機內參數矩陣

 

二、透鏡攝像機

2.1 優缺點

優點:利用透鏡收集更多的光線;

缺點:背離了針 孔幾何模型,而且引入透鏡的畸變

2.2 透鏡畸變

2.2.1 畸變產生原因

畸變產生原因:理論上講是可能定義一種透鏡而不引入任何畸變的,然后現實世界沒有完美的透鏡。這主要是制造上的原因,因為制作一個"球形"透鏡比制作一個數學上理想的透鏡更容易。而且從機械方面也很難把透鏡和成像儀保持平行

兩種主要的畸變:徑向畸變切向畸變

2.2.2 徑向畸變

【重要概念】

徑向畸變:來自於透鏡形狀;

2.2.3 切向畸變

【重要概念】

切向畸變:來自於整個攝像機的組裝過程

2.2.4 其他畸變

 

三、旋轉矩陣和平移向量

【重要概念】

四、攝像機內外參數總結

攝像機參數:一般一共15個相關參數:

(1)外參數6個:旋轉3個參數;平移3個參數;

(2)內參數4個:fx,fy,cx,cy;

求解上述10個參數的前提是先假設每次的畸變參數為0;

(3)5個畸變參數:k1,k2,k3,p1,p2;

其中(2)和(3)都為攝像機內參數,其中k3在普通鏡頭不使用,魚眼鏡頭要使用。

 

五、攝像機標定

5.1 標定目的

矯正因使用透鏡而給針 孔模型帶來的主要偏差。

標定的過程既給出攝像機幾何模型、也給出透鏡的畸變模型,即求解上述的15個相關參數。

5.2 單應性矩陣

【重要概念】

單應性矩陣主要解決外參數和內參數矩陣,且假設畸變參數為0。

在計算機視覺中,平面的單應性被定義為從一個平面到另一個平面的投影映射。

 

5.3 棋盤

5.3.1 棋盤大小

(1)標准

一個標准象棋棋盤,格子為7X7。

(2)非標准

(3)最小要求

最少需要4個點(3X3的棋盤點)

(4)格子多的好處

5.3.2 角點數量與棋盤圖片數量要求

5.4 OpenCV求解標定的理論方法

5.4.1 攝像機標定的理論方法簡介

(1)傳統標定法

傳統標定技術在定標的時候,需要在攝像機前放置一個特定的標定物,並認為地提供一組已知坐標的特征基元,攝像機通過尋找標定物上這些已知的特征基元來實現定標。它用到了很多射影幾何方面的理論,是一種直接計算攝像機模型的方法。

(2)自標定法

自標定技術則更為靈活,它不需要特定的參照物來實現定標,是一種對環境具有很強適應性的定標技術,也是目前研究的熱點。它利用環境的剛體性,通過對比多幅圖像中的對應點來計算攝像機模型,但就目前的研究來看,其定標精度還無法與傳統定標技術相比。

(3)張正友標定法

5.4.1 OpenCV采用的理論方法

5.4.2 張正友標定相關理論資料

(1)精簡版8頁《Flexible Camera Calibration by Viewing a Plane from Unknown Orientations》- Zhang1999

網址:http://www.vision.caltech.edu/bouguetj/calib_doc/papers/zhan99.pdf

(2)完整版22頁《A Flexible New Technique for Camera Calibration.rar》- Zhang2000

網址:http://research.microsoft.com/~zhang/Papers/TR98-71.pdf

(3)張正友主頁:

網址:http://research.microsoft.com/en-us/um/people/zhang/

(3)張正友主頁中的相機標定頁:

網址:http://research.microsoft.com/en-us/um/people/zhang/Calib/

5.4.3 Brown論文資料

網址:http://www.ifp.uni-stuttgart.de/lehre/vorlesungen/Aero/Brown71.pdf

六、矯正

利用棋盤標定的結果可進行畸變矯正。

 

七、OpenCV1.1主要相關函數

7.1 單目標定流程與對應主要函數

(1)查找棋盤角點:cvFindChessboardCorners;

(2)亞像素角點:cvFindCornerSubPix;

(3)顯示角點結果:cvDrawChessboardCorners;

(4)單目標定:

[A]方式一:獲取攝像機內外參數:cvCalibrateCamera2(內部包含

cvFindExtrinsicCameraParams2);

[B]方式二:根據攝像機內參數求取外參數:cvFindExtrinsicCameraParams2

注意:上述兩種方式輸出的是旋轉向量和平移向量,如果需要轉換為矩陣使用函數cvRodrigues2,該函數可以將向量和矩陣進行互轉。

(5)圖像畸變矯正:

[A]單目圖像畸變矯正方式一(效率低):cvUndistort2;

[B]單目圖像畸變矯正方式二(效率高):cvInitUndistortMap+cvRemap;

[C]雙目點畸變矯正:cvUndistortPoints(注意:輸入輸出為點坐標,只能在雙目標定中使用)。

(6)統計單目標定誤差(計算3D點在圖像上的投影坐標與棋盤點坐標的差值):

cvProjectPoints2+cvNorm。

注意:cvProjectPoints2輸入的是旋轉向量和平移向量。

7.2 主要相關函數詳解

7.2.1 cvCalibrateCamera2詳解

(1)函數原型

void cvCalibrateCamera2(const CvMat* object_points,

const CvMat* image_points,

const CvMat* point_counts,

CvSize image_size,

CvMat* intrinsic_matrix,//[output]

CvMat* distortion_coeffs,//[output]

CvMat* rotation_vectors=NULL,//[output]

CvMat* translation_vectors=NULL,//[output]

int flags=0

);

(2)參數注釋(9個)

  • object_points

定標點的世界坐標,為3xN或者Nx3的矩陣,這里N是所有視圖中點的總數。

http://www.360doc.com/content/14/0410/14/10724725_367762917.shtml

 

  • image_points

定標點的圖像坐標,為2xN或者Nx2的矩陣,這里N是所有視圖中點的總數。

  • point_counts

向量,指定不同視圖里點的數目,1xM或者Mx1向量,M是視圖數目。

  • image_size

圖像大小,只用在初始化內參數時。

  • intrinsic_matrix

輸出內參矩陣(A) ,如果指定

CV_CALIB_USE_INTRINSIC_GUESS和(或)CV_CALIB_FIX_ASPECT_RATIONfx fy cxcy部分或者全部必須被初始化。

  • distortion_coeffs

輸出大小為4x1或者1x4的向量,里面為形變參數[k1, k2, p1, p2]

  • rotation_vectors

輸出大小為3xM或者Mx3的矩陣,里面為旋轉向量(旋轉矩陣的緊湊表示方式,具體參考函數cvRodrigues2

  • translation_vectors

    輸出大小為3xMMx3的矩陣,里面為平移向量。

  • flags【重點】

不同的標志,可以是0(默認),或者下面值的組合:

  • CV_CALIB_USE_INTRINSIC_GUESS(1):內參數矩陣包含fxfycxcy的初始值。否則,(cx, cy)被初始化到圖像中心(這兒用到圖像大小),焦距用最小平方差方式計算得到。注意,如果內部參數已知,沒有必要使用這個函數,使用cvFindExtrinsicCameraParams2則可。
  • CV_CALIB_FIX_ASPECT_RATIO2):優化過程中認為fxfy中只有一個獨立變量,保持比例fx/fy不變,fx/fy的值跟內參數矩陣初始化時的值一樣。在這種情況下,(fx, fy)的實際初始值或者從輸入內存矩陣中讀取(當CV_CALIB_USE_INTRINSIC_GUESS被指定時),或者采用估計值(后者情況中fxfy可能被設置為任意值,只有比值被使用)。
  • CV_CALIB_FIX_PRINCIPAL_POINT(4):主點在全局優化過程中不變,一直在中心位置或者在其他指定的位置(當CV_CALIB_USE_INTRINSIC_GUESS設置的時候)。
  • CV_CALIB_ZERO_TANGENT_DIST(8):切向形變參數(p1, p2)被設置為0,其值在優化過程中保持為0
  • CV_CALIB_FIX_FOCAL_LENGTH(16):該標志在優化的時候,直接使用 intrinsic_matrix傳遞過來的
  • CV_CALIB_FIX_K1(32):固定徑向畸變k1。徑向畸變參數可以通過組合這些標志設置為任意值。
  • CV_CALIB_FIX_K2(64):固定徑向畸變k2。徑向畸變參數可以通過組合這些標志設置為任意值。
  • CV_CALIB_FIX_K3(128):固定徑向畸變k3。徑向畸變參數可以通過組合這些標志設置為任意值,通常設置為0。

(3)單目定標函數cvCalibrateCamera2采用怎樣的 flags 比較合適?(來自[文獻4]

由於一般鏡頭只需要計算k1,k2,p1,p2四個參數,所以我們首先要設置 CV_CALIB_FIX_K3;其次,如果所用的攝像頭不是高端的、切向畸變系數非常少的,則不要設置 CV_CALIB_ZERO_TANGENT_DIST,否則單目校正誤差會很大;如果事先知道攝像頭內參的大概數值,並且cvCalibrateCamera2函數的第五個參數intrinsic_matrix非空,則也可設置 CV_CALIB_USE_INTRINSIC_GUESS ,以輸入的intrinsic_matrix為初始估計值來加快內參的計算;其它的 flag 一般都不需要設置,對單目定標的影響不大。

7.2.2 cvFindExtrinsicCameraParams2詳解

(1)函數原型

void cvFindExtrinsicCameraParams2( const CvMat* object_points,

const CvMat* image_points,

const CvMat* intrinsic_matrix,

const CvMat* distortion_coeffs,

CvMat* rotation_vector,//[output]

CvMat* translation_vector//[output]

);

(2)參數注釋(6個)

  • object_points

定標點的坐標,為3xN或者Nx3的矩陣,這里N是視圖中的個數。

  • image_points

定標點在圖像內的坐標,為2xN或者Nx2的矩陣,這里N是視圖中的個數。

  • intrinsic_matrix

內參矩陣(A)

  • distortion_coeffs

大小為4x1或者1x4的向量,里面為形變參數[k1,k2,p1,p2]。如果是NULL,所有的形變系數都為0

  • rotation_vector

輸出大小為3x1或者1x3的矩陣,里面為旋轉向量(旋轉矩陣的緊湊表示方式,具體參考函數cvRodrigues2)。

  • translation_vector

大小為3x11x3的矩陣,里面為平移向量。

7.3 單目標定示例代碼

http://blog.sina.com.cn/s/blog_73ef08a80100vi49.html

 

 

八、單目標定效果不好的原因分析

(1)問題來自[文獻3]):OpenCV中用cvCalibrateCamera2 進行相機標定的精度差,標定結果不穩定

分析:可能原因有:

A.夾角太小會導致誤差較大

可能是在標定的時候標定板所在平面與成像平面(image plane)之間的夾角太小,張正友論文里的仿真數據(有噪聲的數據)說明當兩者夾角太小誤差會很大,從張正友的論文里給出的5幅圖中(http://research.microsoft.com/~zhang/Calib/),其中標定平面與成像平面的夾角分別為:8.8947、11.2325、24.4875、10.8535、9.5829(單位:度)。而且張正友的論文中也提到兩幅標定板之間的位置平行放置的話,相關相當於一幅,因此在實際標定中平行放置的情況最好避免,可能有時你無形之中就犯了這個錯誤。

B.標定時拍攝的圖片太少

雖然張正友的論文里只用了5幅圖片,但是建議用10來幅左右還是必要的,因為我們實際中可能標定板用A4的紙打印出來貼在一塊板上的,標定板上的世界坐標精度就不是特別高,多拍攝幾幅圖像能減少這方面帶來的誤差,而且多個角度拍攝也可能解決了問題一:標定板和成像平面夾角小的問題。

有個例子是用20幅圖片進行標定的:

http://www.vision.caltech.edu/bouguetj/calib_doc/htmls/example.html

C.圖像上角點提取的不准確

用cvFindChessboardCorners函數找角點不是很好,假如拍到的圖像不是完整的棋盤格的時候肯定會有問題的,而且也不少人反應用這個函數提取不出角點,建議可以用其他工具 比如:

OpenCV and MatLab Camera Calibration Toolboxes Enhancement:

http://graphics.cs.msu.ru/en/research/calibration/

Camera Calibration Toolbox for Matlab(強烈推薦):

http://www.vision.caltech.edu/bouguetj/calib_doc/htmls/example.html

 

(2)建議用其他標定方法(比如Tsai)或其他標定工具進行對比

強烈推薦 用這個matlab標定工具箱來進行標定,可以和OpenCV做對比,它也是基於張正友的平面標定方法的,做得非常人性化,有誤差分析、標定結果三維重建、重投影計算角點等功能 。

Camera Calibration Toolbox for Matlab:

http://www.vision.caltech.edu/bouguetj/calib_doc/

 

(3)使用OpenCV進行攝像機定標雖然方便,但是定標結果往往不夠准確和穩定,最好是使用 Matlab標定工具箱 來進行定標,再將定標結果取回來用於立體匹配和視差計算。

 

參考文獻

  1. [書籍]學習OpenCV:第十一章 攝像機模型與標定。
  2. [書籍]基於OpenCV的計算機視覺技術實現

http://blog.csdn.net/zhazhiqiang/article/details/50593677

http://blog.csdn.net/zhazhiqiang/article/details/50593730

  1. [書籍]學習OpenCV:第十一章5。
  2. [書籍]學習OpenCV:第十一章。
  3. [書籍]學習OpenCV:第十一章2

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM