相機標定 calib3d 學習筆記

2021-08-04 03:32:10 字數 4757 閱讀 7588

opencv給的官方**利用xml讀取檔案,不如簡單的讀取txt文字的格式,便於編輯。這份**有三個要注意的地方。

1.txt檔案要標好**

2.size board_size = size(7, 8);我用的是7*8(內角點)的標定板

3.size square_size = size(10, 10);一般情況下應該是這個10*10。

#include 

#include

#include

using

namespace cv;

using

namespace

std;

int main()

else

}int total = image_points_seq.size();

std::cout

<< "total = "

<< total << endl;

int cornernum = board_size.width*board_size.height; //每張上總的角點數

for (int i = 0; i// 便於控制台檢視

std::cout

<< std::endl;

int j = i + 1;

std::cout

<< "----> 第 "

<< j << "張的角點座標 : "

<< endl;;

//輸出所有的角點

for (int j = 0; j < cornernum; j++)

}std::cout

<< "角點提取完成!\n";

//以下是攝像機標定

std::cout

<< "開始標定………………"

<< endl;

/*棋盤三維資訊*/

size square_size = size(10, 10); /* 實際測量得到的標定板上每個棋盤格的大小 */

vector

> object_points; /* 儲存標定板上角點的三維座標 */

/*內外引數*/

mat cameramatrix = mat(3, 3, cv_32fc1, scalar::all(0)); /* 攝像機內引數矩陣 */

vector

point_counts; // 每幅影象中角點的數量

mat distcoeffs = mat(1, 5, cv_32fc1, scalar::all(0)); /* 攝像機的5個畸變係數:k1,k2,p1,p2,k3 */

vector

tvecsmat; /* 每幅影象的旋轉向量 */

vector

rvecsmat; /* 每幅影象的平移向量 */

/* 初始化標定板上角點的三維座標 */

int i, j, t;

for (t = 0; tvector

temppointset;

for (i = 0; ifor (j = 0; j/* 假設標定板放在世界座標系中z=0的平面上 */

realpoint.x = i*square_size.width;

realpoint.y = j*square_size.height;

realpoint.z = 0;

temppointset.push_back(realpoint);}}

object_points.push_back(temppointset);

}/* 初始化每幅影象中的角點數量,假定每幅影象中都可以看到完整的標定板 */

for (i = 0; i/* 開始標定 */

calibratecamera(object_points, image_points_seq, image_size, cameramatrix, distcoeffs, rvecsmat, tvecsmat, 0);

std::cout

<< "標定完成!\n";

//對標定結果進行評價

std::cout

<< "開始評價標定結果………………\n";

double total_err = 0.0; /* 所有影象的平均誤差的總和 */

double err = 0.0; /* 每幅影象的平均誤差 */

vector

image_points2; /* 儲存重新計算得到的投影點 */

std::cout

<< "\t每幅影象的標定誤差:\n\n";

fout << "每幅影象的標定誤差:\n";

for (i = 0; ivector

temppointset = object_points[i];

/* 通過得到的攝像機內外引數,對空間的三維點進行重新投影計算,得到新的投影點 */

projectpoints(temppointset, rvecsmat[i], tvecsmat[i], cameramatrix, distcoeffs, image_points2);

/* 計算新的投影點和舊的投影點之間的誤差*/

vector

tempimagepoint = image_points_seq[i];

mat tempimagepointmat = mat(1, tempimagepoint.size(), cv_32fc2);

mat image_points2mat = mat(1, image_points2.size(), cv_32fc2);

for (int j = 0; j < tempimagepoint.size(); j++)

err = norm(image_points2mat, tempimagepointmat, norm_l2);

total_err += err /= point_counts[i];

std::cout

<< "第"

<< i + 1

<< "幅影象的平均誤差:"

<< err << "畫素"

<< endl << endl;

fout << "第"

<< i + 1

<< "幅影象的平均誤差:"

<< err << "畫素"

<< endl << endl;

}std::cout

<< "總體平均誤差:"

<< total_err / image_count << "畫素"

<< endl << endl;

fout << "總體平均誤差:"

<< total_err / image_count << "畫素"

<< endl << endl;

std::cout

<< "評價完成!"

<< endl;

//儲存定標結果

std::cout

<< "開始儲存定標結果………………"

<< endl;

mat rotation_matrix = mat(3, 3, cv_32fc1, scalar::all(0)); /* 儲存每幅影象的旋轉矩陣 */

fout << "相機內引數矩陣:"

<< endl;

fout << cameramatrix << endl << endl;

fout << "畸變係數:\n";

fout << distcoeffs << endl << endl << endl;

for (int i = 0; i"第"

<< i + 1

<< "幅影象的旋轉向量:"

<< endl;

fout << tvecsmat[i] << endl;

/* 將旋轉向量轉換為相對應的旋轉矩陣 */

rodrigues(tvecsmat[i], rotation_matrix);

fout << "第"

<< i + 1

<< "幅影象的旋轉矩陣:"

<< endl;

fout << rotation_matrix << endl;

fout << "第"

<< i + 1

<< "幅影象的平移向量:"

<< endl;

fout << rvecsmat[i] << endl << endl;

}std::cout

<< "完成儲存"

<< endl;

fout << endl;

mat dst;

undistort(imageinput[0], dst, cameramatrix, distcoeffs);

imshow("result_ex",dst);

waitkey(500);

mat map1, map2;

initundistortrectifymap(

cameramatrix, distcoeffs, mat(),

getoptimalnewcameramatrix(cameramatrix, distcoeffs, image_size, 1, image_size, 0), image_size,

cv_16sc2, map1, map2);

remap(imageinput[0], imageinput[0], map1, map2, inter_linear);

imshow("result_ex2", imageinput[0]);

waitkey(500);

return

0;}

相機模型與標定(學習筆記)

內外參定義 相機中有四個座標系,分別是 從到 從到 從到 標定方法概述 標定板介紹 例 標定方法 計算外參 設三維世界座標點為m x,y,z,1 t,二維相機平面畫素座標為m u,v,1 t,所以標定用的棋盤格平面到影象平面的單應性關係為sm a r,t m,其中 不妨設棋盤格位於z 0,定義旋轉矩...

D3D學習筆記(四)

光照 光照可分為環境光,漫射光,鏡面光三種 三種顏色的光均可用d3decolorvalue或d3dxcolor來表示,描述光線的顏色時,d3dxcolor中的alpha值將被忽略 材質 材質可用結構d3dmaterial9來表示 typedef struct d3dmaterial9d3dmater...

D3D學習筆記(七)

幾何資訊 id3dxbasemesh介面包含乙個頂點快取和乙個索引快取,可用以下方法得到指向這些介面的指標。hresult id3dxmesh getvertexbuffer9 vb 0 hresult id3dxmesh getindexbuffer9 ib 0 如果想鎖定快取進行讀寫操作,那麼可...