Оттенки серого в питоне - неправильные цвета меняются от темно-серого до светло-серого и затем до темно-серого.

Я рисую версию этого изображения в оттенках серого: деловой кот

ИСТОЧНИК: http://matplotlib.org/examples/pylab_examples/griddata_demo.html

Я использовал следующий код:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from PIL import Image

file_name = 'griddata_demo.png'
def func_grey(fname):
    image = Image.open(fname).convert("L")
    arr = np.asarray(image)
    plt.imshow(arr, cmap = cm.Greys_r)
    plt.show()

func_grey(file_name)

Отображать изображение в оттенках серого с помощью matplotlib

Установка, над которой я работаю, включает Python 2.7 и Pandas, и я установил Pillow с простой установкой.

Исходная информация об изображении и требованиях:

  1. Изображение взято из данных, найденных здесь. В идеале версия этого изображения в оттенках серого должна быть сгенерирована непосредственно из этих необработанных данных, т.е. не сохраняйте его как цветное изображение, а затем пытайтесь преобразовать в оттенки серого, а просто создайте версию графика в оттенках серого.
  2. Я не знаю цвета, соответствующие z-значениям — эти цвета можно задавать произвольно.
  3. Карту цветов изображения также можно выбрать произвольно — предпочтений нет. Это версия в оттенках серого, которая вызывает беспокойство.

Мой вопрос связан с цветовой схемой, показанной на панели цветов. Мне нужно отобразить цветовую схему, в которой цветная полоса имеет цвета от светло-серого (самая низкая интенсивность) до темно-серого (самая высокая интенсивность).

После запуска приведенного выше кода создается изображение в оттенках серого. На цветовой полосе изображения в оттенках серого уровень интенсивности -0,36 соответствует темно-серому. В 0.00 он светло-серый. Но тогда 0,48 тоже темно-серый.

Вопрос: Можно ли изменить цветовую карту так, чтобы -0,36 было светло-серым, а 0,48 - темно-серым? Я имею в виду, можно ли отображать цветную полосу от светлого к темному?


person edesz    schedule 06.10.2014    source источник
comment
Это хорошо известная проблема с цветовой картой исходного изображения: то есть она не имеет монотонной яркости (в вашем случае зеленый в 0 ярче, чем красный или синий в крайних точках... вы можете просто посмотрите, так что не вините свой конвертер). Поэтому вместо преобразования с использованием яркости вам нужно инвертировать исходную палитру. Или, если вы можете создать цветное изображение с нуля и вам не нужно создавать существующее изображение, выберите другую карту цветов, например hot или кубическую спираль и т. д.   -  person tom10    schedule 07.10.2014
comment
@tom10: Спасибо. Я действительно смотрю на ваш первый ответ. Я также прочитаю ваш второй комментарий, основанный на ссылке, и отпишусь здесь, как только попробую.   -  person edesz    schedule 07.10.2014
comment
Главный вопрос будет заключаться в том, какова ваша исходная цветовая карта? Поскольку вышеприведенное является просто демонстрацией, а детали карты цветов имеют решающее значение (в том смысле, что некоторые из них тривиальны, а некоторые сложны), важно знать их с самого начала.   -  person tom10    schedule 07.10.2014
comment
@tom10: (Если вы считаете, что было бы уместно обсудить это в чате, пожалуйста, дайте мне знать — затем я опубликую здесь результаты этого, чтобы ответить на исходный пост.) Итак, я проверил свою палитру с печатью cm.get_cmap(), и я получил объект ‹matplotlib.colors.LinearSegmentedColormap по адресу 0x0000000006D81DD8›. Похоже, мне нужно выбрать серый цвет карты, который находится в списке цветовых карт Sequential2. Как изменить категорию и выбрать одну карту из списка новой категории?   -  person edesz    schedule 08.10.2014
comment
Чат меня устраивает, хотя я не знаю, как туда попасть, поэтому, пожалуйста, инициируйте его, если знаете. Когда вы говорите об этой проблеме, важно четко понимать, какая у вас исходная цветовая карта по сравнению с вашим пунктом назначения. Что бы это ни было, пожалуйста, уточните исходное изображение, которое вам нужно преобразовать: 1) есть ли у вас какой-либо контроль над ним (например, вы можете выбрать его цветовую карту)?, знаете ли вы, какие цвета соответствуют какие ценности и откуда вы это знаете? и т.д.   -  person tom10    schedule 08.10.2014
comment
Привет, по поводу чата: к сожалению, я не могу общаться, так как у меня нет необходимых очков репутации. Имея это в виду, я обновил исходный пост, чтобы предоставить больше информации. Как вы и просили, я не знаю цвета, соответствующие значениям — их можно задать произвольно. Да, я могу выбрать его цветовую карту. Единственный интерес представляет цветовая схема изображения версии в оттенках серого — на этом акцент.   -  person edesz    schedule 08.10.2014
comment
Поэтому, если вы можете выбрать цветовую карту оригинала, просто выберите ту, которая легко преобразуется в оттенки серого (hot, cubehelix и т. д.). Тогда convert(L) будет работать, и вся проблема очень проста. Верно? Я напишу короткую демонстрацию позже (если кто-то еще не сделает этого раньше).   -  person tom10    schedule 08.10.2014
comment
@tom10: если бы вы могли опубликовать ответ, это было бы здорово. Я вставил эту строку c_map = plt.set_cmap('cubehelix') перед первой строкой моей функции выше. Но, похоже, это не меняет имидж.   -  person edesz    schedule 08.10.2014
comment
Еще одна вещь меня смущает: если вы можете сделать исходный контурный график в любой цветовой карте, которую хотите, то почему бы не сделать один в оттенках серого вместе с оригиналом (т.е. оба графика из matplotlib). Я хочу быть уверен, что вы не просто спрашиваете, как изменить цветовую карту на оттенки серого в matplotlib; или вам действительно нужно выполнять обработку изображения на ранее созданном контурном графике?   -  person tom10    schedule 08.10.2014
comment
Извините, я должен был это сказать. Да, я могу просто сделать один в оттенках серого, как вы предложили, и оба они взяты из matplotlib.   -  person edesz    schedule 08.10.2014


Ответы (2)


Я думаю, что этот вопрос может быть о том, как использовать цветовую карту в оттенках серого в matplotlib. Если так, то это просто. Вот пример использования разных цветовых карт (на основе кода операционного изображения):

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

from numpy.random import uniform, seed
from matplotlib.mlab import griddata
import matplotlib.pyplot as plt
import numpy as np
# make up data.
#npts = int(raw_input('enter # of random points to plot:'))

def f(spi, the_colormap):
    plt.subplot(spi)
    seed(0)
    npts = 200
    x = uniform(-2, 2, npts)
    y = uniform(-2, 2, npts)
    z = x*np.exp(-x**2 - y**2)
    xi = np.linspace(-2.1, 2.1, 100)
    yi = np.linspace(-2.1, 2.1, 200)
    zi = griddata(x, y, z, xi, yi, interp='linear')

    CS = plt.contour(xi, yi, zi, 15, linewidths=0.5, colors='k')
    CS = plt.contourf(xi, yi, zi, 15, cmap=the_colormap,
                      vmax=abs(zi).max(), vmin=-abs(zi).max())
    plt.colorbar()  # draw colorbar
    # plot data points.
    plt.scatter(x, y, marker='o', c='b', s=5, zorder=10)
    plt.xlim(-2, 2)
    plt.ylim(-2, 2)
    plt.title('griddata test (%d points)' % npts)

f(131, plt.cm.rainbow)
f(132, plt.cm.gray)
f(133, plt.cm.hot)

plt.show()

Если кто-то действительно хочет преобразовать в оттенки серого с помощью PIL (гораздо менее благоприятная, но иногда необходимая задача), лучше всего начать с карты цветов с монотонной яркостью, например hot выше, но не rainbow. Кроме того, в комментариях я предложил использовать cubehelix, но это не стандартно для matplotlib, вместо этого см. здесь. См. здесь для изображения доступных цветовых карт matplotlib.

person tom10    schedule 08.10.2014
comment
Да, это отвечает на вопрос. Я обновлю исходный вопрос, чтобы отразить более подходящую формулировку. По сути, как вы и сказали, нет необходимости создавать изображение и сохранять его, а затем импортировать его просто для изменения цветовой карты. Все это должно быть сделано непосредственно из необработанных данных. Спасибо за ваше терпение и за ответ. Это ответ, который у меня было много проблем с поиском в Интернете. - person edesz; 08.10.2014
comment
Просто продолжение вашего третьего сюжета - вы использовали hot в качестве цветовой карты. Я предполагаю, что по умолчанию он выбрал красный цвет - можно ли установить его на другие цвета? - person edesz; 08.10.2014
comment
Я добавил ссылку, где вы можете увидеть все включенные цветовые карты. Вы также можете довольно легко создавать свои собственные с нуля, если они просты (например, горячие), и если вы хотите это сделать, поищите linearsegmentedcolormap, но включенные, вероятно, сейчас. (Но для вашего конкретного вопроса, афаик, вы не можете изменить «горячий», чтобы использовать другой цвет.) - person tom10; 08.10.2014
comment
Спасибо еще раз. Все вопросы в полном посте и ответы. - person edesz; 08.10.2014

это решение работает для меня и намного проще

from PIL import Image
im = Image.open("image.png")
im.convert('L').show()
im.convert('L').save("image.png")

обратите внимание, что если вы хотите перепутать типы файлов, вы можете (например, .png в .jpg)

person RandomSqueaker    schedule 23.01.2020