Как управлять рендерингом цветного изображения с помощью matplotlib?

Из изображения rgb было сделано другое, только добавлением границ, заполненных нулями: введите описание изображения здесь

Денситометрические профили показывают, что значения пикселей одинаковы для ненулевого домена на обоих изображениях.

subplot(141)
imshow(rgb_chromosomes[0])
subplot(142)
plot(rgb_chromosomes[0][13,:,:])
subplot(143)
imshow(resized_rgb[0][10:40,11:40,:])
subplot(144)
plot(resized_rgb[0][25,17:38,:])

show()

Странно, что измененное изображение выглядит синим, а исходное — коричневым. Что сделать, чтобы второе изображение было похоже на первое?

Спасибо


person Jean-Pat    schedule 18.02.2014    source источник
comment
проверьте свои типы данных. Предполагается, что целые числа находятся в диапазоне [0, 256), числа с плавающей запятой находятся в диапазоне [0, 1] и явно не проверяют эти предположения. также, пожалуйста, не подписывайте свои посты, ваш юзерблок уже внизу.   -  person tacaswell    schedule 18.02.2014
comment
Тип dtype нового изображения resized_rgb[0] — float64! Но если я делаю plot(np.uint8(resized_rgb[0][25,17:38,:])), изображение все еще синее...   -  person Jean-Pat    schedule 18.02.2014
comment
Тип изображения теперь в порядке. Спасибо!   -  person Jean-Pat    schedule 18.02.2014
comment
Можете ли вы написать ответ, объясняющий, как вы это исправили? (а затем примите это, когда SO позволит вам).   -  person tacaswell    schedule 18.02.2014
comment
Здесь есть функция ResizeImages() bit.ly/1dICsaQ (облачный проект sagemath). Проблема была устранена путем указания значения dtype следующего изображения: newIm=np.zeros((maxheight,maxwidth,components), dtype=imtype). Затем меньшее изображение вставляется в большее: newIm[start:start+height,startw:startw+width,:]=ImList[i][:,:,:] . Так как маленький uint8, новый тоже uint8.   -  person Jean-Pat    schedule 18.02.2014
comment
как фактический ответ, а не комментарий, пожалуйста. Это так: а) это более настойчиво б) вы можете получить репутацию за свой ответ;)   -  person tacaswell    schedule 18.02.2014


Ответы (2)


Предположим, у вас есть список изображений rgb, то есть стек из 3 массивов numpy uint8, и вам нужно добавить границы, чтобы все изображения имели одинаковую форму. следующая функция выполняет эту работу:

def ResizeImages(ImList):
        '''Find the largest width and height of images belonging to a list.
        Return a list of images of same width/height
        '''
        maxwidth=0
        maxheight=0
        components = np.shape(ImList[0])[2]
        imtype = ImList[0].dtype
        for i in range(len(ImList)):
            width=np.shape(ImList[i])[1]#width=column
            height=np.shape(ImList[i])[0]#height=line
            #print "width:height",width,":",height
            if width>maxwidth:maxwidth=width
            if height>maxheight:maxheight=height
        #print "maxwidth:maxheight",maxwidth,":",maxheight                
        NewList=[]
        for i in range(0,len(ImList)):
            width=np.shape(ImList[i])[1]
            height=np.shape(ImList[i])[0]

            diffw=maxwidth-width
            startw=round(diffw/2)
            diffh=maxheight-height
            starth=int(round(diffh/2))
            startw=int(round(diffw/2))

            newIm=np.zeros((maxheight,maxwidth,components), dtype=imtype)
            newIm[starth:starth+height,startw:startw+width,:]=ImList[i][:,:,:]
            NewList.append(newIm)
        return NewList

Каждое изображение, размер которого нужно изменить, вставляется в изображение, сначала заполненное нулями типа dtype=uint8 (поскольку в функции отправляются массивы uint8):

newIm=np.zeros((maxheight,maxwidth,components), dtype=imtype)
newIm[starth:starth+height,startw:startw+width,:]=ImList[i][:,:,:]

Баг был здесь:

newIm=np.zeros((maxheight,maxwidth,components))

Поскольку тип не был указан, тип по умолчанию был float64, что объясняет, почему цвет изображений с измененным размером выглядит странно.

person Jean-Pat    schedule 18.02.2014

См. разделы Imshow с той же цветовой полосой и Установите диапазон цветовых полос в matplotlib.

Если вы используете одни и те же vmin/vmax и cmap во всех вызовах imshow, цвета должны отражать одинаковую интенсивность, независимо от общего диапазона изображения.

Изменить: добавлен пример после комментариев. Возможно, я неправильно понял, в чем проблема, но код/изображение иллюстрируют, как можно установить ограничения v для соответствия цветам (верхний ряд) или что произойдет, если каждое изображение будет автоматически нормализовано (нижний ряд).

import numpy as np
import matplotlib.pyplot as plt 
import matplotlib.cm as cm

offset = 5.5

x1 = np.random.rand(12,16) + offset
x2 = np.array(x1)
x2 = np.zeros((15, 20))
x2[2:2+x1.shape[0], 3:3+x1.shape[1]] = x1

vmin = x1.min()
vmax = x1.max()

cmap = cm.hot

plt.figure(1); plt.clf()
f, ax = plt.subplots(2,2, num=1)

im0 = ax[0,0].imshow(x1, interpolation='nearest', cmap=cmap, vmin=vmin, vmax=vmax)
f.colorbar(im0, ax=ax[0,0])

im1 = ax[0,1].imshow(x2, interpolation='nearest', cmap=cmap, vmin=vmin, vmax=vmax)
f.colorbar(im1, ax=ax[0,1])
ax[0,1].set_title('image with border, sharing v lims')

im2 = ax[1,0].imshow(x1, interpolation='nearest', cmap=cmap)
f.colorbar(im2, ax=ax[1,0])

im3 = ax[1,1].imshow(x2, interpolation='nearest', cmap=cmap)
f.colorbar(im3, ax=ax[1,1])
ax[1,1].set_title('image with border, own v lims')

f.show()

эффект ограничений на совместное использование

Примечание. Проблема проявляется только в том случае, если ненулевой цветовой диапазон не включает ноль. Это показано с помощью переменной offset выше.

person Bonlenfum    schedule 18.02.2014
comment
изменение vmin / vmax (cmap=pylab.cm.Greys_r/Greys) не влияет на цветное изображение - person Jean-Pat; 18.02.2014
comment
Я не понимаю вашего комментария. Вы предполагаете, что установка этих значений не может влиять на цветные изображения или что они не влияют на ваше изображение? Я добавил пример кода, который может помочь решить эту проблему? - person Bonlenfum; 18.02.2014
comment
Например, изменение значения vmax не влияет на способ отображения изображения. Наблюдая за вашим кодом, я замечаю, что x2 является монохромным изображением: np.shape(x2) дает (15,20), тогда как изображения в моем примере представляют собой изображение rgb, которое представляет собой стек из 3 массивов numpy, их размер, например, (47, 54,3) - person Jean-Pat; 18.02.2014
comment
цветовая карта используется только при передаче скалярных массивов, если массивы mxnx[3,4] передаются в цветах, используются напрямую. - person tacaswell; 18.02.2014
comment
Ах хорошее место! Я вижу, что в imshow docs указано, что хотя я пропустил это раньше . К сожалению, в этом случае он не предлагает никаких предложений по искусственному окрашиванию. Этот руководство по MPL предлагает используя псевдоцвета, беря только одно из измерений (или, очевидно, смешивая rgb->оттенки серого). Но это может не подходить для ваших данных. - person Bonlenfum; 18.02.2014