Вы знаете значения RGB в каждом из четырех углов, поэтому, чтобы иметь возможность создавать цветовую карту, все, что вам нужно, это функция, которая будет принимать координаты (x,y)
(где x
и y
находятся в диапазон 0
до 1
) и возвращает значение RGB по этой координате.
Для этого нам нужно реализовать билинейную интерполяцию , которая является расширением линейной интерполяции до интерполяции в 2d.
Вы выполняете билинейную интерполяцию, интерполируя между двумя верхними углами, а затем интерполируя результат этого с результатом интерполяции между двумя нижними углами.
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 в виде четырех списков / числовых массивов длиной 3
(a
, b
, c
, d
) и координаты (x
, y
), чтобы вернуть значение 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])
или мы могли бы сделать его более Pythonic с помощью списка компов:
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)])
Теперь нам просто нужно оценить это по массиву, для которого мы можем использовать np.meshgrid
(см. этот вопрос для альтернативных методов).
О, и я начну с 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](https://i.stack.imgur.com/fHlHp.jpg)
Этот метод также используется в перлин-шуме , что позволило мне создать этот генератор местности .