您的位置:首页 > 运维架构

opencv笔记3----摄像机标定

2013-09-30 17:32 309 查看
摄像机标定程序计算出相机内参数矩阵(3*3)、畸变参数矩阵(5*1)和外参数矩阵(3*3旋转矩阵+3*1平移矩阵),其中内参数矩阵和畸变参数矩阵固定不变,外参数矩阵由相机与被拍摄物的相对位置而定。

opencv采用Zhang Zhengyou算法,区别于matlab的标定工具箱(calibration toolbox)采用Tsai算法

#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <vector>
#include "imagelist.h"
using namespace cv;
using namespace std;

int main()
{
int  CurrentImage  = 0;
int  CurrentRow    = 0;         //行
int  CurrentColumn = 0;         //列

int ChessBoardSize_w = 7;       //角点个数
int ChessBoardSize_h = 7;
bool  findcorner_result = false;
float  SquareSize=10;//方格大小

Mat src;
Mat gray;
Mat cameraMatrix; //intrinsic
Mat distCoeffs;
vector<Mat> rvecs,tvecs;
Mat rmatrix,tmatrix;

vector<Point2f> imageCorners;//存储角点
vector<vector<Point2f>> imagePoints;
vector<vector<Point3f>> worldPoints;

//读取图片
for(CurrentImage;CurrentImage<NImages;++CurrentImage)
{
src = imread(imageArray[CurrentImage]);
//灰
cvtColor(src,gray,CV_BGR2GRAY);

//检测角点
imageCorners.clear();
findcorner_result = findChessboardCorners(gray,Size(ChessBoardSize_w,ChessBoardSize_h),imageCorners,3);
//精确坐标
cornerSubPix(gray,imageCorners,Size(10,10),Size(-1,-1),TermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,500,0.003));
imagePoints.push_back(imageCorners);
//画角点
/*
drawChessboardCorners(src,Size(ChessBoardSize_w,ChessBoardSize_h),imageCorners,findcorner_result);
imshow("Chess",src);
std::cout<<"print any key to read the next pic"<<std::endl;
waitKey();
*/
}
std::cout<<"开始定标"<<std::endl;
vector<Point3f> objectsCorners;
//世界坐标系坐标
for(CurrentImage=0;CurrentImage<NImages;CurrentImage++)
{
for(CurrentRow=0;CurrentRow<ChessBoardSize_h;CurrentRow++)
for(CurrentColumn=0;CurrentColumn<ChessBoardSize_w;CurrentColumn++)
objectsCorners.push_back(Point3f(CurrentRow*SquareSize,CurrentColumn*SquareSize,0.0));
worldPoints.push_back(objectsCorners);
objectsCorners.clear();
}

calibrateCamera(worldPoints,imagePoints,Size(ChessBoardSize_w,ChessBoardSize_h),cameraMatrix,distCoeffs,rvecs,tvecs,0);
std::cout<<cameraMatrix<<std::endl;
std::cout<<distCoeffs<<std::endl;

for(int i=0;i<NImages;++i)
{

//std::cout<<"第"<<i<<"个图片的旋转向量"<<std::endl;
//std::cout<<rvecs[i]<<std::endl;
std::cout<<"第"<<i+1<<"个图片的旋转矩阵"<<std::endl;
Rodrigues(rvecs[i],rmatrix);
std::cout<<rmatrix<<std::endl;
std::cout<<"第"<<i+1<<"个图片的平移向量"<<std::endl;
std::cout<<tvecs[i]<<std::endl;
//开始误差分析
double err = 0.0;
vector<Point2f>undistortMatrix;
projectPoints(worldPoints[i],rmatrix,tvecs[i],cameraMatrix,distCoeffs,undistortMatrix);
err = norm(undistortMatrix,imagePoints[i]);
std::cout<<"第"<<i+1<<"张图的误差为:"<<err<<std::endl;
}

//显示校正后的图片
Mat result_image;
namedWindow("Undistort_image",0);
for(CurrentImage=0;CurrentImage<NImages;CurrentImage++)
{
Mat srcimage = imread(imageArray[CurrentImage]);
undistort(srcimage,result_image,cameraMatrix,distCoeffs);
imshow("Undistort_image",result_image);
printf("按任意键显示下一幅图片。。。\n");
waitKey(0);
}
waitKey(0);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: