如何在Matlab中使用已知的相机参数对图像进行去畸变?

8

OpenCV中很容易实现,但我想要一个本地的Matlab实现,它应该是相当高效且易于更改的。该方法应该能够以上面链接中指定的摄像机参数作为输入。

2个回答

13

最简单也是最常见的消除镜头畸变(也称为去除图像畸变或补偿镜头畸变)的方法是对所选输出照片大小进行正向畸变,然后再使用双线性插值进行反向映射。

以下是我编写的执行此操作的代码:

function I = undistort(Idistorted, params)
fx = params.fx;
fy = params.fy;
cx = params.cx;
cy = params.cy;
k1 = params.k1;
k2 = params.k2;
k3 = params.k3;
p1 = params.p1;
p2 = params.p2;

K = [fx 0 cx; 0 fy cy; 0 0 1];

I = zeros(size(Idistorted));
[i j] = find(~isnan(I));

% Xp = the xyz vals of points on the z plane
Xp = inv(K)*[j i ones(length(i),1)]';

% Now we calculate how those points distort i.e forward map them through the distortion
r2 = Xp(1,:).^2+Xp(2,:).^2;
x = Xp(1,:);
y = Xp(2,:);

x = x.*(1+k1*r2 + k2*r2.^2) + 2*p1.*x.*y + p2*(r2 + 2*x.^2);
y = y.*(1+k1*r2 + k2*r2.^2) + 2*p2.*x.*y + p1*(r2 + 2*y.^2);

% u and v are now the distorted cooridnates
u = reshape(fx*x + cx,size(I));
v = reshape(fy*y + cy,size(I));

% Now we perform a backward mapping in order to undistort the warped image coordinates
I = interp2(Idistorted, u, v);

要使用它,需要知道所使用相机的相机参数。 我目前正在使用PMD CamboardNano,根据Cayim.com论坛上使用的参数为:

params = struct('fx',104.119, 'fy', 103.588, 'cx', 81.9494, 'cy', 59.4392, 'k1', -0.222609, 'k2', 0.063022, 'k3', 0, 'p1', 0.002865, 'p2', -0.001446);

I = undistort(Idistorted, params);

subplot(121); imagesc(Idistorted);
subplot(122); imagesc(I);

这是Camboard Nano的输出示例。注意:我人为地添加了边框线,以查看接近边缘的畸变效果(它更加明显):输入图像说明


你的函数支持哪些数据类型?我试了很多种,但都没成功...顺便说一句:感谢你提供这个函数,很奇怪Matlab没有实现它。 - Ander Biguri
@AnderBiguri 至少应该支持单通道类型 "double"。首先要做的是将任何图像转换为双精度。此外,如果您有一幅灰度图像或深度图像,则只需使用正确的参数调用undistort即可正常工作。如果您有一个3通道彩色图像,则需要在每个通道上分别进行去畸变处理。 - twerdster
它不能处理灰度位图,但我会将它们转换为双精度并尝试! - Ander Biguri

2

从R2013B版本开始,您现在可以使用计算机视觉系统工具箱来完成此操作。 有一个名为相机标定器的GUI应用程序和一个undistortImage函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接