为什么我的 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 中得到负值,导致整数下溢(因为 datadtypenumpy.uint8),最终导致数值错误。

为防止这种情况,只需将 math.pi 添加到每个角度:

angle = math.atan2(center[1]-p[1], center[0]-p[0]) + math.pi

因此,angle 的取值范围变为 0 ... 2*pidata 的取值范围变为 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
----------------------------------------