3

I can load a TIFF image into memory as a NumPy array where each pixel is represented by a 3-element RGB vector:

from PIL import Image
import numpy as np
arr=np.array(Image.open(imgfn))

For example the arr above might have shape (2469,2858,3).

Follow the Bokeh docs, in Bokeh, pixels are 1D numbers that are interpreted with respect to a color map.

How do I map my 3D RGB TIFF array into a 1D Bokeh colormap index array, and what colormap should I use?

This post suggest I should write something called an RGBAColorMapper. How do I do that?

There is also something call image_rgba which is a 4D pixel, how would I translate 3D pixels to 4D to use that?

Basically I'm looking for the same functionality as MatPlotLib imshow.

Oren
  • 4,711
  • 4
  • 37
  • 63
Lars Ericson
  • 1,952
  • 4
  • 32
  • 45
  • 1
    I know nothing about bokeh, but an RGBA (4d) image is just an 3d RGB image as you already have with another channel representing alpha (opacity/transparency) so you can just add an extra channel wherein all values are 255 meaning *”fully opaque”*. – Mark Setchell Jun 28 '18 at 12:58
  • "The answer should be a Python script using Bokeh to display a TIFF image loaded into an Y rows by X columns by 3 RGB Numpy array." That's what I'm paying my 50 brownie points for. – Lars Ericson Jun 28 '18 at 13:56

2 Answers2

6

You can convert a tiff image to rgba using the PIL package. It is then straightforward to plot this with image_rgba. The tiff file was downloaded from http://www-eng-x.llnl.gov/documents/tests/tiff.html, following the SO answer posted here.

import numpy

from PIL import Image
from bokeh.plotting import figure, show

im = Image.open('a_image.tif')
im = im.convert("RGBA")
# uncomment to compare
#im.show()
imarray = numpy.array(im)

p = figure(x_range=(0,10), y_range=(0,1), width=1000, height=200)

p.image_rgba(image=[imarray], x=0, y=0, dw=10, dh=1)

show(p)

enter image description here

Anthonydouc
  • 3,334
  • 1
  • 16
  • 29
1

I am not sure the previous solution work, the tiff does not exists anymore so I can't test it. Anyway, for any other image do the following:

from PIL import Image
import numpy as np 
from bokeh.plotting import figure, output_notebook, show

output_notebook()

#load image
im = Image.open('Segment_image.png') # just replace any image that you want here
imarray = np.array(im.convert("RGBA"))

p = figure()
plotted_image = p.image_rgba(image=[imarray.view("uint32").reshape(imarray.shape[:2])], x=0, y=0, dw=imarray.shape[0], dh=imarray.shape[1])
show(p)
Oren
  • 4,711
  • 4
  • 37
  • 63