Matlab雙目標定結果用於opencv(C++)

矩陣的對應關係沒有對應好,導致我的計算結果相差很多,這裏記錄一下矩陣是如何對應的
Matlab 的雙目標定結果包括三部分:兩個相機的內參數、畸變以及兩個相機之間的旋轉R、平移T。

將matlab標定的結果寫入xml文件

參考了網上的代碼

function writeXML2(cameraParams,file)
%writeXML(cameraParams,file)
%功能:將相機校正的參數保存爲xml文件
%輸入:
%cameraParams:相機校正數據結構
%file:xml文件名
%說明在xml文件是由一層層的節點組成的。
%首先創建父節點 fatherNode,
%然後創建子節點 childNode=docNode.createElement(childNodeName),
%再將子節點添加到父節點 fatherNode.appendChild(childNode)
docNode = com.mathworks.xml.XMLUtils.createDocument('opencv_storage'); %創建xml文件對象
docRootNode = docNode.getDocumentElement; %獲取根節點

IntrinsicMatrix = (cameraParams.IntrinsicMatrix)'; %相機內參矩陣
RadialDistortion = cameraParams.RadialDistortion; %相機徑向畸變參數向量1*3
TangentialDistortion =cameraParams.TangentialDistortion; %相機切向畸變向量1*2
Distortion = [RadialDistortion(1:2),TangentialDistortion];%,RadialDistortion(3)]; %構成opencv中的畸變係數向量[k1,k2,p1,p2,k3]

camera_matrix = docNode.createElement('camera-matrix'); %創建mat節點
camera_matrix.setAttribute('type_id','opencv-matrix'); %設置mat節點屬性
rows = docNode.createElement('rows'); %創建行節點
rows.appendChild(docNode.createTextNode(sprintf('%d',3))); %創建文本節點,並作爲行的子節點
camera_matrix.appendChild(rows); %將行節點作爲mat子節點

cols = docNode.createElement('cols');
cols.appendChild(docNode.createTextNode(sprintf('%d',3)));
camera_matrix.appendChild(cols);

dt = docNode.createElement('dt');
dt.appendChild(docNode.createTextNode('d'));
camera_matrix.appendChild(dt);

data = docNode.createElement('data');
for i=1:3
    for j=1:3
        data.appendChild(docNode.createTextNode(sprintf('%.16f ',IntrinsicMatrix(i,j))));
    end
    data.appendChild(docNode.createTextNode(sprintf('\n')));
end
camera_matrix.appendChild(data);
docRootNode.appendChild(camera_matrix);

distortion = docNode.createElement('distortion');
distortion.setAttribute('type_id','opencv-matrix');
rows = docNode.createElement('rows');
rows.appendChild(docNode.createTextNode(sprintf('%d',5)));
distortion.appendChild(rows);

cols = docNode.createElement('cols');
cols.appendChild(docNode.createTextNode(sprintf('%d',1)));
distortion.appendChild(cols);

dt = docNode.createElement('dt');
dt.appendChild(docNode.createTextNode('d'));
distortion.appendChild(dt);
data = docNode.createElement('data');
for i=1:4
      data.appendChild(docNode.createTextNode(sprintf('%.16f ',Distortion(i))));
end
distortion.appendChild(data);

docRootNode.appendChild(distortion);

xmlFileName = file;
xmlwrite(xmlFileName,docNode);
end

運行該函數即可將自己需要的參數分別保存到對應的文件中
在這裏插入圖片描述

opencv使用參數

Mat cameraMatrixL(3, 3, CV_64F), distCoeffL(5, 1, CV_64F);
	Mat cameraMatrixR(3, 3, CV_64F), distCoeffR(5, 1, CV_64F);
	//左右目之間的R,t可通過stereoCalibrate()或matlab工具箱calib求得
	Mat T(3, 1, CV_64F), R(3, 3, CV_64F);
	FileStorage FL;
	FileStorage FR;
	FileStorage FRT;
	FR.open("CamerasParams/2TDanToS/intrcR.xml", FileStorage::READ);
	FL.open("CamerasParams/2TDanToS/intrcL.xml", FileStorage::READ);
	FRT.open("CamerasParams/2TDanToS/out_RT.xml", FileStorage::READ);
	if (FL.isOpened()) {
		FL["camera-matrix"] >> cameraMatrixL;
		FL["distortion"] >> distCoeffL;		
	}
	if (FR.isOpened()) {
		FR["camera-matrix"] >> cameraMatrixR;
		FR["distortion"] >> distCoeffR;
	}
	//cout << cameraMatrixL.ptr<double>(0)[2] << endl;

	if (FRT.isOpened()) {
		FRT["rotation"] >> R;
		FRT["translation"] >> T;
	}
	cout << cameraMatrixL << endl;
	cout << distCoeffL << endl;
	cout << cameraMatrixR << endl;
	cout << distCoeffR << endl;

	cout << R << endl;
	cout << T<<endl;

以上讀入的參數中,需要對R進行轉置,這是因爲matlab的格式與opencv不完全一致導致的。即:

R=R.t();

否則雖然R的變化並不是很大,但是計算結果會有很大的誤差

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章