两个图像上的蓝点之间已经建立了一对一的匹配。image2 是 image1 的变形版本。失真模型似乎是鱼眼镜头失真。问题是:有没有办法计算一个描述这种转变的变换矩阵。实际上是将第一张图像上的蓝点转换为第二张图像上对应的蓝点的矩阵?这里的问题是我们不知道焦距(意味着图像未校准),但是我们确实在两张图像上的大约 200 个点之间完美匹配。 扭曲的图像:
1 回答
我认为您尝试做的事情可以被视为失真校正问题,而不需要其他经典相机校准。
矩阵变换是一种线性变换,线性变换总是将直线映射成直线(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 次幂)坐标需要非常小的系数)。
- 这种方法不需要图像中的点在一个统一的网格中。