为什么我的 conical/angle 渐变图像失真了?
Why is my conical/angle gradient image distorted?
我目前正在尝试创建一个圆锥形渐变,它有点管用。但是,它看起来不太正确,我无法理解为什么:
从中心向上的线稍微向右倾斜,底部有一条可见(不太明显)的线。
代码如下:
import math
import numpy
from PIL import Image
def newImg(w,h):
data = numpy.zeros((h, w, 3), dtype=numpy.uint8)
for y in range(h):
for x in range(w):
p = [y,x]
center = [h/2,w/2]
angle = math.atan2(center[1]-p[1], center[0]-p[0])
data[y,x] = angle*(255/math.pi/2)
return data
image = Image.fromarray(newImg(2000,2000))
image.save('test.png')
image.show()
哦,另一件事是 NumPy/Pillow 交换宽度和高度,但这是我可以解决的问题。不过,如果对此有一个解释,那就太好了。
问题是您从 math.atan2
得到 angle
的负值,因为它的取值范围是 -pi ... pi
。接下来,您在 data
中得到负值,导致整数下溢(因为 data
的 dtype
是 numpy.uint8
),最终导致数值错误。
为防止这种情况,只需将 math.pi
添加到每个角度:
angle = math.atan2(center[1]-p[1], center[0]-p[0]) + math.pi
因此,angle
的取值范围变为 0 ... 2*pi
,data
的取值范围变为 0 ... 255
。当然,那时你的渐变图像旋转了180°,但旋转最终图像应该没有问题吧?
输出图像:
现在,要进一步改进您的代码,摆脱两个 (slooooow) 循环,并使用 NumPy 的矢量化能力:
def newImg(w,h):
x, y = numpy.meshgrid(range(w), range(h))
x = w/2 - x
y = h/2 - y
angles = numpy.arctan2(y, x) + numpy.pi
data = (angles * (255 / numpy.pi / 2)).astype(numpy.uint8)
return data
2000 x 2000
图像大幅加速,输出图像相同。
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.16299-SP0
Python: 3.9.1
NumPy: 1.20.1
Pillow: 8.1.0
----------------------------------------
我目前正在尝试创建一个圆锥形渐变,它有点管用。但是,它看起来不太正确,我无法理解为什么:
从中心向上的线稍微向右倾斜,底部有一条可见(不太明显)的线。
代码如下:
import math
import numpy
from PIL import Image
def newImg(w,h):
data = numpy.zeros((h, w, 3), dtype=numpy.uint8)
for y in range(h):
for x in range(w):
p = [y,x]
center = [h/2,w/2]
angle = math.atan2(center[1]-p[1], center[0]-p[0])
data[y,x] = angle*(255/math.pi/2)
return data
image = Image.fromarray(newImg(2000,2000))
image.save('test.png')
image.show()
哦,另一件事是 NumPy/Pillow 交换宽度和高度,但这是我可以解决的问题。不过,如果对此有一个解释,那就太好了。
问题是您从 math.atan2
得到 angle
的负值,因为它的取值范围是 -pi ... pi
。接下来,您在 data
中得到负值,导致整数下溢(因为 data
的 dtype
是 numpy.uint8
),最终导致数值错误。
为防止这种情况,只需将 math.pi
添加到每个角度:
angle = math.atan2(center[1]-p[1], center[0]-p[0]) + math.pi
因此,angle
的取值范围变为 0 ... 2*pi
,data
的取值范围变为 0 ... 255
。当然,那时你的渐变图像旋转了180°,但旋转最终图像应该没有问题吧?
输出图像:
现在,要进一步改进您的代码,摆脱两个 (slooooow) 循环,并使用 NumPy 的矢量化能力:
def newImg(w,h):
x, y = numpy.meshgrid(range(w), range(h))
x = w/2 - x
y = h/2 - y
angles = numpy.arctan2(y, x) + numpy.pi
data = (angles * (255 / numpy.pi / 2)).astype(numpy.uint8)
return data
2000 x 2000
图像大幅加速,输出图像相同。
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.16299-SP0
Python: 3.9.1
NumPy: 1.20.1
Pillow: 8.1.0
----------------------------------------