使用单应性描述两个图像之间的非线性变换

时间:2013-01-18 18:53:29

标签: image-processing computer-vision robotics camera-calibration projective-geometry

已经建立了一对一点匹配 在两个图像上的蓝点之间。 image2是image1的扭曲版本。失真模型似乎是 眼鱼眼镜畸变。问题是: 有没有办法计算描述这种转变的转换矩阵。 实际上是一个转换蓝色的矩阵 第一个图像上的点到第二个图像上的相应蓝点? 这里的问题是我们不知道焦距(意味着图像未经校准),但我们确实有 在两幅图像上大约200点之间完美匹配。 image1(original) 扭曲的图像: eimage2

1 个答案:

答案 0 :(得分:4)

我认为您尝试做的事情可以被视为失真校正问题,而无需经典相机校准的其余部分。

矩阵变换是线性变换,线性变换总是将直线映射成直线(http://en.wikipedia.org/wiki/Linear_map)。从图中可以明显看出,变换是非线性的,所以你不能用矩阵运算来描述它。

也就是说,你可以使用像OpenCV(http://docs.opencv.org/doc/tutorials/calib3d/camera_calibration/camera_calibration.html)那样使用的镜头失真模型,并且获得系数应该不是很困难。以下是您在Matlab中可以做的事情:

调用(x,y)原始点(顶部图片)和(xp,yp)坐标的失真点(底部图片)的坐标,两者都移动到图像的中心并除以缩放系数(x和y相同)所以它们或多或少地位于[-1,1]区间。失真模型是:

x = ( xp*(1 + k1*r^2 + k2*r^4 + k3*r^6) + 2*p1*xp*yp + p2*(r^2 + 2*xp^2));
y = ( yp*(1 + k1*r^2 + k2*r^4 + k3*r^6) + 2*p2*xp*yp + p1*(r^2 + 2*yp^2));

其中

r = sqrt(x^2 + y^2);

你有5个参数:k1,k2,k3,p1,p2用于径向和切向失真以及200对点,因此你可以求解非线性系统。

确保工作空间中存在x,y,xp和yp数组,并将它们声明为全局:

global x y xp yp

写一个函数来评估给定一组任意失真系数的均方误差,比如说它叫'dist':

function val = dist(var)

global x y xp yp

val = zeros(size(xp));

k1 = var(1);
k2 = var(2);
k3 = var(3);
p1 = var(4);
p2 = var(5);

r = sqrt(xp.*xp + yp.*yp);
temp1 = x - ( xp.*(1 + k1*r.^2 + k2*r.^4 + k3*r.^6) + 2*p1*xp.*yp + p2*(r.^2 + 2*xp.^2));
temp2 = y - ( yp.*(1 + k1*r.^2 + k2*r.^4 + k3*r.^6) + 2*p2*xp.*yp + p1*(r.^2 + 2*yp.^2));
val = sqrt(temp1.*temp1 + temp2.*temp2);

使用'fsolve'解决系统:

[coef, fval] = fsolve(@dist, zeros(5,1));

'coef'中的值是您正在寻找的失真系数。要纠正原始集中不存在的新点(xp,yp)的失真,请使用等式:

r = sqrt(xp.*xp + yp.*yp);
x_corr = xp.*(1 + k1*r.^2 + k2*r.^4 + k3*r.^6) + 2*p1*xp.*yp + p2*(r.^2 + 2*xp.^2);
y_corr = yp.*(1 + k1*r.^2 + k2*r.^4 + k3*r.^6) + 2*p2*xp.*yp + p1*(r.^2 + 2*yp.^2);

结果将移动到图像的中心,并按上面使用的因子进行缩放。

注意:

  • 由于失真相对于它是对称的,因此必须将坐标移动到图像的中心。
  • 没有必要对区间[-1,1]进行归一化,但是这样做可以使得所获得的失真系数大致相同的数量级(使用功率2,4和6像素坐标需要非常小的系数)。
  • 此方法不要求图像中的点位于统一网格中。