Source code for layer_viewer.layers.label_layer
from . layer_base import LayerBase
from .. widgets import TrippleToggleEye, ToggleEye, FractionSelectionBar
from .. distinct_colors import *
from .. pixel_path import *
from . layer_controller import *
from .. widgets import TrippleToggleEye, ToggleEye, FractionSelectionBar, GradientWidget
import pyqtgraph as pg
import os
from pyqtgraph.Qt import QtCore, QtGui
import numpy
###############################################################################
from builtins import range
#from past.utils import old_div
import warnings
from PyQt5.QtCore import pyqtSignal, Qt, QEvent, QRect, QSize, QTimer, QPoint, QItemSelectionModel
from PyQt5.QtGui import QPainter, QFontMetrics, QFont, QPalette, QMouseEvent, QPixmap
from PyQt5.QtWidgets import QStyledItemDelegate, QWidget, QListView, QStyle, \
QLabel, QGridLayout, QSpinBox, QApplication
[docs]class LabelLayer(LayerBase):
labelsChangedSignal = pyqtSignal(object)
# the gui for the user in the layer stack
[docs] class CtrlWidget( QWidget ):
def __init__( self, name=None, parent=None, current_label=1, disc_rad=1):
super(LabelLayer.CtrlWidget, self).__init__( parent=parent )
#self._layer = None
self._font = QFont(QFont().defaultFamily(), 9)
self._fm = QFontMetrics( self._font )
self.bar = FractionSelectionBar( initial_fraction = 1. )
self.bar.setFixedHeight(10)
self.nameLabel = QLabel( parent=self )
self.nameLabel.setFont( self._font )
self.nameLabel.setText(str(name) )
self.opacityLabel = QLabel( parent=self )
self.opacityLabel.setAlignment(Qt.AlignRight)
self.opacityLabel.setFont( self._font )
self.opacityLabel.setText( u"\u03B1=%0.1f%%" % (100.0*(self.bar.fraction())))
self.toggleEye = TrippleToggleEye( parent=self )
self.toggleEye.setActive(True)
self.toggleEye.setFixedWidth(35)
self.toggleEye.setToolTip("Visibility")
self.channelSelector = QSpinBox( parent=self )
self.channelSelector.setFrame( False )
self.channelSelector.setFont( self._font )
self.channelSelector.setMaximumWidth( 35 )
self.channelSelector.setAlignment(Qt.AlignRight)
self.channelSelector.setToolTip("Channel")
self.channelSelector.setVisible(False)
self._layout = QtGui.QGridLayout(self )
self._layout.addWidget( self.toggleEye, 0, 0 )
self._layout.addWidget( self.nameLabel, 0, 1 )
self._layout.addWidget( self.opacityLabel, 0, 2 )
self._layout.addWidget( self.channelSelector, 1, 0)
self._layout.addWidget( self.bar, 1, 1, 1, 2 )
self.labelLabel = QLabel( parent=self )
self.labelLabel.setAlignment(Qt.AlignRight)
self.labelLabel.setFont( self._font )
self.labelLabel.setText("Label:")
self._layout.addWidget( self.labelLabel, 3,0,1,1)
self.labelSelector = QSpinBox( parent=self )
self.labelSelector.setFrame( False )
self.labelSelector.setFont( self._font )
self.labelSelector.setMaximumWidth( 35 )
self.labelSelector.setAlignment(Qt.AlignRight)
self.labelSelector.setToolTip("Label")
self.labelSelector.setVisible(True)
self.labelSelector.setMinimum(0)
self.labelSelector.setMaximum(255)
self.labelSelector.setValue(current_label)
self._layout.addWidget( self.labelSelector, 3,1,1,1)
self.brushLabel = QLabel( parent=self )
self.brushLabel.setAlignment(Qt.AlignRight)
self.brushLabel.setFont( self._font )
self.brushLabel.setText("Brush:")
self._layout.addWidget( self.brushLabel, 3,2,1,1)
self.brushSelector = QSpinBox( parent=self )
self.brushSelector.setFrame( False )
self.brushSelector.setFont( self._font )
self.brushSelector.setMaximumWidth( 35 )
self.brushSelector.setAlignment(Qt.AlignRight)
self.brushSelector.setToolTip("Brush")
self.brushSelector.setVisible(True)
self.brushSelector.setMinimum(0)
self.brushSelector.setMaximum(255)
self.brushSelector.setValue(disc_rad)
self._layout.addWidget( self.brushSelector, 3,3,1,1)
self._layout.setColumnMinimumWidth( 2, 35 )
self._layout.setSpacing(0)
self.setLayout( self._layout )
def f(frac):
self.opacityLabel.setText( u"\u03B1=%0.1f%%" % (100.0*(self.bar.fraction())))
self.bar.fractionChanged.connect(f)
[docs] def setFraction(self, opacity):
self.bar.setFraction(opacity)
self.opacityLabel.setText( u"\u03B1=%0.1f%%" % (100.0*(self.bar.fraction())))
# we need a special image item to handle mouse interaction
[docs] class LabelLayerImageItem(pg.ImageItem):
def __init__(self, label_layer):
super(LabelLayer.LabelLayerImageItem, self).__init__()
self.label_layer = label_layer
self.m_label_data = label_layer.m_label_data
self._pixel_path = label_layer._pixel_path
# otherwise we do not get key events?
self.setFlag(self.ItemIsFocusable, True)
[docs] def mouseDragEvent(self, ev):
modifiers = QtGui.QApplication.keyboardModifiers()
if modifiers != QtCore.Qt.ShiftModifier:
if ev.isStart():
self._pixel_path.clear()
self._pixel_path.add(ev.pos())
elif ev.isFinish():
# add the labels
self._pixel_path.insert_to_image(label_image=self.m_label_data,
label=self.label_layer.current_label,
rad=self.label_layer.disk_rad * [1,3][self.label_layer.current_label == 0]
)
# update image
self.setImage(self.m_label_data,
autoLevels=False)
self.label_layer.m_temp_path.setPath(QtGui.QPainterPath())
# send signal
self.label_layer.labelsChangedSignal.emit(self.label_layer)
else:
self._pixel_path.add(ev.pos())
self.label_layer.m_temp_path.setPath(self._pixel_path.qpath)
ev.accept()
[docs] def keyPressEvent(self, event):
modifiers = QtGui.QApplication.keyboardModifiers()
for label in range(10):
if event.key() == getattr(QtCore.Qt, f"Key_{label}"):
if modifiers == QtCore.Qt.ControlModifier:
self.label_layer.setCurrentDiskRadius(label)
else:
self.label_layer.setCurrentLabel(label)
event.accept()
break
if event.key() == QtCore.Qt.Key_E:
if modifiers != QtCore.Qt.ControlModifier:
self.label_layer.setCurrentLabel(0)
event.accept()
# we need a custom graphics item group to handle key interaction
[docs] class MyQGraphicsItemGroup(QtGui.QGraphicsItemGroup):
keyPressed = QtCore.pyqtSignal(QtCore.QEvent)
def __init__(self, image_item, temp_path):
super(LabelLayer.MyQGraphicsItemGroup, self).__init__()
self.image_item = image_item
self.temp_path = temp_path
self.addToGroup(self.image_item)
self.addToGroup(self.temp_path)
def __init__(self, name, data=None, lut=None):
super(LabelLayer, self).__init__(name=name)
self.lut =get_label_lut()
self.m_label_data = data
self.current_label = 1
self.disk_rad = 1
# self.m_image_item_group.setHandlesChildEvents
self.m_ctrl_widget = LabelLayer.CtrlWidget(name=self.name, current_label=self.current_label, disc_rad=self.disk_rad)
self._pixel_path = PixelPath()
self.m_image_item = LabelLayer.LabelLayerImageItem(label_layer=self)
self.m_image_item.setLookupTable(self.lut)
self.m_temp_path = QtGui.QGraphicsPathItem()
self._set_pen()
self.m_image_item_group = LabelLayer.MyQGraphicsItemGroup(self.m_image_item, self.m_temp_path)
if self.m_label_data is not None:
self.m_image_item.setImage(self.m_label_data, autoLevels=False)
self.m_image_item_group.addToGroup(self.m_image_item)
self.m_image_item_group.addToGroup(self.m_temp_path)
self.disk = disk(self.disk_rad)
#self.m_ctrl_widget.setLut(lut)
self.viewer = None
def _set_pen(self):
fac = [1,3][self.current_label == 0]
if self.current_label == 0:
color = (0,0,0, 255.0 * 0.7)
else:
color = self.lut[self.current_label,:]
p = pg.mkPen(color=color, width=fac*self.disk_rad*2 + 1,cosmetic=False)
p.setCapStyle(QtCore.Qt.RoundCap)
self.m_temp_path.setPen(p)
[docs] def ctrl_widget(self):
#print("ctrl")
w = self.m_ctrl_widget
# toggle eye
w.toggleEye.setActive(True)
def toogleEyeChanged(state):
if self.viewer.m_exlusive_layer is not None:
self.viewer.m_exlusive_layer.setVisible(True)
self.viewer.m_exlusive_layer = None
if state == 2:
self.viewer.showAndHideOthers(self.name)
else:
self.setVisible(bool(state))
w.toggleEye.stateChanged.connect(toogleEyeChanged)
# opacity
w.bar.fractionChanged.connect(self.setOpacity)
# current label
def onLabelChange(label):
self.current_label = label
self._set_pen()
w.labelSelector.valueChanged.connect(onLabelChange)
# current label
def onDiskSizeChange(disk_rad):
#print('disk_rad', disk_rad)
self.disk_rad = disk_rad
self._set_pen()
w.brushSelector.valueChanged.connect(onDiskSizeChange)
w.layer = self
return w
[docs] def setCurrentLabel(self, label):
self.current_label = label
self._set_pen()
self.m_ctrl_widget.labelSelector.setValue(label)
[docs] def setCurrentDiskRadius(self, rad):
self.disc_rad = rad
self._set_pen()
self.m_ctrl_widget.brushSelector.setValue(rad)
[docs] def setOpacity(self, opacity):
self.m_ctrl_widget.setFraction(opacity)
self.m_image_item_group.setOpacity(opacity)
[docs] def setVisible(self, visible):
self.m_ctrl_widget.toggleEye.setState(visible)
self.m_image_item_group.setVisible(visible)
[docs] def updateData(self, image):
self.m_label_data = image
self.m_image_item.m_label_data = self.m_label_data
self.m_image_item.updateImage((image))
[docs] def setData(self, image):
self.m_label_data = image
self.m_image_item.m_label_data = self.m_label_data
self.m_image_item.setImage((image),autoLevels=False)