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 如果想鎖定快取進行讀寫操作,那麼可...