Двухмерная цветовая рампа (матрица 256×256), интерполированная из 4 угловых цветов

То, что я хочу достичь, – это программно создать двумерный цветовой рамп, представленный матрицей цветов 256х256. Ожидаемый результат можно увидеть на прилагаемом изображении. То, что у меня есть для начальной точки, – это 4 угла цвета матрицы, из которых должны быть интерполированы остальные 254 цвета между ними. Хотя у меня был некоторый успех для интерполяции цветов для одной оси, двумерный расчет дает мне некоторые плохие головные боли. Хотя изображение, похоже, имеет нелинейный цветовой градиент, я был бы доволен линейным.

Если бы вы могли дать мне несколько советов, как это сделать с помощью numpy или других инструментов, я буду более чем благодарен.

введите описание изображения здесь

3 Solutions collect form web for “Двухмерная цветовая рампа (матрица 256×256), интерполированная из 4 угловых цветов”

Вот супер короткое решение, использующее функцию масштабирования от scipy.ndimage . Я определяю изображение 2×2 RGB с внутренними цветами (здесь случайными) и просто увеличиваю его до 256×256, order=1 делает интерполяцию линейной. Вот код:

 import numpy as np import matplotlib.pyplot as plt im=(np.random.rand(2,2,3)*255).astype(np.uint8) from scipy.ndimage.interpolation import zoom zoomed=zoom(im,(128,128,1),order=1) plt.subplot(121) plt.imshow(im,interpolation='nearest') plt.subplot(122) plt.imshow(zoomed,interpolation='nearest') plt.show() 

Вывод:

вывод из сценария

Вот очень короткий способ сделать это с помощью ImageMagick, который установлен на большинстве дистрибутивов Linux и доступен для OSX и Windows. Существуют также привязки Python. В любом случае, просто в командной строке создайте квадрат 2×2 с цветами в 4 углах вашего изображения, а затем пусть ImageMagick будет расширяться и интерполироваться до полного размера:

 convert \( xc:"#59605c" xc:"#ebedb3" +append \) \ \( xc:"#69766d" xc:"#b3b3a0" +append \) \ -append -resize 256x256 result.png 

введите описание изображения здесь

Первая строка делает пиксель 1×1 каждого из ваших верхних левых и верхних правых углов и добавляет два бок о бок. Вторая строка делает пиксель 1×1 каждого из ваших нижних и нижних правых углов и добавляет их рядом друг с другом. Окончательная строка добавляет нижний ряд ниже верхнего ряда и увеличивает интерполяцию до 256×256.

Если вы хотите лучше понять, что происходит, вот то же самое основное изображение, но расширенное с использованием ближайшего соседа, а не интерполяция:

 convert \( xc:"#59605c" xc:"#ebedb3" +append \) \ \( xc:"#69766d" xc:"#b3b3a0" +append \) \ -append -scale 20x20 result.png 

введите описание изображения здесь

Вот три способа сделать эту билинейную интерполяцию. Первая версия выполняет всю арифметику в чистом Python, вторая использует состав изображения PIL , третий использует Numpy для выполнения арифметики. Как и ожидалось, чистый Python значительно медленнее, чем другие подходы. Версия Numpy (которая была получена из кода, написанного Andras Deak ), почти так же быстро, как версия PIL для небольших изображений, но для больших изображений версия PIL заметно быстрее.

Я также пробовал использовать технологию масштабирования jadsq в PIL, но результаты были не очень хорошими – я подозреваю, что интерполяционный код PIL немного глючен.

Если вы хотите создать много этих билинейных изображений градиента того же размера, метод PIL имеет еще одно преимущество: после создания масок композиции вам не нужно перестраивать их для каждого изображения.

 #!/usr/bin/env python3 ''' Simple bilinear interpolation Written by PM 2Ring 2016.09.14 ''' from PIL import Image from math import floor import numpy as np def color_square0(colors, size): tl, tr, bl, br = colors m = size - 1 r = range(size) def interp_2D(tl, tr, bl, br, x, y): u0, v0 = x / m, y / m u1, v1 = 1 - u0, 1 - v0 return floor(0.5 + u1*v1*tl + u0*v1*tr + u1*v0*bl + u0*v0*br) data = bytes(interp_2D(tl[i], tr[i], bl[i], br[i], x, y) for y in r for x in r for i in (0, 1, 2)) return Image.frombytes('RGB', (size, size), data) # Fastest def color_square1(colors, size): #Make an Image of each corner color tl, tr, bl, br = [Image.new('RGB', (size, size), color=c) for c in colors] #Make the composition mask mask = Image.new('L', (size, size)) m = 255.0 / (size - 1) mask.putdata([int(m * x) for x in range(size)] * size) imgt = Image.composite(tr, tl, mask) imgb = Image.composite(br, bl, mask) return Image.composite(imgb, imgt, mask.transpose(Image.TRANSPOSE)) # This function was derived from code written by Andras Deak def color_square2(colors, size): tl, tr, bl, br = map(np.array, colors) m = size - 1 x, y = np.mgrid[0:size, 0:size] x = x[..., None] / m y = y[..., None] / m data = np.floor(x*y*br + (1-x)*y*tr + x*(1-y)*bl + (1-x)*(1-y)*tl + 0.5) return Image.fromarray(np.array(data, dtype = 'uint8'), 'RGB') color_square = color_square1 #tl = (255, 0, 0) #tr = (255, 255, 0) #bl = (0, 0, 255) #br = (0, 255, 0) tl = (108, 115, 111) tr = (239, 239, 192) bl = (124, 137, 129) br = (192, 192, 175) colors = (tl, tr, bl, br) size = 256 img = color_square(colors, size) img.show() #img.save('test.png') 

вывод

билинейный градиент


Просто для удовольствия, вот простая программа GUI, использующая Tkinter, которая может использоваться для генерации этих градиентов.

 #!/usr/bin/env python3 ''' Simple bilinear colour interpolation using PIL, in a Tkinter GUI Inspired by https://stackoverflow.com/q/39485178/4014959 Written by PM 2Ring 2016.09.15 ''' import tkinter as tk from tkinter.colorchooser import askcolor from tkinter.filedialog import asksaveasfilename from PIL import Image, ImageTk DEFCOLOR = '#d9d9d9' SIZE = 256 #Make the composition masks mask = Image.new('L', (SIZE, SIZE)) m = 255.0 / (SIZE - 1) mask.putdata([int(m * x) for x in range(SIZE)] * SIZE) maskt = mask.transpose(Image.TRANSPOSE) def do_gradient(): imgt = Image.composite(tr.img, tl.img, mask) imgb = Image.composite(br.img, bl.img, mask) img = Image.composite(imgb, imgt, maskt) ilabel.img = img photo = ImageTk.PhotoImage(img) ilabel.config(image=photo) ilabel.photo = photo def set_color(w, c): w.color = c w.config(background=c, activebackground=c) w.img = Image.new('RGB', (SIZE, SIZE), color=c) def show_color(w): c = w.color newc = askcolor(c)[1] if newc is not None and newc != c: set_color(w, newc) do_gradient() def color_button(row, column, initcolor=DEFCOLOR): b = tk.Button(root) b.config(command=lambda w=b:show_color(w)) set_color(b, initcolor) b.grid(row=row, column=column) return b def save_image(): filetypes = [('All files', '.*'), ('PNG files', '.png')] fname = asksaveasfilename(title="Save Image",filetypes=filetypes) if fname: ilabel.img.save(fname) print('Saved image as %r' % fname) else: print('Cancelled') root = tk.Tk() root.title("Color interpolation") coords = ((0, 0), (0, 2), (2, 0), (2, 2)) tl, tr, bl, br = [color_button(r, c) for r,c in coords] ilabel = tk.Label(root, relief=tk.SUNKEN) do_gradient() ilabel.grid(row=1, column=1) b = tk.Button(root, text="Save", command=save_image) b.grid(row=3, column=1) root.mainloop() 
  • Заполнение интервалов времени в мультииндексе Pandas Dataframe
  • Нестабильность вычислений данных в pandas
  • Установка Numpy и Scipy на окнах
  • ImportError: невозможно импортировать имя add_newdocs
  • numpy IndexError: слишком много индексов для массива при индексировании матрицы с другим
  • Быстро проанализируйте дату и время Python в нелокальном часовом поясе, настроившись на летнее время
  • взвешенная скользящая средняя с numpy.convolve
  • Как создать объект среза для массива Numpy?
  •  
    Interesting Posts for Van-Lav

    Как загрузить результаты поиска изображений Google в Python

    Python pandas – pd.melt dataframe с индексом datetime приводит к NaN

    Как обработчики Python обрабатывают отступы?

    Различия XML между WCF и Python SUDS для наследования?

    Как заставить словарь на python иметь только уникальные ключи?

    Аутентификация пользователя в приложении tornado websocket

    Использование статических методов в python – лучшая практика

    Как добавить новую строку в пустой массив numpy

    Имя не определено в понимании списка с несколькими циклами

    Как свернуть собственный оценщик в PySpark mllib

    Получение индекса возвращаемого значения max или min с помощью max () / min () в списке

    Как создавать списки из спецификации комбинаций элементов

    Как преобразовать dict в строку unicode JSON?

    Регулярное выражение python: захватывает части нескольких строк, которые содержат пробелы

    Найти объект своим членом внутри списка в python

    Python - лучший язык программирования в мире.