我对 scipy.ndimage.interpolation.affine_transform
的 API 感到困惑.并根据 this issue 判断我不是唯一一个。我实际上想用 affine_transform
做更多有趣的事情不仅仅是旋转图像,但对于初学者来说旋转会有所帮助。 (是的,我很清楚 scipy.ndimage.interpolation.rotate
,但弄清楚如何驾驶 affine_transform
是我感兴趣的地方)。
当我想在像 OpenGL 这样的系统中做这种事情时,我会考虑计算应用 2x2 旋转矩阵的变换 R
关于中心c
,因此思考点p
正在改造(p-c)R+c
= pR+c-cR
, 这给出了 c-cR
用作转换的翻译组件的术语。 但是,根据上面的issue,scipy的affine_transform
执行“先偏移”所以我们实际上需要计算偏移量 s
这样 (p-c)R+c=(p+s)R
稍微重新排列一下就可以得到 s=(c-cR)R'
其中 R'
是 R
的倒数.
如果我将其插入 ipython 笔记本(pylab 模式;下面的代码可能需要一些额外的导入):
img=scipy.misc.lena()
#imshow(img,cmap=cm.gray);show()
centre=0.5*array(img.shape)
a=15.0*pi/180.0
rot=array([[cos(a),sin(a)],[-sin(a),cos(a)]])
offset=(centre-centre.dot(rot)).dot(linalg.inv(rot))
rotimg=scipy.ndimage.interpolation.affine_transform(
img,rot,order=2,offset=offset,cval=0.0,output=float32
)
imshow(rotimg,cmap=cm.gray);show()
我明白了
不幸的是,它没有围绕中心旋转。
那么我在这里缺少的技巧是什么?
最佳答案
一旦 treddy 的回答为我提供了一个工作基线,我就设法获得了一个更好的 affine_transform
工作模型。它实际上并不像原始问题提示中链接的问题那么奇怪。
基本上,输出图像中的每个点(坐标)p
都被转换为pT+s
,其中T
和s
是传递给函数的矩阵和偏移量。
因此,如果我们希望输出中的点 c_out
映射到输入图像的 c_in
并从中采样,旋转 R
并且(可能是各向异性的) 缩放 S
我们需要 pT+s = (p-c_out)RS+c_in
可以重新排列以产生 s = (c_int-c_out)T
(使用 T=RS
)。
出于某种原因,我需要将 transform.T
传递给 affine_transform
但我不会太担心这个;可能与右侧变换的行坐标(如上假设)和左侧变换的列坐标有关。
所以这是一个旋转居中图像的简单测试:
src=scipy.misc.lena()
c_in=0.5*array(src.shape)
c_out=array((256.0,256.0))
for i in xrange(0,7):
a=i*15.0*pi/180.0
transform=array([[cos(a),-sin(a)],[sin(a),cos(a)]])
offset=c_in-c_out.dot(transform)
dst=scipy.ndimage.interpolation.affine_transform(
src,transform.T,order=2,offset=offset,output_shape=(512,512),cval=0.0,output=float32
)
subplot(1,7,i+1);axis('off');imshow(dst,cmap=cm.gray)
show()
这里针对不同的图像尺寸进行了修改
src=scipy.misc.lena()[::2,::2]
c_in=0.5*array(src.shape)
c_out=array((256.0,256.0))
for i in xrange(0,7):
a=i*15.0*pi/180.0
transform=array([[cos(a),-sin(a)],[sin(a),cos(a)]])
offset=c_in-c_out.dot(transform)
dst=scipy.ndimage.interpolation.affine_transform(
src,transform.T,order=2,offset=offset,output_shape=(512,512),cval=0.0,output=float32
)
subplot(1,7,i+1);axis('off');imshow(dst,cmap=cm.gray)
show()
这是一个具有各向异性缩放的版本,用于补偿源图像的各向异性分辨率。
src=scipy.misc.lena()[::2,::4]
c_in=0.5*array(src.shape)
c_out=array((256.0,256.0))
for i in xrange(0,7):
a=i*15.0*pi/180.0
transform=array([[cos(a),-sin(a)],[sin(a),cos(a)]]).dot(diag(([0.5,0.25])))
offset=c_in-c_out.dot(transform)
dst=scipy.ndimage.interpolation.affine_transform(
src,transform.T,order=2,offset=offset,output_shape=(512,512),cval=0.0,output=float32
)
subplot(1,7,i+1);axis('off');imshow(dst,cmap=cm.gray)
show()
关于python - 如何使用 scipy.ndimage.interpolation.affine_transform 围绕其中心旋转图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20161175/