OpenCV——單目相機標定
阿新 • • 發佈:2019-02-09
步驟:
1、製作標定板
此處製作邊長2.5cm的棋盤圖,規格大小為8*8,生成程式碼如下所示
//程式設計環境:VS2013, X64,OpenCV3.0.0
#include <iostream>
#include <opencv2\core\core.hpp>
#include <opencv2\opencv.hpp>
using namespace std;
using namespace cv;
int main(){
//單位轉換
int dot_per_inch = 96; //我的電腦是96DPI(dot per inch)
double cm_to_inch = 0.3937; //1cm=0.3937inch
double inch_to_cm = 2.54; //1inch = 2.54cm
double inch_per_dot = 1.0 / 96.0;
//自定義標定板
double blockSize_cm = 2.5; //方格尺寸:邊長2.5cm的正方形
int blockNum = 8; //8*8個方格
int blockSize = (int)(blockSize_cm / inch_to_cm *dot_per_inch);
cout << blockSize << endl;
int imageSize = blockSize * blockNum;
cout << imageSize << endl;
Mat chessBoard(imageSize, imageSize, CV_8UC3, Scalar::all(0));
unsigned char color = 0;
for (int i = 0; i < imageSize; i = i + blockSize){
color = ~color;
for (int j = 0; j < imageSize; j = j + blockSize) {
Mat ROI = chessBoard(Rect(i, j, blockSize, blockSize));
ROI.setTo(Scalar::all(color));
color = ~color;
}
}
imshow("Chess board", chessBoard);
imwrite("chessBoard.jpg", chessBoard);
cvWaitKey(3000);
return 0;
}
標定時,只需將其在電腦上開啟,然後用攝像頭採集圖片即可。
生成的棋盤圖如下圖所示
2、採集20張樣本圖片
下載後,將程式碼複製到VS的win32控制檯程式中,執行,對著棋盤格圖片按空格採集20張圖片即可,如下圖
採集結果:
3、執行相機標定程式
- calibrate.cpp中
str << "C:\\Users\\...\\pic" << i << ".jpg";
這裡就是剛才採集圖片的地址,與2中的地址保持一致即可
2. cv::Size boardSize(6,4);//比如這裡就是6*4,根據你做的棋盤格來改
3. 如果你需要輸出畸變矩陣
在輸出內參矩陣的後面加上
//列印畸變係數矩陣(1*5矩陣)
cv::Mat distCoeffs = cameraCalibrator.getDistCoeffs();
std::cout << "畸變係數矩陣:" << distCoeffs.rows << "x" << distCoeffs.cols << std::endl;
for (int i = 0; i<distCoeffs.rows; i++)
for (int j = 0; j<distCoeffs.cols; j++)
std::cout << distCoeffs.at<double>(i, j) << "\t";```
// save the calibration result
cv::FileStorage camcalibrate("camcalibrate.xml", cv::FileStorage::WRITE);
camcalibrate << "cameraMatrix" << cameraMatrix << "distCoeffs" << distCoeffs.t();
camcalibrate.release();
這裡我用了3種不同的方式採集不同的圖片,得到了不同的結果,分別是
1)直接對電腦圖形取樣(8*8棋盤格 正方形邊長2.5cm)
得到的結果
2)列印棋盤格取樣(8*8棋盤格 正方形邊長2.5cm)
3)直接對電腦圖形取樣(8*8棋盤格 正方形邊長1.5cm)
4)直接對電腦圖形取樣(6*6棋盤格 正方形邊長1.5cm)