【问题标题】:Plot circular gradients using numpy使用 numpy 绘制圆形渐变
【发布时间】:2019-03-14 09:29:56
【问题描述】:

我有一个用 numpy 绘制径向渐变的代码。到目前为止,它看起来像这样:

import numpy as np
import matplotlib.pyplot as plt

arr = np.zeros((256,256,3), dtype=np.uint8)
imgsize = arr.shape[:2]
innerColor = (0, 0, 0)
outerColor = (255, 255, 255)
for y in range(imgsize[1]):
    for x in range(imgsize[0]):
        #Find the distance to the center
        distanceToCenter = np.sqrt((x - imgsize[0]//2) ** 2 + (y - imgsize[1]//2) ** 2)

        #Make it on a scale from 0 to 1innerColor
        distanceToCenter = distanceToCenter / (np.sqrt(2) * imgsize[0]/2)

        #Calculate r, g, and b values
        r = outerColor[0] * distanceToCenter + innerColor[0] * (1 - distanceToCenter)
        g = outerColor[1] * distanceToCenter + innerColor[1] * (1 - distanceToCenter)
        b = outerColor[2] * distanceToCenter + innerColor[2] * (1 - distanceToCenter)
        # print r, g, b
        arr[y, x] = (int(r), int(g), int(b))

plt.imshow(arr, cmap='gray')
plt.show()

有没有办法用numpy函数优化这段代码并提高速度? 之后应该是这样的:

【问题讨论】:

  • 如果从简单的意义上说,你想要一个 250x250 numpy 数组,在索引 124,124 你希望值为零,并希望值根据欧几里得距离增加中心?
  • 完全正确,但是对于 256x256 numpy 数组

标签: python numpy gradient circular-dependency radial


【解决方案1】:

您可以使用矢量化来非常有效地计算距离,而无需 for 循环:

x_axis = np.linspace(-1, 1, 256)[:, None]
y_axis = np.linspace(-1, 1, 256)[None, :]

arr = np.sqrt(x_axis ** 2 + y_axis ** 2)

或者你可以使用网格:

x_axis = np.linspace(-1, 1, 256)
y_axis = np.linspace(-1, 1, 256)

xx, yy = np.meshgrid(x_axis, y_axis)
arr = np.sqrt(xx ** 2 + yy ** 2)

并再次使用广播在innerouter 颜色之间进行插值

inner = np.array([0, 0, 0])[None, None, :]
outer = np.array([1, 1, 1])[None, None, :]

arr /= arr.max()
arr = arr[:, :, None]
arr = arr * outer + (1 - arr) * inner

【讨论】:

    【解决方案2】:

    由于对称性,实际上只需要计算图像256*256的四分之一即64*64,然后将其逐个旋转90度并组合起来。这样,总时间是计算256*256像素的1/4倍。

    以下是示例。

    import numpy as np
    import matplotlib.pyplot as plt
    
    ##Just calculate 64*64
    arr = np.zeros((64,64,3), dtype=np.uint8)
    imgsize = arr.shape[:2]
    innerColor = (0, 0, 0)
    outerColor = (255, 255, 255)
    for y in range(imgsize[1]):
        for x in range(imgsize[0]):
            #Find the distance to the corner
            distanceToCenter = np.sqrt((x) ** 2 + (y - imgsize[1]) ** 2)
    
            #Make it on a scale from 0 to 1innerColor
            distanceToCenter = distanceToCenter / (np.sqrt(2) * imgsize[0])
    
            #Calculate r, g, and b values
            r = outerColor[0] * distanceToCenter + innerColor[0] * (1 - distanceToCenter)
            g = outerColor[1] * distanceToCenter + innerColor[1] * (1 - distanceToCenter)
            b = outerColor[2] * distanceToCenter + innerColor[2] * (1 - distanceToCenter)
            # print r, g, b
            arr[y, x] = (int(r), int(g), int(b))
    #rotate and combine
    arr1=arr
    arr2=arr[::-1,:,:]
    arr3=arr[::-1,::-1,:]
    arr4=arr[::,::-1,:]
    arr5=np.vstack([arr1,arr2])
    arr6=np.vstack([arr4,arr3])
    arr7=np.hstack([arr6,arr5])
    plt.imshow(arr7, cmap='gray')
    plt.show()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多