代码之家  ›  专栏  ›  技术社区  ›  Martin

python-使用由x,y位置定义的rgb值创建colormap

  •  2
  • Martin  · 技术社区  · 7 年前

    我在解决一个问题,我只解决了一半。 我在用x,y坐标处理二维绘图空间。我想在绘图空间上设置4个点,设置每个点的颜色并生成colormap。

    我能够生成带有2个点的彩色地图-创建向量并从一个点到另一个点。然而,这种方法在几何意义上在点上创建二维平面/1d线。但如果设置4点,则需要生成曲面。换言之,我需要在点上拟合曲面。

    我就是这么想的:

    这是我的代码,用于生成从一个x,y,[rgb]到另一个x,y,[rgb]的直接更改。

    import numpy as np 
    import colorsys
    import cv2
    
    a = np.array([100,0,0]) # Point one with x=0,y=0-max and rgb value
    b =  np.array([0,255,0]) # point two with x=max,y=0-max and rgb value
    #in this case i loop from y=0 to y=max for corresponding point on the other side of drawing space - that is x=max
    a = a[::-1]
    b= b[::-1]
    leds = 31 # just constant
    h_color=100 # height of drawing space
    t_lengt = (600/leds)*leds #recalculation of width (because I need integer)
    vector = (b-a)*1.0/t_lengt
    
    arr_texture = np.zeros(shape=[h_color, t_lengt, 3], dtype=np.uint8) #drawing space defined by x,y and 3d value
    
    for i in range(t_lengt): # loop for all points in x=0 to x=max (that is y=0 to max)
        for j in range(h_color):
    
            arr_texture[j][i]=[a[0]+vector[0]*i,a[1]+vector[1]*i,a[2]+vector[2]*i]
    
    
    cv2.imwrite('color_img.jpg', arr_texture)
    cv2.imshow("image", arr_texture);
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    结果:

    另外,我对这种方法很困惑,因为绘图空间上的点是由x,y坐标定义的,但它们携带[r,g,b]值。

    总而言之,我需要 更多 创建彩色地图表面的点,其中的点有x,y坐标,但携带[r,g,b]值。

    提前谢谢

    1 回复  |  直到 7 年前
        1
  •  1
  •   Joe Iddon    7 年前

    你知道四个角上的rgb值,所以,为了能够创建一个彩色地图,你只需要一个函数来获取一个坐标 (x,y) (其中 x y 在范围之内 0 1 )并返回该坐标处的rgb值。

    为此,我们需要实施 bilinear interpolation 它是线性插值到二维插值的扩展。


    通过在顶部两个角之间进行插值,然后使用底部两个角之间的插值结果插值,来执行双线性插值。

    a ----|---- b
          |
          |
    c ----|-----d
    

    所以在我们编写主函数之前,我们首先需要一个助手来执行插值,因为我们将使用它九次。

    这可能是线性的:

    def lerp(x, a, b):
        return a + x * (b-a)
    

    或者更光滑的东西,比如 smoothstep 功能:

    def serp(x, a, b):
        return a + (3*x**2 - 2*x**3) * (b-a)
    

    (结果是,在这种情况下,我们只需要走到拐角处(而不是像用柏林噪声发生器那样的山丘),线性会产生一个更渐变的梯度!)


    该函数将四个rgb值作为四个长度的list/numpy数组 3 ( a ,请 b 我是说, c ,请 d )还有坐标( 我是说, 是的 )返回该坐标处的rgb值。

    def get_color(x, y, a, b, c, d):
        r = lerp(y, lerp(x, a[0], b[0]), lerp(x, c[0], d[0]))
        g = lerp(y, lerp(x, a[1], b[1]), lerp(x, c[1], d[1]))
        b = lerp(y, lerp(x, a[2], b[2]), lerp(x, c[2], d[2]))
        return np.array([r, g, b])
    

    或者,我们可以用一个列表来让它更像蟒蛇:

    def get_color(x, y, a, b, c, d):
        return np.array([lerp(y, lerp(x, a[i], b[i]),
                                 lerp(x, c[i], d[i])) for i in range(3)])
    

    现在我们只需要在一个可以使用的numpy数组上计算这个值 np.meshgrid 对于(请参见 this question 对于其他方法)。

    哦,我会和 matplotlib 因为我没有 OpenCV 安装!

    import matplotlib.pyplot as plt
    import numpy as np
    w = h = 200
    verts = [[255,0,0],[0,255,0],[0,0,255],[255,0,0]]
    img = np.empty((h,w,3), np.uint8)
    for y in range(h):
        for x in range(w):
            img[y,x] = get_color(x/w, y/h, *verts)
    plt.imshow(img)
    plt.show()
    

    它给出了以下图像:

    colormap.jpg


    这种技术也用于 perlin noise 让我创造了这个 terrain generator 是的。