這篇部落格介紹得很詳細,鏈結
其中,opencv魚眼相機標定後,畸變引數是4個,鏈結裡部落格的畸變引數是五個,應該是使k0=1.
1)世界座標系->相機座標系
2)相機座標系->影象物理座標系
注意使用的是歸一化的座標,魚眼模型好像都是近似為單位球面投影模型,這點還是比較困惑,為什麼不直接用f,而是在單位球面上建模。
徑向畸變座標
xd,yd這個公式不太明白,括號內應該是rd才對吧?不過如果是單位球面、等距投影,rd=theta_d,這樣就說的通了。
3)影象物理座標系->影象畫素座標系
綜合:
#include
"learnbasic.h"
#include
"stdio.h"
#include
#include
#include
void
getfiles
(string path, vector
& files)
else
}while
(_findnext
(hfile,
&fileinfo)==0
);_findclose
(hfile);}
}void
fisheyecalibration()
//檢測棋盤點
namedwindow
("img"
, window_normal)
;for
(int i =
0; i < picnum; i++
) worldpoints.
push_back
(worldpoint)
;cornersubpix
(img_gray, imgpoint, cv::
size(3
,3), cv::
size(-
1,-1
),cv::
termcriteria
(cv::termcriteria::max_iter + termcriteria::eps,30,
0.1));
// drawchessboardcorners(img, cv::size(colnum, rownum), imgpoint, true);
// imshow("img", img);
// waitkey(0);
imgpoints.
push_back
(imgpoint);}
//標定
cv::fisheye::
calibrate
(worldpoints, imgpoints, picsize, cameramatrix, distcoeffs,
rvecs, tvecs, flag, cv::
termcriteria(3
,20,1e-6))
; cout << cameramatrix << endl;
cout << distcoeffs << endl;
//調整相機顯示
double mechinew =
540;
//設定想要的幅面寬,高按比例轉換
double chessboardw =
(colnum-1)
* space;
//棋盤點範圍,範圍外畸變校正的效果應該比較差
double chessboardh =
(rownum-1)
* space;
vector undistort_imgpts;
vector prj_imgpts;
mat newcameramatrix = cameramatrix.
clone()
; cv::fisheye::
projectpoints
(worldpoints[0]
, prj_imgpts, rvecs[0]
, tvecs[0]
, cameramatrix, distcoeffs,0,
noarray()
);cv::fisheye::
undistortpoints
(prj_imgpts, undistort_imgpts, cameramatrix, distcoeffs, cv::
noarray()
, cameramatrix)
;double chessboardw_pix =
fabs
(undistort_imgpts.at(
0).x - undistort_imgpts.
at(rownum*colnum -1)
.x);
double chessboardh_pix =
fabs
(undistort_imgpts.at(
0).y - undistort_imgpts.
at(rownum*colnum -1)
.y);
double pixsize =
sqrt((
pow(chessboardw,2)
+pow
(chessboardw,2)
)/(pow
(chessboardw_pix,2)
+pow
(chessboardh_pix,2)
)); cout <<
"畸變校正後畫素精度:"
<< pixsize<< endl;
double scale = mechinew / pixsize /picsize.width;
//縮放比例,確定新的內參,可以想象為把靶面尺寸縮放
cout <<
"scale:"
<
newcameramatrix.at<
double
>(0
,0)= cameramatrix.at<
double
>(0
,0)/scale;
newcameramatrix.at<
double
>(1
,1)= cameramatrix.at<
double
>(1
,1)/scale;
mat mapx, mapy;
cv::fisheye::
initundistortrectifymap
(cameramatrix, distcoeffs, cv::matx33d::
eye(
), newcameramatrix,
picsize, cv_16sc2, mapx, mapy)
;for
(int i =
0; i < picnum; i++
)}
調整顯示後,大致就是我需要的乙個540寬左右區域的範圍 使用OpenCV標定魚眼鏡頭(C )
由於魚眼鏡頭和針孔鏡頭的模型不一樣,對於魚眼鏡頭的模型在之前的部落格中已經做了詳細介紹,這裡直接使用opencv中的cv fisheye calibrate 函式進行標定。函式原型如下,需要輸入目標點集,影象點集 影象尺寸。函式輸出相機內參,畸變係數,旋轉矩陣和平移向量,以及反投影誤差。cv exp...
OPENCV原始碼閱讀 魚眼鏡頭標定
cv fisheye initundistortrectifymap inputarray k,inputarray d,inputarray r,inputarray p,const cv size size,int m1type,outputarray map1,outputarray map2...
OpenCV相機標定
include include include include 標頭檔案 include using namespace cv 包含cv命名空間 using namespace std 棋盤標靶中每塊的寬和高 int g height 100 int g width 100 int g innerh...