https://pan.baidu.com/s/1oHeMG2KahMCKJucHVL-VBg
预备知识见pdf文件。
下面的代码是我在看完书(写完笔记)之后开始写的,所以没必要和图片配套。
原文网址(内容有修改):https://blog.csdn.net/xuelabizp/article/details/50327393
函数形式
bool findChessboardCorners( InputArray image, Size pattern_size, CvPoint2D32f* corners, OutputArray corners, int flags=3);
参数说明
Image:输入的棋盘图,必须是8位的灰度或者彩色图像。
pattern_size:棋盘图中每行和每列角点的个数。
corners:检测到的角点,类型为std::vector<cv::Point2f>。
flags:一般不管。
返回值表示是否找到了角点。
void drawChessboardCorners(
cv::InputOutputArray image, // 棋盘格图像(8UC3)即是输入也是输出
cv::Size patternSize, // 棋盘格内部角点的行、列数
cv::InputArray corners, // findChessboardCorners()输出的角点
bool patternWasFound // findChessboardCorners()的返回值
);
接下来的源代码是我基于原本博客提供的源代码(作者见程序开头)修改的。图片和.cpp文件放在一个文件夹中。能实现相机矫正、输出内参数和畸变参数
CameraCalibrator.cpp
1 #include "stdafx.h"
2
3 // Open chessboard images and extract corner points
4 int CameraCalibrator::addChessboardPoints(
5 const std::vector<std::string>& filelist,
6 cv::Size & boardSize) {
7
8 // the points on the chessboard
9 std::vector<cv::Point2f> imageCorners;
10 std::vector<cv::Point3f> objectCorners;
11
12 // 3D Scene Points:
13 // Initialize the chessboard corners
14 // in the chessboard reference frame
15 // The corners are at 3D location (X,Y,Z)= (i,j,0)
16 for (int i=0; i<boardSize.height; i++) {
17 for (int j=0; j<boardSize.width; j++) {
18
19 objectCorners.push_back(cv::Point3f(i, j, 0.0f));
20 }
21 }
22
23 // 2D Image points:
24 cv::Mat image; // to contain chessboard image
25 int successes = 0;
26 // for all viewpoints
27 for (int i=0; i<filelist.size(); i++) {
28
29 // Open the image
30 image = cv::imread(filelist[i],0);
31
32 // Get the chessboard corners
33 bool found = cv::findChessboardCorners(
34 image, boardSize, imageCorners);
35
36 // Get subpixel accuracy on the corners
37 cv::cornerSubPix(image, imageCorners,
38 cv::Size(5,5),
39 cv::Size(-1,-1),
40 cv::TermCriteria(cv::TermCriteria::MAX_ITER +
41 cv::TermCriteria::EPS,
42 30, // max number of iterations
43 0.1)); // min accuracy
44
45 // If we have a good board, add it to our data
46 if (imageCorners.size() == boardSize.area()) {
47
48 // Add image and scene points from one view
49 addPoints(imageCorners, objectCorners);
50 successes++;
51 }
52
53 //Draw the corners
54 cv::drawChessboardCorners(image, boardSize, imageCorners, found);
55 cv::imshow("Corners on Chessboard", image);
56 cv::waitKey(100);
57 }
58
59 return successes;
60 }
61
62 // Add scene points and corresponding image points
63 void CameraCalibrator::addPoints(const std::vector<cv::Point2f>& imageCorners, const std::vector<cv::Point3f>& objectCorners) {
64
65 // 2D image points from one view
66 imagePoints.push_back(imageCorners);
67 // corresponding 3D scene points
68 objectPoints.push_back(objectCorners);
69 }
70
71 // Calibrate the camera
72 // returns the re-projection error
73 double CameraCalibrator::calibrate(cv::Size &imageSize)
74 {
75 // undistorter must be reinitialized
76 mustInitUndistort= true;
77
78 //Output rotations and translations
79 std::vector<cv::Mat> rvecs, tvecs;
80
81 // start calibration
82 return
83 calibrateCamera(objectPoints, // the 3D points
84 imagePoints, // the image points
85 imageSize, // image size
86 cameraMatrix, // output camera matrix
87 distCoeffs, // output distortion matrix
88 rvecs, tvecs, // Rs, Ts
89 flag); // set options
90 // ,CV_CALIB_USE_INTRINSIC_GUESS);
91
92 }
93
94 // remove distortion in an image (after calibration)
95 cv::Mat CameraCalibrator::remap(const cv::Mat &image) {
96
97 cv::Mat undistorted;
98
99 if (mustInitUndistort) { // called once per calibration
100
101 cv::initUndistortRectifyMap(
102 cameraMatrix, // computed camera matrix
103 distCoeffs, // computed distortion matrix
104 cv::Mat(), // optional rectification (none)
105 cv::Mat(), // camera matrix to generate undistorted
106 cv::Size(640,480),
107 // image.size(), // size of undistorted
108 CV_32FC1, // type of output map
109 map1, map2); // the x and y mapping functions
110
111 mustInitUndistort= false;
112 }
113
114 // Apply mapping functions
115 cv::remap(image, undistorted, map1, map2,
116 cv::INTER_LINEAR); // interpolation type
117
118 return undistorted;
119 }
120
121
122 // Set the calibration options
123 // 8radialCoeffEnabled should be true if 8 radial coefficients are required (5 is default)
124 // tangentialParamEnabled should be true if tangeantial distortion is present
125 void CameraCalibrator::setCalibrationFlag(bool radial8CoeffEnabled, bool tangentialParamEnabled) {
126
127 // Set the flag used in cv::calibrateCamera()
128 flag = 0;
129 if (!tangentialParamEnabled) flag += CV_CALIB_ZERO_TANGENT_DIST;
130 if (radial8CoeffEnabled) flag += CV_CALIB_RATIONAL_MODEL;
131 }
calibrate.cpp
1 /*------------------------------------------------------------------------------------------*\
2 This file contains material supporting chapter 9 of the cookbook:
3 Computer Vision Programming using the OpenCV Library.
4 by Robert Laganiere, Packt Publishing, 2011.
5
6 This program is free software; permission is hereby granted to use, copy, modify,
7 and distribute this source code, or portions thereof, for any purpose, without fee,
8 subject to the restriction that the copyright notice may not be removed
9 or altered from any source or altered source distribution.
10 The software is released on an as-is basis and without any warranties of any kind.
11 In particular, the software is not guaranteed to be fault-tolerant or free from failure.
12 The author disclaims all warranties with regard to this software, any use,
13 and any consequent failure, is purely the responsibility of the user.
14
15 Copyright (C) 2010-2011 Robert Laganiere, www.laganiere.name
16 \*------------------------------------------------------------------------------------------*/
17
18 #include "stdafx.h"
19
20 int main()
21 {
22
23 cv::namedWindow("Image");
24 cv::Mat image;
25 std::vector<std::string> filelist;
26
27 // generate list of chessboard image filename
28 for (int i=1; i<=14; i++) {
29
30 std::stringstream str;
31 str << i << ".JPG";
32 std::cout << str.str() << std::endl;
33
34 filelist.push_back(str.str());
35 image= cv::imread(str.str(),0);
36 }
37
38 // Create calibrator object
39 CameraCalibrator cameraCalibrator;
40 // add the corners from the chessboard
41 cv::Size boardSize(9,6);
42 cameraCalibrator.addChessboardPoints(
43 filelist, // filenames of chessboard image
44 boardSize); // size of chessboard
45 // calibrate the camera
46 // cameraCalibrator.setCalibrationFlag(true,true);
47 cameraCalibrator.calibrate(image.size());
48
49 // Image Undistortion
50 image = cv::imread(filelist[6]);
51 cv::Mat uImage= cameraCalibrator.remap(image);
52
53 // display camera matrix
54 cv::Mat cameraMatrix= cameraCalibrator.getCameraMatrix();
55 std::cout << " Camera intrinsic: " << cameraMatrix.rows << "x" << cameraMatrix.cols << std::endl;
56 std::cout << cameraMatrix.at<double>(0,0) << " " << cameraMatrix.at<double>(0,1) << " " << cameraMatrix.at<double>(0,2) << std::endl;
57 std::cout << cameraMatrix.at<double>(1,0) << " " << cameraMatrix.at<double>(1,1) << " " << cameraMatrix.at<double>(1,2) << std::endl;
58 std::cout << cameraMatrix.at<double>(2,0) << " " << cameraMatrix.at<double>(2,1) << " " << cameraMatrix.at<double>(2,2) << std::endl;
59
60 cv::Mat distCoeffs = cameraCalibrator.getDistCoeffs();
61 std::cout << "畸变系数矩阵:" << distCoeffs.rows << "x" << distCoeffs.cols << std::endl;
62 for (int i = 0; i<distCoeffs.rows; i++)
63 for (int j = 0; j<distCoeffs.cols; j++)
64 std::cout << distCoeffs.at<double>(i, j) << "\t";
65
66 imshow("Original Image", image);
67 imshow("Undistorted Image", uImage);
68
69 cv::waitKey();
70 return 0;
71 }