【发布时间】:2020-11-28 11:35:29
【问题描述】:
我正在尝试重新创建立体校正算法(不使用任何库)。
我已经使用 MATLAB 校准了立体摄像机装置。使用MATLAB内置的立体校正算法,我得到usable rectified images。
我当前的实现(使用与 MATLAB 算法相同的校准结果)生成的图像为 slightly off(相应的特征未水平对齐)。供参考,给出a cropped anaglyph of the undistorted images。
左图修正代码:
load('calibration.mat');%load stereoParams
leftImages = imageDatastore('captures\left\');
distortedImage = readimage(leftImages, 1);
kL = stereoParams.CameraParameters1.IntrinsicMatrix';
k1 = stereoParams.CameraParameters1.RadialDistortion(1);
k2 = stereoParams.CameraParameters1.RadialDistortion(2);
translation = stereoParams.TranslationOfCamera2 .* [-1 -1 1]; %translation vector according to initial left camera frame
e1 = translation / norm(translation);
e2 = [-translation(2), translation(1), 0] / norm(translation(1:2));
e3 = cross(e1, e2);
transform = kL * [e1; e2; e3] / kL;
rectifiedImage(1 : 1000, 1 : 1000) = 0;
for r = 1 : 1000
for c = 1 : 1000
undistortedCoord = eye(3) / kL / transform * [c - 1; r - 1; 1]; %map the rectified coordinate to its corresponding unrectified coordinate
undistortedCoord = undistortedCoord / undistortedCoord(3); %normalize unrectified coordinate with respect to its homogeneous component
radius = sqrt(undistortedCoord(1) ^ 2 + undistortedCoord(2) ^ 2); %compute distance from image plane principal point
distortedCoord = [undistortedCoord(1:2) * (1 + k1 * radius ^ 2 + k2 * radius ^ 4); 1]; %compute distorted coordinate from lens distortion coefficients
imageCoord = kL * distortedCoord; %map the distorted coordinate into the distorted image
if (imageCoord(1) > 0 && imageCoord(2) > 0 && imageCoord(1) < size(distortedImage, 2) - 1 && imageCoord(2) < size(distortedImage, 1) - 1)
rectifiedImage(r, c) = double(distortedImage(round(imageCoord(2) + 1), round(imageCoord(1) + 1))) / 255;
end
end
end
imwrite(rectifiedImage, 'rectifiedL.png');
右图修正代码:
load('calibration.mat');%load stereoParams
rightImages = imageDatastore('captures\right\');
distortedImage = readimage(rightImages, 1);
kL = stereoParams.CameraParameters1.IntrinsicMatrix';
kR = stereoParams.CameraParameters2.IntrinsicMatrix';
k1 = stereoParams.CameraParameters2.RadialDistortion(1);
k2 = stereoParams.CameraParameters2.RadialDistortion(2);
translation = stereoParams.TranslationOfCamera2 .* [-1 -1 1]; %translation vector according to initial left camera frame
e1 = translation / norm(translation);
e2 = [-translation(2), translation(1), 0] / norm(translation(1:2));
e3 = cross(e1, e2);
transform = kL * [e1; e2; e3] * stereoParams.RotationOfCamera2 / kR;
rectifiedImage(1 : 1000, 1 : 1000) = 0;
for r = 1 : 1000
for c = 1 : 1000
undistortedCoord = eye(3) / kR / transform * [c - 1; r - 1; 1]; %map the rectified coordinate to its corresponding unrectified coordinate
undistortedCoord = undistortedCoord / undistortedCoord(3); %normalize unrectified coordinate with respect to its homogeneous component
radius = sqrt(undistortedCoord(1) ^ 2 + undistortedCoord(2) ^ 2); %compute distance from image plane principal point
distortedCoord = [undistortedCoord(1:2) * (1 + k1 * radius ^ 2 + k2 * radius ^ 4); 1]; %compute distorted coordinate from lens distortion coefficients
imageCoord = kR * distortedCoord; %map the distorted coordinate into the distorted image
if (imageCoord(1) > 0 && imageCoord(2) > 0 && imageCoord(1) < size(distortedImage, 2) - 1 && imageCoord(2) < size(distortedImage, 1) - 1)
rectifiedImage(r, c) = double(distortedImage(round(imageCoord(2) + 1), round(imageCoord(1) + 1))) / 255;
end
end
end
imwrite(rectifiedImage, 'rectifiedR.png');
除了应用的单应性之外,这些代码块是相同的。
MATLAB 的立体校正算法基于Bouguet's Algorithm,而我的基于slightly different algorithm,所以我不希望得到相同的结果,但我仍然相信我应该得到有效的校正图像。
我尝试了多种变体(负平移向量、转置旋转矩阵、不同的输出固有矩阵、不同阶的矩阵乘法等),但我无法产生任何有效的结果。根据我使用的算法,我应该颠倒旋转矩阵乘法的顺序,但这样做只会垂直移动右图像,因此会增加错位。我最初虽然图像的比例略有不同,但当在两个图像上使用相同的输出内在矩阵时,这肯定是不可能的。平移向量已按元素乘以 [-1 -1 1] 以匹配 MATLAB 校准工具中显示的左侧相机坐标系。我尝试过其他变体,例如 [-1 -1 -1]、[1 1 1] 等,如果某些矩阵被转置,它们可以给出类似的结果,但是,没有一个给出有效的纠正。
当我使用 MATLAB 内部生成的单应性时,我得到了有效的结果,我的单应性有什么问题?
【问题讨论】: