You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Pillow (PIL)执行仿射图像变换时偏移方向错误的问题

使用Pillow (PIL)执行仿射图像变换时偏移方向错误的问题

嘿,我完全懂你现在的困惑!明明对着文档的公式设置了正的c值,想着能把图像往右移,结果反而往左跑了,这实在是容易绕晕人——其实问题出在你对Pillow的transform方法的变换逻辑理解反了!

你看到的文档里说的:

给定仿射参数[a, b, c, d, e, f],像素的新位置是x_new, y_new = (a*x_old + b*y_old + c, d*x_old + e*y_old + f)

这是前向变换的逻辑:计算原图像的像素会移动到新图像的哪个位置。但Pillow的transform方法用的是逆变换的逻辑——它是反过来的:对于新图像里的每一个像素,它会用这个公式计算「我应该从原图像的哪个位置取像素来填充自己」。

举个直白的例子:
你想把图像右移85像素,意思是新图像里的第85个x坐标位置,应该放原图像第0个x坐标的像素(这样原图像的内容就整体靠右,左边空出来的地方用填充色补上)。那对应逆变换的公式,新图像的x_out对应的原图像x_in应该是x_in = x_out - 85。

而Pillow的仿射参数[a,b,c,d,e,f]对应的逆变换公式是:
x_in = a * x_out + b * y_out + c
y_in = d * x_out + e * y_out + f

所以代入a=1, b=0的情况,要满足x_in = x_out -85,c的值就必须是**-85**,而不是你原来用的+85。

你之前写的affine_params = [1, 0, 85, 0, 1, 0],按照逆变换逻辑,这意味着新图像的每个x_out像素,都从原图像的x_in = x_out +85位置取像素。比如新图像最左边的x_out=0,会取原图像x_in=85的像素,这样原图像的内容就会被拉到新图像的左侧,看起来就像是整体左移了,这正好和你遇到的现象一致!

把参数改成下面这样,就能得到你想要的右移85像素的效果:

from PIL import Image
test_image = Image.open('Test image.png')
# 把c改成-85,实现右移
affine_params = [1, 0, -85, 0, 1, 0]
trans_image = test_image.transform(test_image.size, Image.AFFINE, affine_params, Image.BILINEAR, fillcolor = (150,150,150))
trans_image.save('Transformed image.png')

最后再给你划几个关键点:

  • 记住Pillow的transform用的是逆变换参数:从输出像素找输入源像素,和你直觉里的「原像素移到新位置」是反过来的
  • 方向规则:要实现右移,c设为负数;左移则设为正数;y方向同理,正的f会让图像上移,负的f会下移
  • 不确定的时候可以先试小数值,比如c=-10,快速验证方向是否正确

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 06:40:30