Subversion Repositories OpenCV2-Cookbook

Rev

Rev 3 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 PointedEar 1
/*------------------------------------------------------------------------------------------*\
2
   This file contains material supporting chapter 9 of the cookbook:  
5 PointedEar 3
 Computer Vision Programming using the OpenCV Library.
4
 by Robert Laganiere, Packt Publishing, 2011.
3 PointedEar 5
 
5 PointedEar 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.
3 PointedEar 14
 
5 PointedEar 15
 Copyright (C) 2010-2011 Robert Laganiere, www.laganiere.name
16
 \*------------------------------------------------------------------------------------------*/
3 PointedEar 17
 
18
#include "CameraCalibrator.h"
19
 
20
// Open chessboard images and extract corner points
5 PointedEar 21
int
22
CameraCalibrator::addChessboardPoints(const std::vector<std::string>& filelist,
23
    cv::Size & boardSize)
24
{
3 PointedEar 25
 
5 PointedEar 26
  // the points on the chessboard
27
  std::vector<cv::Point2f> imageCorners;
28
  std::vector<cv::Point3f> objectCorners;
3 PointedEar 29
 
5 PointedEar 30
  // 3D Scene Points:
31
  // Initialize the chessboard corners
32
  // in the chessboard reference frame
33
  // The corners are at 3D location (X,Y,Z)= (i,j,0)
34
  for (int i = 0; i < boardSize.height; i++)
35
    {
36
      for (int j = 0; j < boardSize.width; j++)
37
        {
3 PointedEar 38
 
5 PointedEar 39
          objectCorners.push_back(cv::Point3f(i, j, 0.0f));
40
        }
3 PointedEar 41
    }
42
 
5 PointedEar 43
  // 2D Image points:
44
  cv::Mat image; // to contain chessboard image
45
  int successes = 0;
46
  // for all viewpoints
47
  for (unsigned int i = 0; i < filelist.size(); i++)
48
    {
3 PointedEar 49
 
5 PointedEar 50
      // Open the image
51
      image = cv::imread(filelist[i], 0);
3 PointedEar 52
 
5 PointedEar 53
      // Get the chessboard corners
54
      bool found = cv::findChessboardCorners(image, boardSize, imageCorners);
3 PointedEar 55
 
5 PointedEar 56
      // Get subpixel accuracy on the corners
57
      cv::cornerSubPix(image, imageCorners, cv::Size(5, 5), cv::Size(-1, -1),
58
          cv::TermCriteria(cv::TermCriteria::MAX_ITER + cv::TermCriteria::EPS,
59
              30, // max number of iterations
60
              0.1)); // min accuracy
3 PointedEar 61
 
5 PointedEar 62
      // If we have a good board, add it to our data
63
      if (imageCorners.size() == (unsigned int) boardSize.area())
64
        {
3 PointedEar 65
 
5 PointedEar 66
          // Add image and scene points from one view
67
          addPoints(imageCorners, objectCorners);
68
          successes++;
69
        }
3 PointedEar 70
 
5 PointedEar 71
      //Draw the corners
72
      cv::drawChessboardCorners(image, boardSize, imageCorners, found);
73
      cv::imshow("Corners on Chessboard", image);
74
      cv::waitKey(100);
3 PointedEar 75
    }
76
 
5 PointedEar 77
  return successes;
3 PointedEar 78
}
79
 
80
// Add scene points and corresponding image points
5 PointedEar 81
void
82
CameraCalibrator::addPoints(const std::vector<cv::Point2f>& imageCorners,
83
    const std::vector<cv::Point3f>& objectCorners)
84
{
3 PointedEar 85
 
5 PointedEar 86
  // 2D image points from one view
87
  imagePoints.push_back(imageCorners);
88
  // corresponding 3D scene points
89
  objectPoints.push_back(objectCorners);
3 PointedEar 90
}
91
 
92
// Calibrate the camera
93
// returns the re-projection error
5 PointedEar 94
double
95
CameraCalibrator::calibrate(cv::Size imageSize)
3 PointedEar 96
{
5 PointedEar 97
  // undistorter must be reinitialized
98
  mustInitUndistort = true;
3 PointedEar 99
 
5 PointedEar 100
  //Output rotations and translations
101
  std::vector<cv::Mat> rvecs, tvecs;
3 PointedEar 102
 
5 PointedEar 103
  // start calibration
104
  return calibrateCamera(objectPoints, // the 3D points
105
      imagePoints, // the image points
106
      imageSize, // image size
107
      cameraMatrix, // output camera matrix
108
      distCoeffs, // output distortion matrix
109
      rvecs, tvecs, // Rs, Ts
110
      flag); // set options
3 PointedEar 111
//                                      ,CV_CALIB_USE_INTRINSIC_GUESS);
112
 
113
}
114
 
115
// remove distortion in an image (after calibration)
5 PointedEar 116
cv::Mat
117
CameraCalibrator::remap(const cv::Mat &image)
118
{
3 PointedEar 119
 
5 PointedEar 120
  cv::Mat undistorted;
3 PointedEar 121
 
5 PointedEar 122
  if (mustInitUndistort)
123
    { // called once per calibration
124
 
125
      cv::initUndistortRectifyMap(cameraMatrix, // computed camera matrix
126
          distCoeffs, // computed distortion matrix
127
          cv::Mat(), // optional rectification (none)
128
          cv::Mat(), // camera matrix to generate undistorted
129
          cv::Size(640, 480),
3 PointedEar 130
//            image.size(),  // size of undistorted
5 PointedEar 131
          CV_32FC1,// type of output map
132
          map1, map2); // the x and y mapping functions
3 PointedEar 133
 
5 PointedEar 134
      mustInitUndistort = false;
135
    }
3 PointedEar 136
 
5 PointedEar 137
  // Apply mapping functions
138
  cv::remap(image, undistorted, map1, map2, cv::INTER_LINEAR); // interpolation type
3 PointedEar 139
 
5 PointedEar 140
  return undistorted;
3 PointedEar 141
}
142
 
143
// Set the calibration options
144
// 8radialCoeffEnabled should be true if 8 radial coefficients are required (5 is default)
145
// tangentialParamEnabled should be true if tangeantial distortion is present
5 PointedEar 146
void
147
CameraCalibrator::setCalibrationFlag(bool radial8CoeffEnabled,
148
    bool tangentialParamEnabled)
149
{
3 PointedEar 150
 
5 PointedEar 151
  // Set the flag used in cv::calibrateCamera()
152
  flag = 0;
153
  if (!tangentialParamEnabled)
154
    flag += CV_CALIB_ZERO_TANGENT_DIST;
155
  if (radial8CoeffEnabled)
156
    flag += CV_CALIB_RATIONAL_MODEL;
3 PointedEar 157
}
158