0
votes

I am recently new in OpenCV and I have been struggling to calibrate my camera. After a few days researching I have a basic understanding of it. But I still fail to understand some basic points.

1) The initialization of the objectpoint Matrix, why do we initialize this matrix in 0,0

Mat a = new MatOfPoint3f();
        for(int y=0; y<SIZE_Y; ++y) 
        {
            for(int x=0; x<SIZE_X; ++x)
            {
                points = new MatOfPoint3f(new Point3(x*distance_Board , y*distance_Board , 0));
                a.push_back(points);
            }
        }

Wouldn't it make more sense to initialize it where the board is in the 3D World for example

Mat a = new MatOfPoint3f();
        for(int y=1; y<=SIZE_Y; ++y) 
        {
            for(int x=1; x<=SIZE_X; ++x)
            {
                points = new MatOfPoint3f(new Point3(x*distance_Board + FirstPoint.x, y*distance_Board + FirstPoint.y, 0));
                a.push_back(points);
            }
        }

2)

I tried to calibrate my camera using

         Calib3d.calibrateCamera(object_points, corners, gray.size(), cameraMatrix, distCoeffs, rvecs, tvecs);

I have tried with more than 15 images but the results are still very poor , because i don't understand the significance of having a rvec and tvec for very image(I understand the logic, since for every point the rotation and translation is different) but how does it help us with other points/other images. I thought that the calibration provided us with a fair good method to translate 3d point into 2d points in the whole scene..

That's why when I run

        Calib3d.projectPoints(objectPoints, rvecs.get(i), tvecs.get(i), cameraMatrix, distCoeffs, imagePoints);

I really don't know which rvecs and tvecs to choose

3)

Is there a method to translate from 2D(imagePoints) into 3D(real World).I have tried this but the results are incorrect due to the incorrect parameters of calibration

4)

I have also tried to do the translation from 2D to 3D as follow

x ̃  =  x * ( 1 +  k1 * r^2 + k2 * r^4 ) + [ 2 p1 * x * y + p2 * ( r^2 + 2 * x^2 ) ] 

y ̃  =  y * ( 1 +  k1 * r^2 + k2 * r^4 ] + [ 2 p2 * x * y + p2 * ( r^2 + 2 * y^2 ) ],

a)But what is r? r = sqrt( x^2 + y^2 )? And x = (the x coordinate pixel) - (the camera center in pixels) ?

b) Is the camera center in pixel = cx = parameter of the camera matrix?

c) Is the x coordinate pixel = u = imagepoint?

There is a lot of information online but i have not found a 100% reliable source

I have run out of options, I would really apreciate if someone could give me a good explanation of the camera calibration or point me into the right direction(Papers etc).

Thank you in advance

2

2 Answers

1
votes

Do you ever wondered why do you have two eyes? In the most primitive sense, it is because only with both eyes we can have an idea of how far or near objects are. In some applications which need to recuperate 3D information it is made by using two cameras, this is called stereoscopy (http://en.wikipedia.org/wiki/Stereoscopy). If you are trying to depict 3D information using a single camera, you only can have a poor approximation, in this case its needed a transformation called homography (http://en.wikipedia.org/wiki/Homography), the last in order to try to model the perspective (or how far or near objects are). In most cases when we wanted to calibrate a single camera we try to remove the radial distortions produced by the lens of the camera (http://en.wikipedia.org/wiki/Distortion_%28optics%29). Opencv offers you a tool to do this process, in most cases its needed a Chess board to help this process, you can check this: http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html, in the spite of being more specific, the function cvFindChessboardCorners. I hope this could be useful to you, sorry for the english, no native speaker.

0
votes

I don't know if you already fixed your issue with the opnecv calibration but I will give you some hints anyway. First of all I suggest you to read the Zhang paper on calibration (http://research.microsoft.com/en-us/um/people/zhang/Papers/TR98-71.pdf). Opencv methods are based on Zhang's work so understanding it is a real priority. Calibrating a camera means determine the relation between camera 2D coordinate system (in pixel units, with the origin on top left corner of camera image) and the 3D coordinate systme of the external world (in metres, for example). When you place a known planar calibration object in front of the camera, the system should compute the homogeneous transformation between the knonw 3D object and the 2D one on image (that is the "rvecs.get(i), tvecs.get(i)" you are talking about). Image coordinates are always in pixel and also the intrinsic calibration matrix is expressed in pixel. You cannot "translate" from 2D image coordinates to 3D world coordinates but you can compute the proper transformation: it is composed by an intrinc calibration matrix and a roto-translation matrix. Please have a look also at this article http://research.microsoft.com/en-us/um/people/zhang/Papers/Camera%20Calibration%20-%20book%20chapter.pdf Hope this helps!