1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
#include<opencv\cv.h>
#include<opencv\highgui.h>
#include<stdlib.h>
#include<stdio.h>
#include<vector>
using namespace cv;
int main()
{
int numBoards = 0;
int numCornersHor;
int numCornersVer;
printf("Enter number of corners along width: ");
scanf("%d", &numCornersHor);
printf("Enter number of corners along height: ");
scanf("%d", &numCornersVer);
printf("Enter number of boards: ");
scanf("%d", &numBoards);
int numSquares = numCornersHor * numCornersVer;
Size board_sz = Size(numCornersHor, numCornersVer);
VideoCapture capture = VideoCapture(0);
vector<vector<Point3f>> object_points; //physical position of the corners in 3d space. this has to be measured by us
vector<vector<Point2d>> image_points; //location of corners on in the image (2d) once the program has actual physical locations and locations
//on the image, it can calculate the relation between the two.
//create list of corners. temporary hold the current snapshot's chessboard corners. also declare variable that will keep a track
// of successfully capturing a chessboard and saving it into the lists we declared above.
vector<Point2f> corners;
int successes=0;
Mat image;
Mat gray_image;
capture >> image;
//Next, we do a little hack with object_points. Ideally, it should contain the physical position of each corner.
//The most intuitive way would be to measure distances “from” the camera lens. That is, the camera is the origin and
//the chessboard has been displaced.
//can set chessboard on someplace (like xy plane or xz plane), easier to do second one we just assign a constant position
//to each vertex.
vector<Point3f> obj;
for(int j=0; j<numSquares; j++)
obj.push_back(Point3f(j/numCornersHor, j%numCornersHor, 0)); //this creates a list of coordinates (0,0,0),(0,1,0)
//(0,2,0) ... (1,4,0) .. so on. Each corresponds to a particular vertex
while(successes<numBoards)
{
//convert image to grayscale
cvtColor(image,gray_image, CV_BGR2GRAY);
bool found = findChessboardCorners(image, board_sz, corners, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS);
if(found)
{
cornerSubPix(gray_image, corners, Size(11, 11), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 30, 0.1));
drawChessboardCorners(gray_image, board_sz, corners, found);
}
imshow("win1", image);
imshow("win2", gray_image);
capture>>image;
int key = waitKey(1);
if(key=27)
return 0;
if(key==' ' && found!=0)
{
image_points.push_back(corners);
object_points.push_back(obj);
printf("Snap stored!\n");
successes++;
if(successes>=numBoards)
break;
}
}
//next we get ready to do the calibration, we declare variables that will hold the unknowns:
Mat intrinsic = Mat(3, 3, CV_32FC1);
Mat distCoeffs;
vector<Mat> rvecs;
vector<Mat> tvecs;
//modify intrinsic matrix with whatever we know. camera spect ration is 1 (that's usually the case.. if not change it as required
intrinsic.ptr<float>(0)[0] = 1;
intrinsic.ptr<float>(1)[1] = 1;
//(0,0) and (1,1) are focal lengths along x and y axis
//now finally the calibration
calibrateCamera(object_points, image_points, image.size(),intrinsic, distCoeffs, rvecs, tvecs);
//after this you will have the intrinsic matrix, distortion coefficients and the rotation + translation vectors.
//intrinsic matrix and distortion coeffs are property of the camera and lens. so if you don't change it focal lengths zoom lenses you
//can reuse it.
//now we have distortion coeffcients we can undistor the images, using a loop will do this
Mat imageUndistorted;
while(1)
{
capture >> image;
undistort(image, imageUndistorted, intrinsic, distCoeffs);
imshow("win1", image);
imshow("win2", imageUndistorted);
waitKey(1);
}
//finally we'll release the camera and quit
capture.release();
return 0;
}
|