步骤:
(1)制作棋盘格,打印Opencv自带的9*7的棋盘格到A4纸上。棋盘格方格大小为27*27mm。
(2)对准相机晃动棋盘格。得到多张图像。注意棋盘格角度不要过大,出图像边界。距离相机近点。
(3)使用得到的图像,比如10张,一般大于5张。使用Opencv2.0的程序进行相机标定。获取内参和畸变系数矩阵。(程序见下方)
(4)使用内参和畸变系数矩阵进行图像矫正。
#include "stdafx.h"
#include
#include
#include
#include
#include
using namespace cv;
using namespace std;
//#define CALIB //打开此宏则为标定,否则为矫正
int main(int argc,char *argv[])
{
#ifdef CALIB
int numBoards = 10; // 图像个数
int board_w = 8; // 棋盘格X方向格子个数-1
int board_h = 6; // 棋盘格Y方向格子个数-1
Size board_sz = Size(board_w, board_h);
int board_n = board_w*board_h;
vector > objectPoints;
vector > imagePoints;
vector corners;
Mat img, gray;
int success = 0;
int k = 0;
bool found = false;
Size sz;
vector obj;
for (int j=0; j
{
obj.push_back(Point3f(j/board_w*27, (j%board_w)*27, 0.0f));
}
//读入一个文件夹下图像
char *path = "Imgs\\";
int count = 0;
char numidx[10] = {0};
char filename[20] = {0};
for (count=0; count
{
memset(numidx,0,10);
itoa(count+1,numidx,10);
memset(filename,0,20);
strcat(filename,path);
strcat(filename,numidx);
strcat(filename,".jpg");
img = imread(filename);
sz = Size(img.cols,img.rows);
if (img.empty())
{
continue;
}
cvtColor(img, gray, CV_BGR2GRAY);
found = findChessboardCorners(gray, board_sz, corners,
CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS);
// returns bool if found or not
if (found)
{
imagePoints.push_back(corners);
objectPoints.push_back(obj);
printf ("Corners stored\n");
success++;
}
cornerSubPix(gray, corners, Size(11, 11), Size(-1, -1),
TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 30, 0.1));
drawChessboardCorners(img, board_sz, corners, found);
imshow("corners", img);
waitKey(200);
img.release();
}
Mat CM = Mat(3, 3, CV_32FC1);
Mat D;
vector rvecs, tvecs;
CM.at(0, 0) = 1;
CM.at(1, 1) = 1;
calibrateCamera(objectPoints, imagePoints, sz, CM, D, rvecs, tvecs);
//保存结果
FileStorage fs1("mycalib.yml", FileStorage::WRITE);
fs1 << "CM" << CM;
fs1 << "D" << D;
fs1.release();
#else
//读入图像
char *filename = "Imgs\\1.jpg";
Mat Img = imread(filename);
Mat ImgUndistort = Img.clone();
Mat CM = Mat(3, 3, CV_32FC1);
Mat D;
//导入相机内参和畸变系数矩阵
FileStorage fs2("mycalib.yml",FileStorage::READ);
fs2["CM"]>>CM;
fs2["D"]>>D;
fs2.release();
//矫正
undistort(Img,ImgUndistort,CM,D);
imshow("img",Img);
imshow("undistort",ImgUndistort);
waitKey(0);
Img.release();
ImgUndistort.release();
#endif
}