1
votes

I have obtained the camera calibration parameters such as camera matrix, distortion coeff, (rotation + translation) vector and image points using OpenCv code here.

The equation they used to compute the 2D screen coordinates is given by: enter image description here

By hard coding the obtained values for the camera matrix, rotation + translation vector and the object point coordinates (X,Y,Z,1) in Matlab, i'm unable to get the same coordinate values as the image points. What am I missing here? Do i need to account for the distortion coefficients too for obtaining the exact or correct image points?

Matlab Code:

% Define all the parameters camera matrix , sample image point, object point,   rotation and translation vectors%
cameraMatrix =  [5.9354 0 3.1950; 0 5.9354 2.3950 ; 0 0 1]
rotationMatrix = [2.5233 1.6803  3.0728];
translationMatrix = [1.2682 1.9657 8.0141];
X = [0; 0; 0; 1];

rotationMatrix = transpose(rotationMatrix);
translationMatrix = transpose(translationMatrix);

%convert the rotation vector into rotation matrix using Rodrigues func.%
rotMat = rodrigues(rotationMatrix);

R_T = horzcat(rotMat, translationMatrix)

%Convert to 2D points%
imgPts = cameraMatrix * R_T * X

lastElement = imgPts(end);

ScreenImgPts = imgPts / lastElement

The object points are defined by the square size of the chessboard square size (30mm), i.e. [0,0,0,1] , [30,0,0,1] etc.

However after my calculations and comparing the image points stored in the xml file are not the same. My results are as follows

  1. 4.1343 3.8508 [0, 0, 0, 1]
  2. 3.8373 1.0331 [30, 0, 0, 1]
  3. 3.8002 0.6812 [60, 0, 0, 1]

The output (image points) for the first point, second point and 3rd point should be:

  1. 4.13546326e+002 3.85645935e+002
  2. 3.91346527e+002 3.85897003e+002
  3. 3.69121155e+002 3.86479431e+002

The output file for all the parameters is given here

2

2 Answers

2
votes

The problem was very simple, i was rounding off the value for all the important parameters (camera matrix, rotation + translation) to the 4th digit whereas there was an exponent (e) clearly present towards the end of the values. Hence rounding off was resulting in incorrect values.

Here is the code with the corrected values

% Define all the parameters camera matrix , sample image point, object point, rotation and translation vectors%
cameraMatrix =  [5.9354136482375827e+002 0. 3.1950000000000000e+002; 0. 5.9354136482375827e+002 2.3950000000000000e+002 ; 0 0 1;]

%Rotatoin and translation vector of different planes (snapshot)%
rotationVector = [2.5233190617669338e-001 1.6802568443347082e-001  3.0727563215131681e+000];
translationVector = [1.2682348793063555e+002 1.9656574525587070e+002 8.0141048598043449e+002];

% rotationVector = [2.3492892819146791e-001 1.6451261910667694e-001 3.0787833660290516e+000];
% translationVector = [1.2806533156889765e+002 1.9877886039281353e+002 8.0447195879431570e+002];

% rotationVector = [2.1721 1.6300 3.0619];
% translationVector = [1.2661 1.9511 8.0681];

distCoeffs = [1.0829115704079707e-001 -1.0278232972256371e+000 0 0 1.7962320082487011e+000]; % k1, k2, p1, p2, k3 %

k1 = distCoeffs(1);
k2 = distCoeffs(2);
p1 = 0;
p2 = 0;
k3 = distCoeffs(end);


% X = [0 0 0; 30 0 0]

rotationVector = transpose(rotationVector);
translationVector = transpose(translationVector);


%convert the rotation vector into rotation matrix using Rodrigues func.%
rotMat = rodrigues(rotationVector)

R_T = horzcat(rotMat, translationVector)

%Convert to 2D points%
% imgPts = cameraMatrix * R_T * X
% 
% lastElement = imgPts(end)
% 
% ScreenImgPts = imgPts / lastElement

%%%%%%%%%%%%%% Adding calculation for distortion parameters%%%%%%%%%%

objectPoints = [0 0 0; 30 0 0; 60 0 0; 90 0 0; 120 0 0; 150 0 0;180 0 0; 
0 30 0; 30 30 0; 60 30 0; 90 30 0; 120 30 0; 150 30 0; 180 30 0;
0 60 0; 30 30 0; 60 60 0; 90 60 0; 120 60 0; 150 60 0; 180 60 0;
0 90 0; 30 30 0; 60 90 0; 90 90 0; 120 90 0; 150 90 0; 180 90 0;
0 120 0; 30 120 0; 60 120 0; 90 120 0; 120 120 0; 150 120 0; 180 120 0;]

Xelement = [];
screenCoords = [];
NormXY = [];

for i = 1:35
    Xelement = (objectPoints(i,:))
    NormXY(:,1) = (rotMat * transpose(Xelement)) + translationVector
    lastElement = NormXY(end)
    NormXY = NormXY / lastElement
    x = NormXY(1)
    y = NormXY(2)

    r2 = power(x,2) + power(y,2)
    r4 = power(r2,2)
    r6 = power(r2,3)

     xcorr = x * (1 + k1*r2 + k2*r4 + k3*r6)
     ycorr = y * (1 + k1*r2 + k2*r4 + k3*r6)

      XY = [xcorr ;ycorr;1]
      screenCoords(:,i) = cameraMatrix * XY


end
1
votes

Yes, you do need to account for distortion. Also, if you are working in MATLAB, it may be easier to use MATLAB's built in the Camera Calibrator App.