After performing stereo calibration using a checkerboard, the same checkerboard is reconstructed in 3D. I have several questions regarding the results.
Currently, I am facing three issues related to 3D reconstruction. As shown in the first attached image, I describe the x-axis as positive to the right and the y-axis as positive upwards (since the checkerboard is planar, I will not consider the z-axis in this question). The green plots mean the ground truth, and the red plots mean reconstructed values in the first attached image.
When considering the detected checkerboard corner points in the same x×y layout as the premise, the ground truth is detected and plotted as 8×11, while the reconstructed values are detected and plotted as 10×7. Why is there a difference of one cell in the detected grid? Please refer to the attached checkerboard image for this situation.
As seen in the attached image, the long side of the ground truth checkerboard is aligned along the y-axis direction, while the long side of the reconstructed checkerboard appears to be aligned along the x-axis direction. Why does it seem like the long side’s position has rotated during reconstruction?
The first detected corner point of the reconstructed values should be located at the same origin as the first detected corner point of the ground truth, but it is located in a different position. What is the cause of this? Is this due to low accuracy in the camera parameters, or is it because the reconstructed values and the ground truth are represented in different coordinate systems? Could there be other reasons for this?
The specific causes for the second and third questions might be the same, but I appreciate your response. For reference, I am attaching the code as well.
% Loading stereo images
I1 = imread(‘/Users/uchidataisei/dev/uchida/kenkyu_data/2024-06-14/C3/GX010541_frames/frame0052.png’); % 左画像
I2 = imread(‘/Users/uchidataisei/dev/uchida/kenkyu_data/2024-06-14/C2/GX010611_frames/frame0052.png’); % 右画像
% Using pre-obtained calibration parameters
load(‘/Users/uchidataisei/dev/uchida/MATLAB_data/2024_06_14/calibrationSession_0614_C3_2_.mat’);
% Rectification
% [J1, J2, reprojectionMatrix] = rectifyStereoImages(I1, I2, stereoParams_0614_C3_2);
[J1, J2, reprojectionMatrix] = rectifyStereoImages(I1, I2, stereoParams_0614_C3_2_);
% Calculating the disparity map
disparityMap = disparitySGM(rgb2gray(J1), rgb2gray(J2));
% Reconstructing the 3D scene
points3D = reconstructScene(disparityMap, reprojectionMatrix);
% Setting the ground truth of the checkerboard, [mm]
squareSize = 114;
% Detecting the corners of the checkerboard
[imagePoints, boardSize] = detectCheckerboardPoints(J1);
% Calculating the ground truth grid of the checkerboard
[worldX, worldY] = meshgrid(0:squareSize:((boardSize(1)-1)*squareSize), 0:squareSize:((boardSize(2)-1)*squareSize));
worldPoints = [worldX(:), worldY(:), zeros(numel(worldX), 1)]; % Z=0
% Matching the number of detected corners with the number of ground truth points
% if size(worldPoints, 1) > size(imagePoints, 1)
% worldPoints = worldPoints(1:size(imagePoints, 1), :);
% elseif size(worldPoints, 1) < size(imagePoints, 1)
% error(‘The number of ground truth points is less than the number of detected corners. Please check the number of ground truth points.’);
% end
% Extracting the 3D points of the reconstructed checkerboard corners
detected3DPoints = zeros(size(imagePoints, 1), 3);
validIndices = true(size(imagePoints, 1), 1);
for i = 1:size(imagePoints, 1)
x = round(imagePoints(i, 1));
y = round(imagePoints(i, 2));
if x > 0 && y > 0 && x <= size(points3D, 2) && y <= size(points3D, 1)
detected3DPoints(i, 🙂 = points3D(y, x, :);
if any(isnan(detected3DPoints(i, :)) | isinf(detected3DPoints(i, :)))
validIndices(i) = false;
end
else
validIndices(i) = false;
end
end
% Excluding invalid points
% detected3DPoints = detected3DPoints(validIndices, :); %Reconstructed grid
% worldPoints = worldPoints(validIndices, :); %Ground truth grid
% Omitting scale transformation
detected3DPoints_mm = detected3DPoints;
% Comparison of ground truth and reconstructed results
figure;
plot3(worldPoints(:,1), worldPoints(:,2), worldPoints(:,3), ‘go’);
hold on;
plot3(detected3DPoints_mm(:,1), detected3DPoints_mm(:,2), detected3DPoints_mm(:,3), ‘rx’);
% Displaying numbers on each plot
for i = 1:size(worldPoints, 1)
text(worldPoints(i, 1), worldPoints(i, 2), worldPoints(i, 3), num2str(i), ‘Color’, ‘green’);
text(detected3DPoints_mm(i, 1), detected3DPoints_mm(i, 2), detected3DPoints_mm(i, 3), num2str(i), ‘Color’, ‘red’);
end
legend(‘True Points’, ‘Reconstructed Points’);
xlabel(‘X (mm)’);
ylabel(‘Y (mm)’);
zlabel(‘Z (mm)’);
title(‘Comparison of True and Reconstructed Points’);
grid on;
% Calculating the error
errors_xy = sqrt(sum((worldPoints(:, 1:2) – detected3DPoints_mm(:, 1:2)).^2, 2));
meanError_xy = mean(errors_xy);
disp([‘Mean Error in XY plane: ‘, num2str(meanError_xy), ‘ millimeters’]);Currently, I am facing three issues related to 3D reconstruction. As shown in the first attached image, I describe the x-axis as positive to the right and the y-axis as positive upwards (since the checkerboard is planar, I will not consider the z-axis in this question). The green plots mean the ground truth, and the red plots mean reconstructed values in the first attached image.
When considering the detected checkerboard corner points in the same x×y layout as the premise, the ground truth is detected and plotted as 8×11, while the reconstructed values are detected and plotted as 10×7. Why is there a difference of one cell in the detected grid? Please refer to the attached checkerboard image for this situation.
As seen in the attached image, the long side of the ground truth checkerboard is aligned along the y-axis direction, while the long side of the reconstructed checkerboard appears to be aligned along the x-axis direction. Why does it seem like the long side’s position has rotated during reconstruction?
The first detected corner point of the reconstructed values should be located at the same origin as the first detected corner point of the ground truth, but it is located in a different position. What is the cause of this? Is this due to low accuracy in the camera parameters, or is it because the reconstructed values and the ground truth are represented in different coordinate systems? Could there be other reasons for this?
The specific causes for the second and third questions might be the same, but I appreciate your response. For reference, I am attaching the code as well.
% Loading stereo images
I1 = imread(‘/Users/uchidataisei/dev/uchida/kenkyu_data/2024-06-14/C3/GX010541_frames/frame0052.png’); % 左画像
I2 = imread(‘/Users/uchidataisei/dev/uchida/kenkyu_data/2024-06-14/C2/GX010611_frames/frame0052.png’); % 右画像
% Using pre-obtained calibration parameters
load(‘/Users/uchidataisei/dev/uchida/MATLAB_data/2024_06_14/calibrationSession_0614_C3_2_.mat’);
% Rectification
% [J1, J2, reprojectionMatrix] = rectifyStereoImages(I1, I2, stereoParams_0614_C3_2);
[J1, J2, reprojectionMatrix] = rectifyStereoImages(I1, I2, stereoParams_0614_C3_2_);
% Calculating the disparity map
disparityMap = disparitySGM(rgb2gray(J1), rgb2gray(J2));
% Reconstructing the 3D scene
points3D = reconstructScene(disparityMap, reprojectionMatrix);
% Setting the ground truth of the checkerboard, [mm]
squareSize = 114;
% Detecting the corners of the checkerboard
[imagePoints, boardSize] = detectCheckerboardPoints(J1);
% Calculating the ground truth grid of the checkerboard
[worldX, worldY] = meshgrid(0:squareSize:((boardSize(1)-1)*squareSize), 0:squareSize:((boardSize(2)-1)*squareSize));
worldPoints = [worldX(:), worldY(:), zeros(numel(worldX), 1)]; % Z=0
% Matching the number of detected corners with the number of ground truth points
% if size(worldPoints, 1) > size(imagePoints, 1)
% worldPoints = worldPoints(1:size(imagePoints, 1), :);
% elseif size(worldPoints, 1) < size(imagePoints, 1)
% error(‘The number of ground truth points is less than the number of detected corners. Please check the number of ground truth points.’);
% end
% Extracting the 3D points of the reconstructed checkerboard corners
detected3DPoints = zeros(size(imagePoints, 1), 3);
validIndices = true(size(imagePoints, 1), 1);
for i = 1:size(imagePoints, 1)
x = round(imagePoints(i, 1));
y = round(imagePoints(i, 2));
if x > 0 && y > 0 && x <= size(points3D, 2) && y <= size(points3D, 1)
detected3DPoints(i, 🙂 = points3D(y, x, :);
if any(isnan(detected3DPoints(i, :)) | isinf(detected3DPoints(i, :)))
validIndices(i) = false;
end
else
validIndices(i) = false;
end
end
% Excluding invalid points
% detected3DPoints = detected3DPoints(validIndices, :); %Reconstructed grid
% worldPoints = worldPoints(validIndices, :); %Ground truth grid
% Omitting scale transformation
detected3DPoints_mm = detected3DPoints;
% Comparison of ground truth and reconstructed results
figure;
plot3(worldPoints(:,1), worldPoints(:,2), worldPoints(:,3), ‘go’);
hold on;
plot3(detected3DPoints_mm(:,1), detected3DPoints_mm(:,2), detected3DPoints_mm(:,3), ‘rx’);
% Displaying numbers on each plot
for i = 1:size(worldPoints, 1)
text(worldPoints(i, 1), worldPoints(i, 2), worldPoints(i, 3), num2str(i), ‘Color’, ‘green’);
text(detected3DPoints_mm(i, 1), detected3DPoints_mm(i, 2), detected3DPoints_mm(i, 3), num2str(i), ‘Color’, ‘red’);
end
legend(‘True Points’, ‘Reconstructed Points’);
xlabel(‘X (mm)’);
ylabel(‘Y (mm)’);
zlabel(‘Z (mm)’);
title(‘Comparison of True and Reconstructed Points’);
grid on;
% Calculating the error
errors_xy = sqrt(sum((worldPoints(:, 1:2) – detected3DPoints_mm(:, 1:2)).^2, 2));
meanError_xy = mean(errors_xy);
disp([‘Mean Error in XY plane: ‘, num2str(meanError_xy), ‘ millimeters’]); Currently, I am facing three issues related to 3D reconstruction. As shown in the first attached image, I describe the x-axis as positive to the right and the y-axis as positive upwards (since the checkerboard is planar, I will not consider the z-axis in this question). The green plots mean the ground truth, and the red plots mean reconstructed values in the first attached image.
When considering the detected checkerboard corner points in the same x×y layout as the premise, the ground truth is detected and plotted as 8×11, while the reconstructed values are detected and plotted as 10×7. Why is there a difference of one cell in the detected grid? Please refer to the attached checkerboard image for this situation.
As seen in the attached image, the long side of the ground truth checkerboard is aligned along the y-axis direction, while the long side of the reconstructed checkerboard appears to be aligned along the x-axis direction. Why does it seem like the long side’s position has rotated during reconstruction?
The first detected corner point of the reconstructed values should be located at the same origin as the first detected corner point of the ground truth, but it is located in a different position. What is the cause of this? Is this due to low accuracy in the camera parameters, or is it because the reconstructed values and the ground truth are represented in different coordinate systems? Could there be other reasons for this?
The specific causes for the second and third questions might be the same, but I appreciate your response. For reference, I am attaching the code as well.
% Loading stereo images
I1 = imread(‘/Users/uchidataisei/dev/uchida/kenkyu_data/2024-06-14/C3/GX010541_frames/frame0052.png’); % 左画像
I2 = imread(‘/Users/uchidataisei/dev/uchida/kenkyu_data/2024-06-14/C2/GX010611_frames/frame0052.png’); % 右画像
% Using pre-obtained calibration parameters
load(‘/Users/uchidataisei/dev/uchida/MATLAB_data/2024_06_14/calibrationSession_0614_C3_2_.mat’);
% Rectification
% [J1, J2, reprojectionMatrix] = rectifyStereoImages(I1, I2, stereoParams_0614_C3_2);
[J1, J2, reprojectionMatrix] = rectifyStereoImages(I1, I2, stereoParams_0614_C3_2_);
% Calculating the disparity map
disparityMap = disparitySGM(rgb2gray(J1), rgb2gray(J2));
% Reconstructing the 3D scene
points3D = reconstructScene(disparityMap, reprojectionMatrix);
% Setting the ground truth of the checkerboard, [mm]
squareSize = 114;
% Detecting the corners of the checkerboard
[imagePoints, boardSize] = detectCheckerboardPoints(J1);
% Calculating the ground truth grid of the checkerboard
[worldX, worldY] = meshgrid(0:squareSize:((boardSize(1)-1)*squareSize), 0:squareSize:((boardSize(2)-1)*squareSize));
worldPoints = [worldX(:), worldY(:), zeros(numel(worldX), 1)]; % Z=0
% Matching the number of detected corners with the number of ground truth points
% if size(worldPoints, 1) > size(imagePoints, 1)
% worldPoints = worldPoints(1:size(imagePoints, 1), :);
% elseif size(worldPoints, 1) < size(imagePoints, 1)
% error(‘The number of ground truth points is less than the number of detected corners. Please check the number of ground truth points.’);
% end
% Extracting the 3D points of the reconstructed checkerboard corners
detected3DPoints = zeros(size(imagePoints, 1), 3);
validIndices = true(size(imagePoints, 1), 1);
for i = 1:size(imagePoints, 1)
x = round(imagePoints(i, 1));
y = round(imagePoints(i, 2));
if x > 0 && y > 0 && x <= size(points3D, 2) && y <= size(points3D, 1)
detected3DPoints(i, 🙂 = points3D(y, x, :);
if any(isnan(detected3DPoints(i, :)) | isinf(detected3DPoints(i, :)))
validIndices(i) = false;
end
else
validIndices(i) = false;
end
end
% Excluding invalid points
% detected3DPoints = detected3DPoints(validIndices, :); %Reconstructed grid
% worldPoints = worldPoints(validIndices, :); %Ground truth grid
% Omitting scale transformation
detected3DPoints_mm = detected3DPoints;
% Comparison of ground truth and reconstructed results
figure;
plot3(worldPoints(:,1), worldPoints(:,2), worldPoints(:,3), ‘go’);
hold on;
plot3(detected3DPoints_mm(:,1), detected3DPoints_mm(:,2), detected3DPoints_mm(:,3), ‘rx’);
% Displaying numbers on each plot
for i = 1:size(worldPoints, 1)
text(worldPoints(i, 1), worldPoints(i, 2), worldPoints(i, 3), num2str(i), ‘Color’, ‘green’);
text(detected3DPoints_mm(i, 1), detected3DPoints_mm(i, 2), detected3DPoints_mm(i, 3), num2str(i), ‘Color’, ‘red’);
end
legend(‘True Points’, ‘Reconstructed Points’);
xlabel(‘X (mm)’);
ylabel(‘Y (mm)’);
zlabel(‘Z (mm)’);
title(‘Comparison of True and Reconstructed Points’);
grid on;
% Calculating the error
errors_xy = sqrt(sum((worldPoints(:, 1:2) – detected3DPoints_mm(:, 1:2)).^2, 2));
meanError_xy = mean(errors_xy);
disp([‘Mean Error in XY plane: ‘, num2str(meanError_xy), ‘ millimeters’]); #reconstructscene, stereoparameters, detectcheckerboardpoints, 3d reconstruction MATLAB Answers — New Questions