我一直在阅读Jan Erik Solem的Programming Computer Vision with Python,这是一本非常好的书,但是我无法澄清有关图像注册的问题。
基本上,我们有一堆图像(面)需要稍微对齐,所以首先需要通过相似变换来执行严格的变换:
x' = | sR t | x
| 0 1 |
其中x是要通过旋转R,平移t和缩放s变换为x'的向量(在这种情况下是一组坐标)。
Solem为每个图像计算这个刚性变换,它返回旋转矩阵R和平移向量tx和ty:
R,tx,ty = compute_rigid_transform(refpoints, points)
然而,由于某种原因,他重新安排了R的元素:
T = array([[R[1][1], R[1][0]], [R[0][1], R[0][0]]])
后来他执行affine transformation:
im2[:,:,i] = ndimage.affine_transform(im[:,:,i],linalg.inv(T),offset=[-ty,-tx])
在此示例中,此仿射变换在每个通道上执行,但这不相关。 im[:,:,i]
是要处理的图像,此过程返回另一个图像。
什么是T
,为什么我们在仿射变换中反转那个矩阵?实现图像注册的常用步骤是什么?
Here您可以在Google图书中找到此代码的相关部分。从第67页的底部开始。
答案 0 :(得分:1)
对我来说,这似乎是代码中的错误。 T
似乎只是R
的转置,对于旋转矩阵,它与反转相同。然后他在ndimage.affine_transform
的调用中反过来(再次)。我认为应该将T
或linalg.inv(R)
传递给该函数。
答案 1 :(得分:0)
我会尝试回答你的问题并指出书中的错误(?)。 (1)为什么使用T =数组([[R [1] [1],R [1] [0]],[R [0] [1],R [0] [0]]])? 因为R,tx,ty = compute_rigid_transform(refpoints,points)计算旋转矩阵 并以下列形式翻译:
|x'| = s|R[0][0] R[0][1]||x| + |tx| Equation (1)
|y'| |R[1][0] R[1][1]||y| |ty|
但是,OUT = ndimage.affine_transform(IN,A,b)要求(y,x)形式的坐标不是(x,y)的顺序。所以上面的等式(1)将成为
|y'| = s|R[1][1] R[1][0]||y| + |ty| = T|y| + |ty| Equation(2)
|x'| |R[0][1] R[0][0]||x| |tx| |x| |tx|
然后,在函数ndimage.affine_transform()中,矩阵将是linalg.inv(T),而不是linalg.inv(R)。
(2)仿射变换OUT = ndimage.affine_transform(IN,A,b)实际上是A * OUT + b => IN。 根据等式(2),将其重写为
|y| = inv(T)|y'| - inv(T)|ty|
|x| |x'| |tx|
因此函数ndimage.affine_transform()中的偏移量为inv(T)[ - ty,-tx],而不是[-ty -tx]。 我认为这是原始代码中的一个错误。