python - 如何使用 scipy.ndimage.interpolation.affine_transform 围绕其中心旋转图像?

标签 python numpy matplotlib rotation scipy

我对 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()

我明白了

rotated but not about centre lena image

不幸的是,它没有围绕中心旋转。

那么我在这里缺少的技巧是什么?

最佳答案

一旦 treddy 的回答为我提供了一个工作基线,我就设法获得了一个更好的 affine_transform 工作模型。它实际上并不像原始问题提示中链接的问题那么奇怪。

基本上,输出图像中的每个点(坐标)p 都被转换为pT+s,其中Ts 是传递给函数的矩阵和偏移量。 因此,如果我们希望输出中的点 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()

Spinning Lena

这里针对不同的图像尺寸进行了修改

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()

Spinning small Lena

这是一个具有各向异性缩放的版本,用于补偿源图像的各向异性分辨率。

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() 

Spinning anisotropic Lena

关于python - 如何使用 scipy.ndimage.interpolation.affine_transform 围绕其中心旋转图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20161175/

相关文章:

python - DJANGO - 多用户

python - 如何有效找到线性分类模型的0/1损失?

python - 我怎样才能解决下面的这些错误?

python - 属性错误 : 'numpy.ndarray' object has no attribute 'append'

python - 找出列表中任何 float 最接近的两个数字

Python ElementTree 解析未绑定(bind)前缀错误

python - Numpy 数组中的循环和搜索

python - 使用 Matplotlib 绘制多索引数据框时出现 x 轴标签错误

python - 添加具有约束布局的外部边距?

python - mongodb $push 查找某物的最大数量