Jet colormap to grayscale

2019-03-27 12:42发布

I have a jet colormap:

jet colormap

and I would like to know if there's some way to convert to a grayscale. I can't use average because maximum and minimum value goes to the same gray color. Or if there's some way to convert to another color palette.

I can't find on Google a function to convert it. MATLAB uses some thing called rgb2ind but I would like to know the formula.

4条回答
冷血范
2楼-- · 2019-03-27 12:59

rgb2ind converts the RGB values for each pixel into indices within a color map. If you use the 2 input version with a color map input, then it will look-up the closest color in the color map that matches each pixel. This will basically give you a single number for each pixel, rather than an RGB value.

For example, if you load your image

RGB = imread(imagefilename);

then, since the Jet color map is returned by jet, then you can get the indexed data using

mapsize = 256;
map = jet(mapsize);
ind = rgb2ind(RGB, map);

You can then display the image using any color map

colormap(map)
image(ind)
colormap('gray')

Don't use imagesc because it may stretch the dynamic range of your image unacceptably.

查看更多
Juvenile、少年°
3楼-- · 2019-03-27 13:03

Python implementation of the answer given by teng (assuming a default matplotlib jetmap).

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


def PIL2array(img):
    return numpy.array(img.getdata(),
                numpy.uint8).reshape(img.size[1], img.size[0], 3)
def array2PIL(arr, size):
    mode = 'RGBA'
    arr = arr.reshape(arr.shape[0]*arr.shape[1], arr.shape[2])
    if len(arr[0]) == 3:
       arr = numpy.c_[arr, 255*numpy.ones((len(arr),1), numpy.uint8)]
    return Image.frombuffer(mode, size, arr.tostring(), 'raw', mode, 0, 1)

def return_x(y,color,direction):

    if color == "blue" and direction == "up":
       m = (4.0 + 6.0/11.0)
       c = 0.5
    elif color == "blue" and direction == "down":
       m = -3.226
       c = 2.097
    elif color == "green" and direction == "up":
       m = 4.0
       c = -0.5
    elif color == "green" and direction == "down":
       m = -3.704
       c = 3.370
    elif color == "red" and direction == "up":
       m = 3.223
       c = -1.129
    elif color == "red" and direction == "down":
       m = -4.545
       c = 5.041
    else:
       print "Returning y:: INCORRECT OPTIONS"
       m = 1
       c = 0

    return (y-c)/m 

# x >= y
def big_equal(x,y):
    return x > y or np.allclose(x,y)

# x <= y
def less_equal(x,y):
    return x < y or np.allclose(x,y)

def convert_jet_to_grey(img_array,n):
    new_image = np.zeros((img_array.shape[0],img_array.shape[1]))
    for i in range(img_array.shape[0]):
        for j in range(img_array.shape[1]):
            pixel_blue = img_array[i,j,2]
            pixel_green = img_array[i,j,1]
            pixel_red = img_array[i,j,0]
            if (pixel_blue < 1) and big_equal(pixel_blue,0.5) and less_equal(pixel_green,0.5) :
               #print "a1"
               #print "i,j = ",i,",",j
               new_image[i,j] = return_x(pixel_blue,"blue","up")**n
            elif np.allclose(pixel_blue,1.0) and big_equal(pixel_green,0):
                 #print "b1"
                 #print "i,j = ",i,",",j
                 new_image[i,j] = return_x(pixel_green,"green","up")**n
            elif (pixel_blue < 1) and big_equal(pixel_blue,0.4) and big_equal(pixel_green,0.5):
                 #print "c1"
                 #print "i,j = ",i,",",j
                 new_image[i,j] = return_x(pixel_green,"blue","down")**n
            elif (pixel_red < 1) and big_equal(pixel_red,0.4) and big_equal(pixel_green,0.5):
                 #print "c2"
                 #print "i,j = ",i,",",j
                 new_image[i,j] = return_x(pixel_green,"red","up")**n
            elif np.allclose(pixel_red,1.0) and big_equal(pixel_green,0):
                 #print "b2"
                 #print "i,j = ",i,",",j
                 new_image[i,j] = return_x(pixel_green,"green","down")**n
            elif (pixel_red < 1) and big_equal(pixel_red,0.5) and less_equal(pixel_green,0.5):
           #print "a2"
           #print "i,j = ",i,",",j
           new_image[i,j] = return_x(pixel_blue,"red","down")**n
        else:
           print "Leaving 0:: NOT A JET IMAGE"

return new_image

def main():


   img = Image.open('test.jpg')
   arr = PIL2array(img)

   img_new = convert_jet_to_grey(arr/255.0,1)
   imgplot = plt.imshow(img_new)
   plt.show()

if __name__ == '__main__':
   main()
查看更多
冷血范
4楼-- · 2019-03-27 13:04

First let me create an indexed image using the Jet colormap:

img = repmat(uint8(0:255), 100, 1);
cmap = jet(256);

imshow(img, 'Colormap',cmap)

jet

The straightforward conversion using IND2GRAY produces the following:

J = ind2gray(img,cmap);
imshow(J)

jet_to_gray

As you expressed, the min/max converge to the same value. From what I understood, you are looking to map the jet colormap to linearly go from dark to light shades of gray. For this, we can reorder using the hue value which we get with the RGB2HSV function. Compare the following against the original colormap:

[~,idx] = sortrows(rgb2hsv(cmap), -1);  %# sort by Hue
C = gray(256);
C = C(idx,:);

imshow(img, 'Colormap',C)

hue_sorted

查看更多
淡お忘
5楼-- · 2019-03-27 13:19

create the image in MATLAB

image(1:64);axis off;colormap(jet);

save the image as tiff, crop out the borders with Paintbrush and save as '\directorypath\jetmage.tiff'.

load the image in MATLAB

jetmage=imread('\\directorypath\jetmage.tiff');

get image size

[szX,szY,szZ]=size(jetmage);

get a row of image for each color, red, green and blue.

r=reshape(jetmage(uint8(szX/2),:,1),[szY,1]);
g=reshape(jetmage(uint8(szX/2),:,2),[szY,1]);
b=reshape(jetmage(uint8(szX/2),:,3),[szY,1]);

plot the intensity profile for each color for that row.

plot(r,'r-');hold on;
plot(g,'g-');hold on;
plot(b,'b-');hold on;

The plot should be something like so:

enter image description here

you can use array [r,g,b] as the look-up-table or base on that figure out a way to get the 'formula' from array [r,g,b]

查看更多
登录 后发表回答