vtkImageMapToColors display a wrong color

I am using vtkImageMapToColors to map gray image to color image. My image has only 0/1 value:

img = vtk.vtkImageData()
img.SetDimensions(256, 256, 1)
img.AllocateScalars(vtk.VTK_INT, 1)

for i in range(256):
    for j in range(256):

        if i > 128 and i<192 and j>128 and j<192:
            img.SetScalarComponentFromFloat(i, j, 0, 0, 1)
        else:
            img.SetScalarComponentFromFloat(i, j, 0, 0, 0)

If the color table is given as:

colorTable = vtk.vtkWindowLevelLookupTable()
colorTable.SetNumberOfTableValues(2)
colorTable.SetTableValue(0, 1, 1, 1, 1)
colorTable.SetTableValue(1, 1, 0, 0, 1)
colorTable.Build()

The shown result is what I expect:

image

But, if the color table is given as:

colorTable = vtk.vtkWindowLevelLookupTable()
colorTable.SetNumberOfTableValues(3)
colorTable.SetTableValue(0, 1, 1, 1, 1)
colorTable.SetTableValue(1, 1, 0, 0, 1)
colorTable.SetTableValue(2, 1, 1, 0, 1)
colorTable.Build()

The shown result is:

image

I hope the color part is red, because the value in image is 1, and colorTable.SetTableValue(1, 1, 0, 0, 1). I don’t know why the color part is yellow.

The complete code to reproduce my problem is:

import vtkmodules.all as vtk

img = vtk.vtkImageData()
img.SetDimensions(256, 256, 1)
img.AllocateScalars(vtk.VTK_INT, 1)

for i in range(256):
    for j in range(256):

        if i > 128 and i<192 and j>128 and j<192:
            img.SetScalarComponentFromFloat(i, j, 0, 0, 1)
        else:
            img.SetScalarComponentFromFloat(i, j, 0, 0, 0)

colorTable = vtk.vtkWindowLevelLookupTable()
colorTable.SetNumberOfTableValues(3)
colorTable.SetTableValue(0, 1, 1, 1, 1)
colorTable.SetTableValue(1, 1, 0, 0, 1)
colorTable.SetTableValue(2, 1, 1, 0, 1)
colorTable.Build()

mapToColor = vtk.vtkImageMapToColors()
mapToColor.SetInputData(img)
mapToColor.SetLookupTable(colorTable)

imgMapper = vtk.vtkImageSliceMapper()
imgMapper.SetInputConnection(mapToColor.GetOutputPort())
imgSlice = vtk.vtkImageSlice()
imgSlice.SetMapper(imgMapper)

render = vtk.vtkRenderer()
render.AddActor(imgSlice)
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(render)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)
iren.Initialize()
iren.Start()

By default, vtkLookupTable will map an input value of zero to the first color, and an input value of one to the last color. In other words, by default the lookup table assumes that the input data is a set of floating-point values between 0.0 and 1.0.

You can set the Range of the table to make it map integers directly to colors:

colorTable.SetRange(0, colorTable.GetNumberOfTableValues() - 1)

For example, if the table has 3 values, this sets the Range to [0, 2].

1 Like

Thanks for kindly reply. I have another question. When I modify the setting as:

colorTable = vtk.vtkWindowLevelLookupTable()
colorTable.IndexedLookupOn() ################# only categorical data is considered
colorTable.SetNumberOfTableValues(3)
colorTable.SetTableRange(0, 2)
colorTable.SetTableValue(0, 1, 1, 1, 1)
colorTable.SetTableValue(1, 1, 0, 0, 1)
colorTable.SetTableValue(2, 1, 1, 0, 1)
colorTable.Build()

In this setting, I add colorTable.IndexedLookupOn(), and the result is:

image

How to use IndexedLookupOn?

For IndexedLookupOn() to work, you must add annotations to the lookup table. I’ve never used it, so I don’t have anything else to say about it.

1 Like

@dgobbi Thanks for kindly reply. IndexedLookupOn() works with the following setting:

colorTable = vtk.vtkWindowLevelLookupTable()
colorTable.IndexedLookupOn()
colorTable.SetNumberOfTableValues(3)
colorTable.SetTableValue(0, 1, 1, 1, 1)
colorTable.SetTableValue(1, 1, 0, 0, 1)
colorTable.SetTableValue(2, 1, 1, 0, 1)


colorTable.SetAnnotation(0, 'white')
colorTable.SetAnnotation(1, 'red')
colorTable.SetAnnotation(2, 'yellow')

colorTable.Build()