Implement the camera calibration apply Robot

Posted at: THUrsday - 27/10/2016 10:04 - post name: SuperG
Iimplement the camera calibration

Iimplement the camera calibration

In this post, I will show you how to implement the camera calibration using method of Jie Zhao, Dong-Ming Yan, Guo-Zun Men and Ying-Kang Zhang according to their paper: A method of calibrating the intrinsic and extrinsic camera parameters separately for multi-camera system, issued in the Sixth International Conference Machine Learning and Cybernetics, Hong Kong, 19-22 August 2007.

Please be sure you understand the method before reading the next. You can find the concept of method by searching in the internet or just click here to download the paper. This post only care about the implementation!

1. Preparation
It is easy to do the following:
  - Set up a C/C++ compiler (Visual Studio, Eclipse CDT, DEV C++ ...)
  - Download the latest OpenCV library.
  - Download a math library, I suggest you to use Engen library. You can find it here.
  - Integrate all libray into your compiler.

2. Data collection
We use camera which need to be calibrated to capture the image contained 2 small balls. Each ball presents the point. 

B and C lie on a line and are observable points which can be detected by using the Hough transformation.
A is an unobservable point and it's position is calculated according to the position of B and C.
We will capture N (N = 100 for example) images and find N positions of B and C. These positions then will be written in a data file for the purpose of calibrating below.

Code for collecting data:




#include <...> ---> All neccessary headers!
 
cv::Point A(100, 100);  //You can use the Paint in Window to get the pos of A
 
// To ditermine where is B and where is C, we compare these positions by calculating the distances from each point to A.
 
double point_dist(cv::Point B)
{
    return sqrt((A.x - B.x)*(A.x - B.x) + (A.y - B.y)*(A.y - B.y));
}
//Read all images in a folder, calculate the position of B, C and store these in a file.
 
void data_collection(QString img_path)
{
    // I am using QT here to read image files in the folder, you can use others
      //like dirent.h ....
 
      cv::Mat src;
      ofstream data_file("data.txt");
      QDirIterator files(img_path);
    while(files.hasNext())
    {
        files.next();
        if(files.fileInfo().completeSuffix() == "bmp" ||
                               files.fileInfo().completeSuffix() == "jpg")
       {
          QString file = img_path + "\\" + files.fileName();
          src = cv::imread(file.toStdString(), CV_LOAD_IMAGE_GRAYSCALE)
std::vector<Vec3f> circles;
cv::HoughCircles(src, circles, CV_HOUGH_GRADIENT, 1, 
                           src_gray.rows/8, 200, 100, 0, 0 ); 
//We just desire to detect 2 circles. 
if(circles.size() != 2) continue;
cv::Point B(cvRound(circles[0][0], cvRound(circles[0][1]);
cv::Point C(cvRound(circles[1][0], cvRound(circles[1][1]); 
//Store these points in a file 
point_dist(B, A) > point_dist(C, A) ?
data_file << B : data_file << C;
data_file << "\n";

                }
          } 
     


data_file.close();

}

3. Calculate camera intrinsics.




std::vector<double> camera_intrinsic()
{
using namespace Eigen; 
  std::vector<double> results;  double u0, v0, anpha, beta, gamma;double Za;double L = 2.0;double la = 0.6;double lb = 0.4;double temp1, temp2;int i = 0, j = 0;  MatrixXd V(N,6);  MatrixXd Q(N,2);  VectorXd l(N);  VectorXd s(2);  double xb, yb, xc, yc;  Vector3d a(3), b(3), c(3), h(3);  VectorXd x;  VectorXd e = VectorXd::Ones(N);  double b11, b12, c11, c12;  std::ifstream file("data.txt");  while(file >> xb >> yb >> xc >> yc) {    Q.row(j) << yc - yb, xb - xc;    l(j) = xb*(yc - yb) + yb*(xb - xc);    j++;  }  file.close();  file.open("data.txt");  s = (Q.transpose()*Q).inverse()*Q.transpose()*l;  a<<s[0], s[1], 1;  if(file.is_open()){    while(file >> b11 >> b12 >> c11 >> c12) {      b<<b11, b12, 1;   c<<c11, c12, 1;      temp1 = (a.cross(c)).dot(b.cross(c));      temp2 = (b.cross(c)).dot(b.cross(c));      h = a + ((la*temp1)/(lb*temp2))*b;      V.row(i) << h(0)*h(0), 2*h(0)*h(1), h(1)*h(1),
                  2*h(0)*h(2), 2*h(1)*h(2), h(2)*h(2);      i++;    }  }x = (L*L)*((((V.transpose()*V).inverse())*V.transpose())*e);v0 = (x(1)*x(3) - x(0)*x(4))/(x(0)*x(2) - x(1)*x(1));Za = sqrt(x(5) - (x(3)*x(3) + v0*(x(1)*x(3) - x(0)*x(4)))/x(0));anpha = Za/sqrt(x(0));beta = Za*sqrt(fabs(x(0)/(x(0)*x(2) - x(1)*x(1))));gamma = -(x(1)*anpha*anpha*beta)/(Za*Za);u0 = v0*gamma/beta - x(3)*anpha*anpha/(Za*Za);results.push_back(u0); 
results.push_back(v0); 
results.push_back(anpha);
results.push_back(beta); 
results.push_back(gamma);return results;
 
} 

4. Calculate camera extrinsics


Chose 4 points according to your own real cordinate system to calculate the extrinsics of camera. It is simple, --->> no code for this section :)​

Article reviews
Total number of articles is: 0 in 0 rating
You click on a star to rate article
 

About us

About us HNRobot mainly focuses on the students eager to learn Robotics from Basic. They will get the chance to expand their knowledge in the field of designing, construction, operation, and application of Robot with real time hand on...