zka*_*oca 4 matlab image image-processing matrix computer-vision
我有两个图像,其中一个是原始图像,第二个是转换图像.
我必须找出使用3x3变换矩阵旋转了多少度转换图像.另外,我需要找到从原点翻译的距离.
两个图像都被灰度化并保存在矩阵变量中.它们的尺寸相同[350 500].
我找到了一些像这样的讲义.
讲义说我应该使用以下矩阵公式进行轮换:

对于翻译矩阵,给出了公式:

一切都是好的.但是有两个问题:
x',y'价值观,但我已经得到了x,x',y,y'值.我需要找到旋转角度(θ)tx和ty.x,x',y,y'在矩阵.我有以下代码:
rotationMatrix = [ cos(theta) sin(theta) 0 ; ...
-sin(theta) cos(theta) 0 ; ...
0 0 1];
translationMatrix = [ 1 0 tx; ...
0 1 ty; ...
0 0 1];
Run Code Online (Sandbox Code Playgroud)
但正如您所看到的,tx,ty,theta变量在使用之前未定义.我该如何计算theta,tx和ty?
PS:禁止使用图像处理工具箱功能.
这基本上是单应性恢复问题.您正在做的是在一个图像中给出坐标,在另一个图像中给出相应的坐标,您正在尝试恢复用于将点从一个图像扭曲到另一个图像的组合平移和旋转矩阵.
您可以通过将两个矩阵相乘来将旋转和平移组合成单个矩阵.乘法只是将两个操作合成在一起.你会得到:
H = [cos(theta) -sin(theta) tx]
[sin(theta) cos(theta) ty]
[ 0 0 1]
Run Code Online (Sandbox Code Playgroud)
这背后的想法是通过最小化每对点之间的最小二乘误差来找到参数.
基本上,你想要找到的是以下关系:
xi_after = H*xi_before
Run Code Online (Sandbox Code Playgroud)
H是将坐标从一个图像映射到另一个图像所需的组合旋转和平移矩阵. H也是一个3 x 3矩阵,并且知道右下方的条目(第3行,第3列)是1,它使事情变得更容易.此外,假设您的点位于增强坐标系中,我们基本上希望找到从第一张图像(x_i, y_i)到另一张图像的每对坐标的这种关系(x_i', y_i'):
[p_i*x_i'] [h11 h12 h13] [x_i]
[p_i*y_i'] = [h21 h22 h23] * [y_i]
[ p_i ] [h31 h32 1 ] [ 1 ]
Run Code Online (Sandbox Code Playgroud)
尺度p_i是考虑单应性缩放和消失点.让我们执行这个等式的矩阵向量乘法.我们可以忽略第3个元素,因为它对我们没用(现在):
p_i*x_i' = h11*x_i + h12*y_i + h13
p_i*y_i' = h21*x_i + h22*y_i + h23
Run Code Online (Sandbox Code Playgroud)
现在让我们来看看第3个元素.我们知道p_i = h31*x_i + h32*y_i + 1.因此,代p_i入各方程,并重新排列,以解决x_i'和y_i',因此,我们得到:
x_i' = h11*x_i + h12*y_i + h13 - h31*x_i*x_i' - h32*y_i*x_i'
y_i' = h21*x_i + h22*y_i + h23 - h31*x_i*y_i' - h32*y_i*y_i'
Run Code Online (Sandbox Code Playgroud)
你现在拥有的是每对独特点的两个方程式.我们现在能做的是建立一个过度确定的方程组.拿出每一对并从中构建两个方程式.然后,您将把它放入矩阵形式,即:
啊= b
A将是使用来自第一图像的坐标从每组方程建立的系数矩阵,b将是第二图像的每对点,并且h将是您要求解的参数.最终,你终于解决了以矩阵形式重新表述的线性方程组:

你可以求解h可以通过最小二乘法执行的向量.在MATLAB中,您可以通过以下方式执行此操作:
h = A \ b;
Run Code Online (Sandbox Code Playgroud)
给你的旁注:如果图像之间的运动真的只是旋转和平移,那么在我们求解参数后h31和h32都将为零.但是,我总是喜欢彻底,所以无论如何我会解决h31和h32.
注意:此方法仅在您拥有至少 4 对唯一点时才有效.因为有8个参数来解决,并且有每点2个方程,A必须至少有一个以8级的系统是一致的(如果你想在环路一些线性代数的术语来扔).如果您的积分少于4分,您将无法解决此问题.
如果你想要一些MATLAB代码,我们假设你的点存储在sourcePoints和中targetPoints. sourcePoints来自第一张图片,targetPoints用于第二张图片.显然,两个图像之间应该有相同数量的点.据推测,这两个sourcePoints和targetPoints被存储为M x 2矩阵.第一列包含您x的坐标,第二列包含您y的坐标.
numPoints = size(sourcePoints, 1);
%// Cast data to double to be sure
sourcePoints = double(sourcePoints);
targetPoints = double(targetPoints);
%//Extract relevant data
xSource = sourcePoints(:,1);
ySource = sourcePoints(:,2);
xTarget = targetPoints(:,1);
yTarget = targetPoints(:,2);
%//Create helper vectors
vec0 = zeros(numPoints, 1);
vec1 = ones(numPoints, 1);
xSourcexTarget = -xSource.*xTarget;
ySourcexTarget = -ySource.*xTarget;
xSourceyTarget = -xSource.*yTarget;
ySourceyTarget = -ySource.*yTarget;
%//Build matrix
A = [xSource ySource vec1 vec0 vec0 vec0 xSourcexTarget ySourcexTarget; ...
vec0 vec0 vec0 xSource ySource vec1 xSourceyTarget ySourceyTarget];
%//Build RHS vector
b = [xTarget; yTarget];
%//Solve homography by least squares
h = A \ b;
%// Reshape to a 3 x 3 matrix (optional)
%// Must transpose as reshape is performed
%// in column major format
h(9) = 1; %// Add in that h33 is 1 before we reshape
hmatrix = reshape(h, 3, 3)';
Run Code Online (Sandbox Code Playgroud)
完成后,您将拥有一个组合的旋转和平移矩阵.如果你想要x和y翻译,只需选择第3列,第1行和第2行hmatrix.然而,我们也可以用向量工作h本身,所以H13是件3,和H23将元件数量6.如果要旋转的角度,简单地采取相应的反三角函数的行1,2和列1,2.对于h向量,这将是元素1,2,4和5.根据您选择的元素,将会有一些不一致,因为这是通过最小二乘法求解的.获得良好整体角度的一种方法可能是找到所有4个元素的角度然后做某种平均值.无论哪种方式,这都是一个很好的起点.
我不久前通过Leow Wee Kheng的计算机视觉课程学习了单应性.我告诉你的是基于他的幻灯片:http: //www.comp.nus.edu.sg/~cs4243/lecture/camera.pdf.如果您想知道我从哪里取出这些材料,请查看幻灯片30-32.但是,我自己编写的MATLAB代码:)