opencv實現攝像機標定(張正友的標定方法)

2021-06-23 01:25:20 字數 3208 閱讀 2010

張正友演算法的原理:

這裡假定模板平面在世界座標系z=0的平面上:

如下圖,其中,k為攝像機的內引數矩陣,[x y 1]t為模板平面上點的齊次座標,[u v 1]t為模板平面上點投影到圖象平面上對應點的齊次座標,[r1r2r3]和t 分別是攝像機座標系相對於世界座標系的旋轉矩陣和平移向量。

根據旋轉矩陣的性質,即r1tr2=0和||r1||=||r2||=1,每幅圖象可以獲得以下兩個對內引數矩陣的基本約束

由於攝像機有5個未知內引數,所以當所攝取得的影象數目大於等於3時,就可以線性唯一求解出k。

ok,開始動手:

1.首先需要準備一張標定板(在一張a4紙上列印一幅黑白相間的類似西洋棋的棋盤圖):

2.將需要標定的攝像頭固定好(注意是固定,就是說拍照過程中攝像頭不要動)

3.將棋盤圖放在攝像頭的拍攝範圍內,不斷改變a4紙的方向和傾角,拍攝至少10張以上**(理論上多一點會更準確一點)

4.附上原始碼:

/**

* 程式實現功能:標定攝像頭引數

* 輸出:內引數矩陣、畸變係數、旋轉向量、旋轉矩陣、平移向量

* 執行環境:linux + opencv + eclipse (windows下也可以照常執行)

*/#include #include #include using namespace std;

int image_width = 640;//待標定的寬度

int image_height = 480;//待標定的高度

const int chessboardsize_w = 5;//中可標定的行角點數

const int chessboardsize_h = 5;//中可標定的列角點數

const cvsize chessboardsize = cvsize(chessboardsize_w,chessboardsize_h);

const int npoints = chessboardsize_w*chessboardsize_h;//每張中的總角點數

const int nimages=7;//待標定的數

int corner_count[nimages] = ;

float squarewidth = 19; //棋盤格仔的邊長19公釐。

cvmat *intrinsics;

cvmat *distortion_coeff;

cvmat *rotation_vectors;

cvmat *translation_vectors;

cvmat *object_points;

cvmat *point_counts;

cvmat *image_points;

//計算旋轉矩陣需要

double r_matrix[9];

cvmat pr_vec;

cvmat pr_matrix;

void initcorners3d(cvmat *corners3d, cvsize chessboardsize, int nimages, float squaresize);//得到定標點三維座標矩陣

int main()

else cout<

tranv[i] = ((float*)(translation_vectors->data.ptr))[i];

rotv[i] = ((float*)(rotation_vectors->data.ptr))[i];

} dist[3] = ((float*)(distortion_coeff->data.ptr))[3];

//外引數中的r就是旋轉矩陣,t就是平移向量/

cout<

cout<

cout<

cout<

cout<

cout<

//由旋轉向量計算旋轉矩陣

cvinitmatheader(&pr_vec,1,3,cv_64fc1,rotv,cv_autostep);

cvinitmatheader(&pr_matrix,3,3,cv_64fc1,r_matrix,cv_autostep);

cvrodrigues2(&pr_vec, &pr_matrix,0);

cout<

cout<

for(int i=1; i<=9; i++)

cout<

cout<

cout<

cout<

cvreleasemat(&intrinsics);

cvreleasemat(&distortion_coeff);

cvreleasemat(&rotation_vectors);

cvreleasemat(&translation_vectors);

cvreleasemat(&point_counts);

cvreleasemat(&object_points);

cvreleasemat(&image_points);

cvdestroyallwindows();

return 0;

}void initcorners3d(cvmat *corners3d, cvsize chessboardsize, int nimages, float squaresize)

} }(*corners3d) = cvmat(nimages*npoints,3,cv_32fc1, temppoints);//這裡理解起來可能比較晦澀,

//具體可以檢視type_c.h中的cv_inline cvmat cvmat( int rows, int cols, int type, void* data cv_default(null))

}

攝像機標定 張正友標定推導詳解

這裡直接拿上篇博文的結果,中間省去了其它座標系直接的關係,直接給出,如下所示 公式如下 為了和張正友教授的 相統一,現在把公式符號統一一下。第一點 旋轉向量r為正交矩陣,所以又以下的性質 第二點 就是s。它是尺度因子,它的出現只是為了方便運算,而且對於齊次座標,尺度因子不會改變座標值。剛開始不知道 ...

攝像機標定

利用攝像機所拍攝到的影象來還原空間中的物體。在這裡,不妨假設攝像機所拍攝到的影象與三維空間中的物體之間存在以下一種簡單的線性關係 像 m 物 這裡,矩陣m可以看成是攝像機成像的幾何模型。m中的引數就是攝像機引數。通常,這些引數是要通過實驗與計算來得到的。這個求解引數的過程就稱為攝像機標定。中文名 攝...

攝像機標定

攝像機鏡頭的畸變 由於攝像機光學系統並不是精確地按理想化的小孔成像原理工作,存在有透鏡畸 變,物體點在攝像機成像面上實際所成的像與理想成像之間存在有光學畸變誤差。主要的畸變誤差分為三類 徑向畸變 偏心畸變和薄稜鏡畸變。第一類只產生徑向 位置的偏差,後兩類則既產生徑向偏差,又產生切向偏差,下圖2 為無...