您的位置:首页 > 编程语言 > C语言/C++

OpenCV26(c++风格的标定程序)

2017-02-15 20:07 375 查看
http://blog.csdn.net/xuelabizp/article/details/50432715
http://blog.csdn.net/zc850463390zc/article/details/48975263
Bouguet极线校正的方法
http://blog.csdn.net/zkl99999/article/details/48372077
第零部分:截取标定用的图

// 调用两个摄像头.cpp : 定义控制台应用程序的入口点。
// 分别捕获两摄像头的图像
// 2017.02.16

#include "stdafx.h"
#include "opencv2/opencv.hpp"
#include <iostream>
#include <vector>
#include <iostream>

using namespace cv;
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
// introduction !
std::cout<<"*********** Using Guide *********** " <<std::endl;
std::cout<<"* 1. Press 'q' to quit; " <<std::endl;
std::cout<<"* 2. Press 'c' to capture left camera frame (0); " <<std::endl;
std::cout<<"* 3. Press 'v' to capture right camera frame (1); " <<std::endl;
std::cout<<"* 4. Press 'z' to reset pictures' name to start from 0 ; " <<std::endl;
std::cout<<"********** Using Guide End ********** \n" <<std::endl;

VideoCapture cap1;
VideoCapture cap2;
cap1.open(0);
cap2.open(1);

if(cap1.isOpened() && cap2.isOpened())
{
double w = 640, h = 480;
cap1.set(CV_CAP_PROP_FRAME_WIDTH,w);  cap1.set(CV_CAP_PROP_FRAME_HEIGHT,h);
cap2.set(CV_CAP_PROP_FRAME_WIDTH,w);  cap2.set(CV_CAP_PROP_FRAME_HEIGHT,h);

Mat frame1,frame2;
bool stop = false;
namedWindow("Video1");
namedWindow("Video2");

int capturedImageNumber(0);

while(!stop)
{
cap1>>frame1;  if (frame1.empty())  { return -1;  }
imshow("Video1",frame1);

cap2>>frame2;	if (frame2.empty()) {  return -2; }
imshow("Video2",frame2);

if(waitKey(10) == 'q')
stop = true;
else if(waitKey(10) == 'c' )// capture pictures
{
char filename[20]="";
sprintf_s (filename,"img1-%d.jpg", capturedImageNumber++);
imwrite(filename, frame1);
std::cout<<"Saving... "<< filename <<std::endl;
}
else if(waitKey(10) == 'v' )
{
char filename[20]="";
sprintf_s (filename,"img2-%d.jpg", capturedImageNumber++);
imwrite(filename, frame2);
std::cout<<"Saving... "<< filename <<std::endl;
}
else if(waitKey(10) == 'z' )
{
capturedImageNumber = 0;
std::cout<<"capturedImageNumber = "<< capturedImageNumber <<std::endl;
}

}

}
else
{
if(!cap1.isOpened())
std::cout<<" !cap1.isOpened() "<<std::endl;
if(!cap2.isOpened())
std::cout<<" !cap2.isOpened() "<<std::endl;
return -1;
}

return 0;
}


第一部分:单目摄像机的标定

#include "stdafx.h"
#include "opencv2/opencv.hpp"
#include <iostream>
#include <vector>

using namespace cv;

int _tmain(int argc, _TCHAR* argv[])
{
cv::Mat img1;
bool stop(false);
std::vector< std::vector<cv::Point2f> > corners;		// n幅图的角点坐标集合
std::vector< cv::Point2f > corner;						// 一幅图中的角点坐标集合
const int imageWidth = 640;                             // 标定用图的宽
const int imageHeight = 480;							// 标定用图的高
const int boardWidth = 19;                              // 横向的内角点数(见下图中的圈点)
const int boardHeight = 13;                             // 纵向的内角点数(见下图中的圈点)
const int boardCorner = boardWidth * boardHeight;       // 总的角点数据
const int squareSize = 10;                              // 标定板黑白格子的大小(正方形格子的边长) 单位mm
const cv::Size patternSize(boardWidth, boardHeight);	// findChessboardCorners 参数
int number_image = 15;									// 标定用的图片张数
// start to calibrate cameras
// finding cornors

for(int i=1; i<number_image; ++i)
{
char filename[20]="";
sprintf_s (filename,"img1-%d.jpg",i);
img1 = cv::imread(filename);

bool isFind = cv::findChessboardCorners(img1, patternSize, corner,0); // single picture

if(isFind)
{
cv::Mat img_gray;
cv::cvtColor(img1, img_gray, CV_BGR2GRAY);
cv::cornerSubPix(img_gray, corner, cv::Size(5,5), cv::Size(-1, -1), cv::TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 20, 0.1));

// show the process
cv::drawChessboardCorners(img1, patternSize, corner, isFind);
cv::imshow("chessboard", img1);
std::cout << "Image "<<i<<" is good" << std::endl;

// save cornor
corners.push_back(corner);
}
else
{
std::cout << "Image "<<i<<" is bad" << std::endl;
}
} // for end

// intrinsic
cv::Mat intrinsic, distortion_coeff;
intrinsic.create(3, 3, CV_64FC1);
distortion_coeff.create(5, 1, CV_64FC1);

std::vector<cv::Point3f> imgpoint;  // 以棋盘的左上点为原点,棋盘格为单位一,建立坐标
for (int rowIndex = 0; rowIndex < boardHeight; rowIndex++)
{
for (int colIndex = 0; colIndex < boardWidth; colIndex++)
imgpoint.push_back(cv::Point3f(rowIndex * squareSize, colIndex * squareSize, 0));
}
std::vector< std::vector<cv::Point3f> > objRealPoints;                   //各副图像的角点的实际物理坐标集合
for (unsigned imgIndex = 0; imgIndex < corners.size(); ++imgIndex)
objRealPoints.push_back(imgpoint);

// calibration
cv::Mat rvecs, tvecs; // R & t
calibrateCamera(objRealPoints, corners, cv::Size(imageWidth, imageHeight),
intrinsic, distortion_coeff, rvecs, tvecs, CV_CALIB_FIX_ASPECT_RATIO);

// save
// opencv3.0.0以后删去了 cvSave 接口,代替之为 FileStorage
FileStorage fs("intrinsic.yml", FileStorage::WRITE);
if (fs.isOpened())
{
fs << "intrinsic" << intrinsic ;
fs.release();
std::cout << "intrinsic =:" << intrinsic << std::endl;
}
else
{
std::cout << "Error: can not save the intrinsics!!!!!" << std::endl;
}

fs.open("distortion_coeff.yml", FileStorage::WRITE);  // 畸变系数
if (fs.isOpened())
{
fs << "distortion_coeff" << distortion_coeff;
fs.release();
std::cout << "distortion_coeff =:" << distortion_coeff << std::endl;
}
else
std::cout << "Error: can not save the extrinsic parameters !!!"<< std::endl;
return 0;
}




第二部分:双目摄像机的标定
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: