7

I have code that looks like this

from skimage import io as sio
test_image = imread('/home/username/pat/file.png')
test_image  = skimage.transform.resize(test_image, (IMG_HEIGHT, IMG_WIDTH), mode='constant', preserve_range=True)
print test_image.shape # prints (128,128)
print test_image.max(), test_image.min() # prints 65535.0 0.0
sio.imshow(test_image)

More importantly, I need to make this image be in 3 channels, so I can feed it into a neural network that expects such input, any idea how to do that?

I want to transform a 1-channel image into a 3-channel image that looks reasonable when I plot it, makes sense, etc. How?

I tried padding with 0s, I tried copying the same values 3 times for the 3 channels, but then when I try to display the image, it looks like gibberish. So how can I transform the image into 3 channels, even if it becomes something like, bluescale instead of greyscale, but still be able to visualize it in a meaningful way?

Edit: if I try

test_image = skimage.color.gray2rgb(test_image)

I get all white image, with some black dots.

I get the same all white, rare small black dots if I try

convert Test1_PC_1.tif -colorspace sRGB -type truecolor Test1_PC_1_new.tif

Before the attempted transform with gray2rgb

print type(test_image[0,0])
<type 'numpy.uint16'>

After

print type(test_image[0,0,0])
<type 'numpy.float64'>
martineau
  • 119,623
  • 25
  • 170
  • 301
Baron Yugovich
  • 3,843
  • 12
  • 48
  • 76
  • It (probably) comes out colored because you did not set a colormap and the default is somewhat a bad choice here. Nobody can tell you how to *magically* derive colors for some NN which is unknown, as most NNs used for natural colors will fail completely with this one. – sascha Aug 11 '18 at 21:29
  • 1
    Have you tried `gray2rgb`? http://scikit-image.org/docs/dev/api/skimage.color.html#skimage.color.gray2rgb – Håken Lid Aug 11 '18 at 23:05

3 Answers3

9

You need to convert the array from 2D to 3D, where the third dimension is the color.

You can use the gray2rgb function function provided by skimage:

test_image = skimage.color.gray2rgb(test_image)

Alternatively, you can write your own conversion -- which gives you some flexibility to tweak the pixel values:

# basic conversion from gray to RGB encoding
test_image = np.array([[[s,s,s] for s in r] for r in test_image],dtype="u1")

# conversion from gray to RGB encoding -- putting the image in the green channel
test_image = np.array([[[0,s,0] for s in r] for r in test_image],dtype="u1")

I notice from your max() value, that you're using 16-bit sample values (which is uncommon). You'll want a different dtype, maybe "u16" or "int32". Also, you may need to play some games to make the image display with the correct polarity (it may appear with black/white reversed).

One way to get there is to just invert all of the pixel values:

test_image = 65535-test_image ## invert 16-bit pixels

Or you could look into the norm parameter to imshow, which appears to have an inverse function.

Brent Bradburn
  • 51,587
  • 17
  • 154
  • 173
  • Thanks, will try. Can you please elaborate a bit on the dtype stuff? Also, do you have any logical explanation as to why my original attempt doesn't work? – Baron Yugovich Aug 12 '18 at 01:25
  • I tried test_image = skimage.color.gray2rgb(test_image), I get a white image with some rare small black dots, doesn't work. – Baron Yugovich Aug 12 '18 at 01:27
  • `dtype` sets the numeric data type used inside the array. You may want to pay special attention to that. Try printing the type of the sample values before and after the conversion to make sure something didn't change radically. 2D: `print type(test_image[0,0])` 3D: `print type(test_image[0,0,0])` – Brent Bradburn Aug 12 '18 at 01:30
  • The [imshow docs](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.imshow.html) say `cmap is ignored if X is 3-D, directly specifying RGB(A) values.` This is my guess as to why you aren't seeing something sensible. See what happens if you invert the image. – Brent Bradburn Aug 12 '18 at 01:35
  • How would I invert the image, what is the exact command? Also, please see the edits I made to the original question above. – Baron Yugovich Aug 12 '18 at 01:36
  • The suggested command to invert the image is `test_image = 65535-test_image`. That is based on the assumption that your values range from 0..65535. It could help if you included the original grayscale image in your question, since not having that leaves me to guess about exactly what you are seeing. – Brent Bradburn Aug 12 '18 at 02:55
  • Also, the `transform.resize` seems to be converting the image to floating-point, which further complicates things. You might try leaving that step out while you sort out the conversion from gray to RGB. – Brent Bradburn Aug 12 '18 at 03:06
4

Your conversion from gray-value to RGB by replicating the gray-value three times such that R==G==B is correct.

The strange displayed result is likely caused by assumptions made during display. You will need to scale your data before display to fix it.

Usually, a uint8 image has values 0-255, which are mapped to min-max scale of display. Uint16 has values 0-65535, with 65535 mapped to max. Floating-point images are very often assumed to be in the range 0-1, with 1 mapped to max. Any larger value will then also be mapped to max. This is why you see so much white in your output image.

If you divide each output sample by the maximum value in your image you’ll be able to display it properly.

Cris Luengo
  • 55,762
  • 10
  • 62
  • 120
2

Well, imshow is using by default, a kind of heatmap to display the image intensities. To display a grayscale image just specify the colormap as above:

plt.imshow(image, cmap="gray")

Now, i think you can get the channel of an image by doing:

image[:,:,i] where i is in {0,1,2}

To extract an image for a specific channel:

red_image = image.copy()
red_image[:,:,1] = 0
red_image[:,:,2] = 0

Edit: Do you definitely have to use skimage? What about python-opencv module? Have you tried the following example?

import cv2
import cv

color_img = cv2.cvtColor(gray_img, cv.CV_GRAY2RGB)
curi0uz_k0d3r
  • 505
  • 2
  • 9