2017年2月23日 星期四

使用OpenCv實作攝影機校正(內部參數、外部參數)

開發環境 : Visual studio 2012 、Win10、OpenCv 2.4.7

平台 : x64

屬性 :  VC++目錄 - Include目錄: C:\opencv\build\include
                                                        C:\opencv\build\include\opencv
                                                        C:\opencv\build\include\opencv2

                               -程式庫目錄 : C:\opencv\build\x64\vc11\lib
                                                 
           連結器        -其他相依性: opencv_core247d.lib
                                                     opencv_imgproc247d.lib
                                                     opencv_highgui247d.lib
                                                     opencv_ml247d.lib
                                                     opencv_video247d.lib
                                                     opencv_features2d247d.lib
                                                     opencv_calib3d247d.lib
                                                     opencv_objdetect247d.lib
                                                     opencv_contrib247d.lib
                                                     opencv_legacy247d.lib
                                                     opencv_flann247d.lib
                                                     opencv_nonfree247d.lib



#include <opencv2/opencv.hpp>

#include <opencv2\highgui\highgui.hpp>

#include <iostream>

#include <stdio.h>

#include <iomanip>
using namespace std;
using namespace cv;

//Camera Calibration
vector<vector<double>> r_side;
vector<vector<double>> t_side;
Mat rotation_side;
Mat translation_side;
Mat extrinsicMat_side;
Mat intrinsicMat_side;
Mat distCoeffs_side;
Size boardSize; // The size of the board -> Number of items by width and height
    float squareSize; // The size of a square in your defined unit (point, millimeter,etc).
int numFrameUse; // number of frame to use for calibration
vector<string> Cali_imageList;
bool Cali_flag = false;
void calibrate();
//Find corners
vector<vector<Point2f>> chessBoardPoints_side;
//Camera Calibration

int main(){
// Calibration
boardSize.width = 11;
boardSize.height = 8;
squareSize = 1.0;
numFrameUse = 21;
Cali_imageList.clear();
Cali_imageList.push_back("Database/1.bmp"); //圖存在專案資料夾/Database資料夾中
Cali_imageList.push_back("Database/2.bmp");
Cali_imageList.push_back("Database/3.bmp");
Cali_imageList.push_back("Database/4.bmp");
Cali_imageList.push_back("Database/5.bmp");
Cali_imageList.push_back("Database/6.bmp");
Cali_imageList.push_back("Database/7.bmp");
Cali_imageList.push_back("Database/8.bmp");
Cali_imageList.push_back("Database/9.bmp");
Cali_imageList.push_back("Database/10.bmp");
Cali_imageList.push_back("Database/11.bmp");
Cali_imageList.push_back("Database/12.bmp");
Cali_imageList.push_back("Database/13.bmp");
Cali_imageList.push_back("Database/14.bmp");
Cali_imageList.push_back("Database/15.bmp");
Cali_imageList.push_back("Database/16.bmp");
Cali_imageList.push_back("Database/17.bmp");
Cali_imageList.push_back("Database/18.bmp");
Cali_imageList.push_back("Database/19.bmp");
Cali_imageList.push_back("Database/20.bmp");
Cali_imageList.push_back("Database/21.bmp");
// vectors for chessboard corners in both image frame and object frame
vector<vector<Point2f> > imagePoints;
imagePoints.clear();
vector<vector<Point3f>> objectPoints;
Size imageSize = imread(Cali_imageList[0]).size();
vector<Point2f> corners;

// find the chessboard corners
cout << "Find the chessboard corners." << endl;
for (int idx=0; idx < Cali_imageList.size() ; idx++)
{
Mat Img = imread(Cali_imageList[idx], CV_LOAD_IMAGE_GRAYSCALE);
corners.clear();
bool isFound = findChessboardCorners( Img, boardSize, corners,
CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FAST_CHECK | CV_CALIB_CB_NORMALIZE_IMAGE);
// use subpixel precise
if (isFound)
{

cornerSubPix( Img, corners, Size(5,5),
 Size(-1,-1), TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1 ));
cout << "num : " << idx+1 << endl;
//imshow("imageList",imread(imageList[i], 0));
imagePoints.push_back(corners);
}
else
cout << "num : " << idx+1 << "Missed!!!"<< endl;
}

// calculate the corners in object frame
vector<Point3f> objectCorners;
for (int idx=0; idx < imagePoints.size(); idx++)
{
objectCorners.clear();
for(int jdx = 0; jdx < boardSize.height; jdx++ )
  for(int kdx = 0; kdx < boardSize.width; kdx++ )
  objectCorners.push_back(Point3f(kdx*squareSize, jdx*squareSize, 0));
objectPoints.push_back(objectCorners);
}

// set the calibration flag and do calibration
cout << "Calibrating....Please wait...." << endl;
calibrateCamera(objectPoints, imagePoints, imageSize, intrinsicMat_side, distCoeffs_side, r_side, t_side);
cout << "Calibration Finished." << endl << endl;
Cali_flag = true;

//find chess board point
chessBoardPoints_side = imagePoints;
if(Cali_flag)
{
cout << fixed << setprecision(6) <<"Intrinsic Matrix : " << endl << "[";
for(int row=0; row<3; row++)
{
for(int col=0; col<3; col++)
{
cout << intrinsicMat_side.at<double>(row,col);
if(col!=2)
cout << ", " ;
}
if(row!=2)
cout << ";" << endl;
else
cout << "]" << endl << endl;
}
// Convert rotation vector to rotation matrix
Rodrigues(r_side[0], rotation_side);
// Build extrinsic parameter matrix
extrinsicMat_side = Mat(3, 4, CV_64F);
translation_side = Mat(3, 1, CV_64F);
for (int idx=0; idx<3; idx++)
for (int jdx=0; jdx<3; jdx++)
extrinsicMat_side.at<double>(idx, jdx) = rotation_side.at<double>(idx, jdx);
for (int idx=0; idx<3; idx++)
translation_side.at<double>(idx) = t_side[0][idx];
for (int idx=0; idx<3; idx++)
extrinsicMat_side.at<double>(idx, 3) = translation_side.at<double>(idx);

cout << fixed << setprecision(6) <<"Extrinsic Matrix : " << endl << "[";
for(int row=0; row<3; row++)
{
for(int col=0; col<4; col++)
{
cout << extrinsicMat_side.at<double>(row,col);
if(col!=3)
cout << ", " ;
}
if(row!=2)
cout << ";" << endl;
else
cout << "]" << endl << endl;
}
cout << fixed << setprecision(6) <<"Distortion Matrix : " << endl << "[";
for(int row=0; row<1; row++)
{
for(int col=0; col<5; col++)
{
cout << distCoeffs_side.at<double>(row,col);
if(col!=4)
cout << ", " ;
}
if(row!=0)
cout << ";" << endl;
else
cout << "]" << endl << endl;
}
}
getchar();
}

沒有留言:

張貼留言