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
第零部分:截取标定用的图
第一部分:单目摄像机的标定
第二部分:双目摄像机的标定
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; }
第二部分:双目摄像机的标定
相关文章推荐
- 在win32 api程序中:使用C++风格的字符串
- 编写C++风格的程序,解决百钱问题,将1元人民币兑换成1,2,5分的硬币,有多少种换法
- opencv标定图片生成程序
- Matlab程序 转C++/Opencv基于Mat 不可不知的17个函数
- opencv标定程序(修改)
- 在win32 api程序中:使用C++风格的字符串
- 利用opencv进行相机标定程序
- 改善C++ 程序的150个建议学习之建议26:用引用代替指针
- 改善C++ 程序的150个建议学习之建议24:尽量采用C++风格的强制转型
- Matlab程序转C++/OpenCV不可不知的17个函数
- opencv中c/c++风格函数使用说明
- OpenCV1.0摄像机标定程序
- C++程序风格的思考
- OpenCV单目摄像机标定程序
- c++ opencv调用摄像头程序
- 程序风格的要素-C++风格指南
- C++程序风格的思考
- C++程序风格的思考
- 使用OpenCV编写的LDA程序----C++ LDA代码
- C++程序风格的思考