ilastik / ilastik

ilastik-shell, applets, and workflows to string them together.
https://ilastik.org
Other
349 stars 130 forks source link

Color table list index out of range in labeling gui #933

Open martinsch opened 10 years ago

martinsch commented 10 years ago

When adding more than 16 label classes, the labeling gui throws a "list index out of range" exception. Tested with object classification.

Quick workaround: disable "add label" after 15 label classes.

ERROR 2014-07-03 14:11:58,912 log_exception 15669 140300557887296 Logged the above exception just in case PyQt loses it.
ERROR 2014-07-03 14:11:58,912 excepthooks 15669 140300557887296 Traceback (most recent call last):
  File "/home/mschiegg/software/ilastik06/ilastik/ilastik/utility/bind.py", line 64, in __call__
    self.f(*(self.bound_args + args[0:self.numUnboundArgs]))
  File "/home/mschiegg/software/ilastik06/ilastik/ilastik/applets/labeling/labelingGui.py", line 570, in _addNewLabel
    self._labelingSlots.labelNames.setValue( operator_names, check_changed=False )
  File "/home/mschiegg/ilastik06/lazyflow/lazyflow/slot.py", line 89, in call_in_setup_context
    return func(self, *args, **kwargs)
  File "/home/mschiegg/ilastik06/lazyflow/lazyflow/graph.py", line 136, in __exit__
    sig_setup_complete()
  File "/home/mschiegg/ilastik06/lazyflow/lazyflow/utility/orderedSignal.py", line 73, in __call__
    f(*args, **kw)
  File "/home/mschiegg/software/ilastik06/ilastik/ilastik/utility/gui/threadRouter.py", line 70, in routed
    val = func(*args, **kwargs)
  File "/home/mschiegg/software/ilastik06/ilastik/ilastik/applets/layerViewer/layerViewerGui.py", line 401, in updateAllLayers
    newGuiLayers = self.setupLayers()
  File "/home/mschiegg/software/ilastik06/ilastik/ilastik/applets/objectClassification/objectClassificationGui.py", line 590, in setupLayers
    self._setPredictionColorTableForRow( predictLayer, row )
  File "/home/mschiegg/software/ilastik06/ilastik/ilastik/applets/objectClassification/objectClassificationGui.py", line 661, in _setPredictionColorTableForRow
    oldcolor = self._colorTable16_forpmaps[row+1]
IndexError: list index out of range
akreshuk commented 7 years ago

This is still a problem in object classification, but not in pixel classification. Also, it's interesting to see how much the adding of labels slows down as you add more. Adding label 15 is much much slower than label 2 in pixel classification.

stuarteberg commented 6 years ago

Apparently this is still an issue in Pixel Classification. @anjalitaneja94 encountered this when attempting to use more than 16 colors.

ERROR 2018-02-27 14:04:22,131 excepthooks 31219 140626135111424 Unhandled exception in thread: 'MainThread'
ERROR 2018-02-27 14:04:22,133 excepthooks 31219 140626135111424 Traceback (most recent call last):
  File "/opt/ilastik-1.3.0-Linux/ilastik-meta/ilastik/ilastik/shell/gui/ilastikShell.py", line 627, in openFileAndCloseStartscreen
    self.openProjectFile(path)
  File "/opt/ilastik-1.3.0-Linux/ilastik-meta/ilastik/ilastik/shell/gui/ilastikShell.py", line 1448, in openProjectFile
    self._loadProject(hdf5File, projectFilePath, workflow_class, readOnly)
  File "/opt/ilastik-1.3.0-Linux/ilastik-meta/ilastik/ilastik/shell/gui/ilastikShell.py", line 1561, in _loadProject
    self.setSelectedAppletDrawer(appletName)
  File "/opt/ilastik-1.3.0-Linux/ilastik-meta/ilastik/ilastik/shell/gui/ilastikShell.py", line 1084, in setSelectedAppletDrawer
    self.showCentralWidget(applet_index)
  File "/opt/ilastik-1.3.0-Linux/ilastik-meta/ilastik/ilastik/shell/gui/ilastikShell.py", line 1099, in showCentralWidget
    centralWidget = self._applets[applet_index].getMultiLaneGui().centralWidget()
  File "/opt/ilastik-1.3.0-Linux/ilastik-meta/ilastik/ilastik/applets/base/singleToMultiGuiAdapter.py", line 64, in centralWidget
    if self.currentGui() is None:
  File "/opt/ilastik-1.3.0-Linux/ilastik-meta/ilastik/ilastik/applets/base/singleToMultiGuiAdapter.py", line 44, in currentGui
    self._guis[self._imageLaneIndex] = self.singleImageGuiFactory( self._imageLaneIndex )
  File "/opt/ilastik-1.3.0-Linux/ilastik-meta/ilastik/ilastik/applets/base/standardApplet.py", line 142, in __createSingleLaneGui
    return self.singleLaneGuiClass( self, singleLaneOperator )
  File "/opt/ilastik-1.3.0-Linux/ilastik-meta/ilastik/ilastik/applets/layerViewer/layerViewerGui.py", line 72, in __call__
    instance._after_init()
  File "/opt/ilastik-1.3.0-Linux/ilastik-meta/ilastik/ilastik/applets/layerViewer/layerViewerGui.py", line 192, in _after_init
    self.updateAllLayers()
  File "/opt/ilastik-1.3.0-Linux/ilastik-meta/ilastik/ilastik/utility/gui/threadRouter.py", line 76, in routed
    val = func(*args, **kwargs)
  File "/opt/ilastik-1.3.0-Linux/ilastik-meta/ilastik/ilastik/applets/layerViewer/layerViewerGui.py", line 427, in updateAllLayers
    newGuiLayers = self.setupLayers()
  File "/opt/ilastik-1.3.0-Linux/ilastik-meta/ilastik/ilastik/applets/pixelClassification/pixelClassificationGui.py", line 575, in setupLayers
    layers = super(PixelClassificationGui, self).setupLayers()
  File "/opt/ilastik-1.3.0-Linux/ilastik-meta/ilastik/ilastik/applets/labeling/labelingGui.py", line 842, in setupLayers
    self._updateLabelList()
  File "/opt/ilastik-1.3.0-Linux/ilastik-meta/ilastik/ilastik/applets/labeling/labelingGui.py", line 590, in _updateLabelList
    self._addNewLabel()
  File "/opt/ilastik-1.3.0-Linux/ilastik-meta/ilastik/ilastik/applets/labeling/labelingGui.py", line 633, in _addNewLabel
    self.onLabelListDataChanged(newColorIndex, newColorIndex) # Make sure label layer colortable is in sync with the new color
  File "/opt/ilastik-1.3.0-Linux/ilastik-meta/ilastik/ilastik/applets/labeling/labelingGui.py", line 308, in onLabelListDataChanged
    self._colorTable16[firstRow+1] = color.rgba()
IndexError: list assignment index out of range
akreshuk commented 6 years ago

let's bind fixing this issue with finally making the colortable for the first colors color-blind friendly.

stuarteberg commented 6 years ago

Any hope for a patch in the meantime?

stuarteberg commented 6 years ago

Locally, on @anjalitaneja94's computer, I tried simply extending the colortable in labelingGui.py with more colors, and it seems to work just fine. I didn't do extensive testing by any means, but pixel classification allows you to put down brushstrokes and make predictions.

akreshuk commented 6 years ago

I have no problem in pixel classification, are you doing something more than just adding labels? I tried adding, renaming, changing color, it works fine. image

akreshuk commented 6 years ago

Oops, found it, works fine the first time, but you can't load the project afterwards. We'll fix it, stay tuned.

k-dominik commented 6 years ago

In Object classification it will fail with the 16th added label - no saving / loading required

akreshuk commented 6 years ago

For Pixel Classification I now see what the problem is: there is this function called _getNext() in PixelClassificationGui.py It compares the currently requested label number with the total number already present in the slot argument and returns an old one if the slot contains enough. The problem is, the slot is filled by the deserializer, but the LabelingGui._colorTable16 is not in sync after deserialization.

wolny commented 6 years ago

Looks like the functionality of adding labels is inconsistent between PixelClassificationGui and ObjectClassificationGui. The logic for returning new colors for labels has side effects in many places and involves dancing with the colorTable indexing which sometimes throws index our of range errors. I'd say we fix that first by encapsulating the logic related to the labeling/colorTable in a separate class which exposes a clean interface for the LabelingGui and using this class in LabelingGui. Then we hunt those bugs one-by-one. @akreshuk re

it's interesting to see how much the adding of labels slows down as you add more. Adding label 15 is much much slower than label 2 in pixel classification.

There is this convoluted logic of returning a new lablel name: https://github.com/ilastik/ilastik/blob/master/ilastik/applets/labeling/labelingGui.py#L670. Every time you want a new label name, it scans the whole label list parses the numbers and gives you the max+1 for the new label name. It's quite heavy and has a complexity of O(n), where n is the number of labels currently in the list. So yeah adding labels slows down as you add more...