Commit c5d0ae61 authored by JosefBrandt's avatar JosefBrandt

BugFix in Particle Reassignment, Combination.
Performance increase..
parent 96e55786
...@@ -502,16 +502,20 @@ class ParticleAnalysis(QtWidgets.QMainWindow): ...@@ -502,16 +502,20 @@ class ParticleAnalysis(QtWidgets.QMainWindow):
def getSelectedPolymers(self): def getSelectedPolymers(self):
return [checkbox.text() for checkbox in self.polymerCheckBoxes if checkbox.isChecked()] return [checkbox.text() for checkbox in self.polymerCheckBoxes if checkbox.isChecked()]
# @QtCore.pyqtSlot(int) #TODO: Connect to widget that allows jumping to particular particle #TODO: Connect to widget that allows jumping to particular particle
# def selectParticleIndex(self, particleIndex, centerOn=True): def selectParticleIndex(self, particleIndex, centerOn=True):
# assignment = self.particleContainer.getParticleAssignmentByIndex(particleIndex) self.typeSelectorCombo.currentIndexChanged.disconnect()
# self.typeSelectorCombo.setCurrentText(assignment) assignment = self.particleContainer.getParticleAssignmentByIndex(particleIndex)
# particleIndices = self.particleContainer.getIndicesOfParticleType(assignment) self.typeSelectorCombo.setCurrentText(assignment)
# self.particleSelector.setValue(particleIndices.index(particleIndex)+1) self.typeSelectorCombo.currentIndexChanged.connect(self.displayNewPolymerType)
#
# self.updateToSelectedParticle(resetSpectrumCount=True, centerOn=False) self.particleSelector.valueChanged.disconnect()
particleIndices = self.particleContainer.getIndicesOfParticleType(assignment)
self.particleSelector.setValue(particleIndices.index(particleIndex)+1)
self.particleSelector.valueChanged.connect(self.updateToSelectedParticle)
self.updateToSelectedParticle(resetSpectrumCount=True, centerOn=centerOn)
def displayNewPolymerType(self, resetCurrentIndex=True): def displayNewPolymerType(self, resetCurrentIndex=True):
polymerName = self.typeSelectorCombo.currentText() polymerName = self.typeSelectorCombo.currentText()
numParticles = self.particleContainer.getNumberOfParticlesOfAssignment(polymerName) numParticles = self.particleContainer.getNumberOfParticlesOfAssignment(polymerName)
......
...@@ -238,15 +238,20 @@ class ParticleContainer(object): ...@@ -238,15 +238,20 @@ class ParticleContainer(object):
newParticle.area = area newParticle.area = area
newParticle.contour = newContour newParticle.contour = newContour
self.particles.append(newParticle)
self.removeParticles(particleIndices) self.removeParticles(particleIndices)
print('removed particles')
self.particles.append(newParticle)
print('added new particle')
self.resetParticleIndices() self.resetParticleIndices()
print('resetted indices')
def removeParticles(self, indexList): def removeParticles(self, indexList):
for index in indexList: for index in sorted(indexList, reverse=True):
particle = self.getParticleOfIndex(index) particle = self.getParticleOfIndex(index) #just for asserting to have the correct particle!
print('removing particle of index', index) del self.particles[index]
self.particles.remove(particle) # particle = self.getParticleOfIndex(index)
# print('removing particle of index', index)
# self.particles.remove(particle)
def resetParticleIndices(self): def resetParticleIndices(self):
for newIndex, particle in enumerate(self.particles): for newIndex, particle in enumerate(self.particles):
......
...@@ -32,11 +32,11 @@ from PyQt5 import QtWidgets, QtCore ...@@ -32,11 +32,11 @@ from PyQt5 import QtWidgets, QtCore
class ParticleContextMenu(QtWidgets.QMenu): class ParticleContextMenu(QtWidgets.QMenu):
combineParticlesSignal = QtCore.pyqtSignal(list, str) combineParticlesSignal = QtCore.pyqtSignal(list, str)
reassignParticlesSignal = QtCore.pyqtSignal(list, str) reassignParticlesSignal = QtCore.pyqtSignal(list, str)
def __init__(self, sampleView): def __init__(self, viewparent):
super(ParticleContextMenu, self).__init__() super(ParticleContextMenu, self).__init__()
self.sampleView = sampleView self.viewparent = viewparent
self.selectedParticleIndices = self.sampleView.selectedParticleIndices self.selectedParticleIndices = self.viewparent.selectedParticleIndices
self.particleContainer = self.sampleView.dataset.particleContainer self.particleContainer = self.viewparent.dataset.particleContainer
def executeAtScreenPos(self, screenPos): def executeAtScreenPos(self, screenPos):
self.combineActs = [] self.combineActs = []
...@@ -44,7 +44,10 @@ class ParticleContextMenu(QtWidgets.QMenu): ...@@ -44,7 +44,10 @@ class ParticleContextMenu(QtWidgets.QMenu):
assignments = [] assignments = []
for particleIndex in self.selectedParticleIndices: for particleIndex in self.selectedParticleIndices:
assignment = self.particleContainer.getParticleAssignmentByIndex(particleIndex) try:
assignment = self.particleContainer.getParticleAssignmentByIndex(particleIndex)
except:
return
assignments.append(assignment) assignments.append(assignment)
for assignment in np.unique(assignments): for assignment in np.unique(assignments):
...@@ -88,12 +91,12 @@ class ParticleContextMenu(QtWidgets.QMenu): ...@@ -88,12 +91,12 @@ class ParticleContextMenu(QtWidgets.QMenu):
class ParticleEditor(QtCore.QObject): class ParticleEditor(QtCore.QObject):
particleEditProcessStarted = QtCore.pyqtSignal() particleContoursChanged = QtCore.pyqtSignal()
particlesEdited = QtCore.pyqtSignal() particleAssignmentChanged = QtCore.pyqtSignal()
def __init__(self, sampleView, particleContainer): def __init__(self, analysisparent, particleContainer):
super(ParticleEditor, self).__init__() super(ParticleEditor, self).__init__()
self.particleContainer = particleContainer self.particleContainer = particleContainer
self.sampleView = sampleView #the assigned analysis widget self.analysisparent = analysisparent #the assigned analysis widget
self.backupFreq = 3 #save a backup every n actions self.backupFreq = 3 #save a backup every n actions
self.neverBackedUp = True self.neverBackedUp = True
self.actionCounter = 0 self.actionCounter = 0
...@@ -101,18 +104,17 @@ class ParticleEditor(QtCore.QObject): ...@@ -101,18 +104,17 @@ class ParticleEditor(QtCore.QObject):
def connectToSignals(self, contextMenu): def connectToSignals(self, contextMenu):
contextMenu.combineParticlesSignal.connect(self.combineParticles) contextMenu.combineParticlesSignal.connect(self.combineParticles)
contextMenu.reassignParticlesSignal.connect(self.reassignParticles) contextMenu.reassignParticlesSignal.connect(self.reassignParticles)
def createSafetyBackup(self): def createSafetyBackup(self):
self.actionCounter += 1 self.actionCounter += 1
if self.actionCounter == self.backupFreq-1 or self.neverBackedUp: if self.actionCounter == self.backupFreq-1 or self.neverBackedUp:
backupname = self.sampleView.dataset.saveBackup() backupname = self.analysisparent.dataset.saveBackup()
print('backing up as', backupname) print('backing up as', backupname)
self.neverBackedUp = False self.neverBackedUp = False
self.actionCounter = 0 self.actionCounter = 0
@QtCore.pyqtSlot(list, str) @QtCore.pyqtSlot(list, str)
def combineParticles(self, contourIndices, newAssignment): def combineParticles(self, contourIndices, newAssignment):
self.particleEditProcessStarted.emit()
self.createSafetyBackup() self.createSafetyBackup()
print(f'Combining particles {contourIndices} into {newAssignment}') print(f'Combining particles {contourIndices} into {newAssignment}')
contours = self.particleContainer.getParticleContoursByIndex(contourIndices) contours = self.particleContainer.getParticleContoursByIndex(contourIndices)
...@@ -120,8 +122,7 @@ class ParticleEditor(QtCore.QObject): ...@@ -120,8 +122,7 @@ class ParticleEditor(QtCore.QObject):
stats = self.characterizeParticle(newContour) stats = self.characterizeParticle(newContour)
self.particleContainer.mergeParticles(contourIndices, newContour, stats, newAssignment=newAssignment) self.particleContainer.mergeParticles(contourIndices, newContour, stats, newAssignment=newAssignment)
self.particlesEdited.emit() self.particleContoursChanged.emit()
# #save data # #save data
# minHQI = self.parent.hqiSpinBox.value() # minHQI = self.parent.hqiSpinBox.value()
# compHQI = self.parent.compHqiSpinBox.value() # compHQI = self.parent.compHqiSpinBox.value()
...@@ -132,13 +133,12 @@ class ParticleEditor(QtCore.QObject): ...@@ -132,13 +133,12 @@ class ParticleEditor(QtCore.QObject):
@QtCore.pyqtSlot(list, str) @QtCore.pyqtSlot(list, str)
def reassignParticles(self, contourindices, newAssignment): def reassignParticles(self, contourindices, newAssignment):
self.particleEditProcessStarted.emit()
self.createSafetyBackup() self.createSafetyBackup()
print(f'reassigning indices {contourindices} into {newAssignment}') print(f'reassigning indices {contourindices} into {newAssignment}')
for partIndex in contourindices: for partIndex in contourindices:
self.particleContainer.reassignParticleToAssignment(partIndex, newAssignment) self.particleContainer.reassignParticleToAssignment(partIndex, newAssignment)
self.particlesEdited.emit() self.particleAssignmentChanged.emit()
def mergeContours(self, contours): def mergeContours(self, contours):
cnt = np.vstack(tuple(contours)) #combine contous cnt = np.vstack(tuple(contours)) #combine contous
...@@ -166,7 +166,7 @@ class ParticleEditor(QtCore.QObject): ...@@ -166,7 +166,7 @@ class ParticleEditor(QtCore.QObject):
temp, contours, hierarchy = cv2.findContours(img, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE) temp, contours, hierarchy = cv2.findContours(img, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
if len(contours)>1: if len(contours)>1:
QtWidgets.QMessageBox.critical(self.parent, 'ERROR!', QtWidgets.QMessageBox.critical(self.viewparent, 'ERROR!',
'Particle contours are not connected and cannot be combined!') 'Particle contours are not connected and cannot be combined!')
return return
...@@ -194,7 +194,8 @@ class ParticleEditor(QtCore.QObject): ...@@ -194,7 +194,8 @@ class ParticleEditor(QtCore.QObject):
long, short = short, long long, short = short, long
return long, short, longellipse, shortellipse, cv2.contourArea(cnt) return long, short, longellipse, shortellipse, cv2.contourArea(cnt)
\ No newline at end of file
...@@ -22,6 +22,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets ...@@ -22,6 +22,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
import numpy as np import numpy as np
import os import os
import cv2 import cv2
import time
from dataset import DataSet, loadData from dataset import DataSet, loadData
from ramancom.ramancontrol import RamanControl, simulatedRaman from ramancom.ramancontrol import RamanControl, simulatedRaman
...@@ -179,7 +180,6 @@ class SampleView(QtWidgets.QGraphicsView): ...@@ -179,7 +180,6 @@ class SampleView(QtWidgets.QGraphicsView):
self.detectionwidget.close() self.detectionwidget.close()
self.detectionwidget.destroy() self.detectionwidget.destroy()
self.ramanwidget.setVisible(False) self.ramanwidget.setVisible(False)
self.resetParticleContours()
self.mode = mode self.mode = mode
self.loadPixmap(self.microscopeMode) self.loadPixmap(self.microscopeMode)
if mode == "OpticalScan": if mode == "OpticalScan":
...@@ -231,7 +231,6 @@ class SampleView(QtWidgets.QGraphicsView): ...@@ -231,7 +231,6 @@ class SampleView(QtWidgets.QGraphicsView):
del widget del widget
self.dataset = loadData(fname) self.dataset = loadData(fname)
self.resetParticleContours()
self.setupParticleEditor() self.setupParticleEditor()
self.setMicroscopeMode() self.setMicroscopeMode()
self.imparent.setWindowTitle(self.dataset.name + (" SIMULATION" if simulatedRaman else "")) self.imparent.setWindowTitle(self.dataset.name + (" SIMULATION" if simulatedRaman else ""))
...@@ -259,14 +258,23 @@ class SampleView(QtWidgets.QGraphicsView): ...@@ -259,14 +258,23 @@ class SampleView(QtWidgets.QGraphicsView):
self.imparent.snapshotAct.setEnabled(True) self.imparent.snapshotAct.setEnabled(True)
def setupParticleEditor(self): def setupParticleEditor(self):
def tryDisconnectingSignal(signal):
try:
signal.disconnect()
except TypeError:
pass
if self.particleEditor is None: if self.particleEditor is None:
self.particleEditor = ParticleEditor(self, self.dataset.particleContainer) self.particleEditor = ParticleEditor(self, self.dataset.particleContainer)
self.particleEditor.particleEditProcessStarted.connect(self.disableContourSelection) #try disconnecting the signals. If they are connected multiple times, the functions will run accordingly...
self.particleEditor.particlesEdited.connect(self.resetParticleContours) tryDisconnectingSignal(self.particleEditor.particleContoursChanged)
self.particleEditor.particlesEdited.connect(self.enableContourSelection) tryDisconnectingSignal(self.particleEditor.particleAssignmentChanged)
if self.analysiswidget is not None:
self.particleEditor.particlesEdited.connect(self.analysiswidget.updateDisplays) self.particleEditor.particleContoursChanged.connect(self.resetParticleContours)
if self.analysiswidget is not None:
self.particleEditor.particleContoursChanged.connect(self.analysiswidget.updateDisplays)
self.particleEditor.particleAssignmentChanged.connect(self.analysiswidget.updateDisplays)
def setMicroscopeMode(self): def setMicroscopeMode(self):
if self.ramanSwitchNeeded: if self.ramanSwitchNeeded:
...@@ -360,6 +368,11 @@ class SampleView(QtWidgets.QGraphicsView): ...@@ -360,6 +368,11 @@ class SampleView(QtWidgets.QGraphicsView):
self.scaleImage(factor) self.scaleImage(factor)
def checkForContourSelection(self, event): def checkForContourSelection(self, event):
'''
Iam not yet happy how this selection is handled.
I would prefer having it in the viewitems themselves, but somehow the sampleview has to check
for already selected indices and also check when nothing is hit...
'''
def addContourToSelection(cnt): def addContourToSelection(cnt):
cnt.isSelected = True cnt.isSelected = True
cnt.update() cnt.update()
...@@ -378,9 +391,11 @@ class SampleView(QtWidgets.QGraphicsView): ...@@ -378,9 +391,11 @@ class SampleView(QtWidgets.QGraphicsView):
if not event.modifiers()==QtCore.Qt.ShiftModifier: if not event.modifiers()==QtCore.Qt.ShiftModifier:
addContourToSelection(cnt) addContourToSelection(cnt)
self.analysiswidget.selectParticleIndex(cnt.particleIndex, centerOn=False)
else: else:
if cnt.particleIndex not in self.selectedParticleIndices: if cnt.particleIndex not in self.selectedParticleIndices:
addContourToSelection(cnt) addContourToSelection(cnt)
self.analysiswidget.selectParticleIndex(cnt.particleIndex, centerOn=False)
elif cnt.particleIndex in self.selectedParticleIndices: elif cnt.particleIndex in self.selectedParticleIndices:
removeContourFromSelection(cnt) removeContourFromSelection(cnt)
...@@ -540,16 +555,12 @@ class SampleView(QtWidgets.QGraphicsView): ...@@ -540,16 +555,12 @@ class SampleView(QtWidgets.QGraphicsView):
self.ramanscanitems.append(item) self.ramanscanitems.append(item)
def resetParticleContours(self): def resetParticleContours(self):
t0 = time.time()
for cnt in self.contourItems: for cnt in self.contourItems:
self.scene().removeItem(cnt) self.scene().removeItem(cnt)
self.contourItems = [] self.contourItems = []
if self.dataset is not None: if self.dataset is not None:
for particleIndex, contour in enumerate(self.dataset.particleContainer.getParticleContours()): for particleIndex, contour in enumerate(self.dataset.particleContainer.getParticleContours()):
###
part = self.dataset.particleContainer.getParticleOfIndex(particleIndex)
if part.index != particleIndex:
print('missmatch at countour index and particleIndex', part.index, particleIndex)
###
newCnt = SegmentationContour(self, contour) newCnt = SegmentationContour(self, contour)
newCnt.setIndex(particleIndex) newCnt.setIndex(particleIndex)
assignment = self.dataset.particleContainer.getParticleAssignmentByIndex(particleIndex) assignment = self.dataset.particleContainer.getParticleAssignmentByIndex(particleIndex)
...@@ -558,17 +569,8 @@ class SampleView(QtWidgets.QGraphicsView): ...@@ -558,17 +569,8 @@ class SampleView(QtWidgets.QGraphicsView):
self.contourItems.append(newCnt) self.contourItems.append(newCnt)
self.scene().addItem(newCnt) self.scene().addItem(newCnt)
self.update() self.update()
print('resetted contours:', round((time.time()-t0)*1000))
def disableContourSelection(self):
self.disableSelection = True
# for contourItem in self.contourItems:
# contourItem.setAcceptedMouseButtons(QtCore.Qt.NoButton)
def enableContourSelection(self):
self.disableSelection = False
# for contourItem in self.contourItems:
# contourItem.setAcceptedMouseButtons(QtCore.Qt.AllButtons)
def updateLegend(self, legendItems): def updateLegend(self, legendItems):
self.imparent.legend.setTextColorItems(legendItems) self.imparent.legend.setTextColorItems(legendItems)
...@@ -581,6 +583,8 @@ class SampleView(QtWidgets.QGraphicsView): ...@@ -581,6 +583,8 @@ class SampleView(QtWidgets.QGraphicsView):
def centerOnRamanIndex(self, index, centerOn=True, highlightContour=True): def centerOnRamanIndex(self, index, centerOn=True, highlightContour=True):
if centerOn: if centerOn:
self.centerOn(self.ramanscanitems[index]) self.centerOn(self.ramanscanitems[index])
if highlightContour:
self.highLightRamanIndex(index)
def clearItems(self): def clearItems(self):
for item in self.fititems: for item in self.fititems:
......
...@@ -82,9 +82,9 @@ class SegmentationContour(QtWidgets.QGraphicsItem): ...@@ -82,9 +82,9 @@ class SegmentationContour(QtWidgets.QGraphicsItem):
def contextMenuEvent(self, event): def contextMenuEvent(self, event):
if self.isSelected: if self.isSelected:
contextMenu = ParticleContextMenu(self.parent) self.contextMenu = ParticleContextMenu(self.parent)
self.parent.particleEditor.connectToSignals(contextMenu) self.parent.particleEditor.connectToSignals(self.contextMenu)
contextMenu.executeAtScreenPos(event.screenPos()) self.contextMenu.executeAtScreenPos(event.screenPos())
#class SegmentationContours(QtWidgets.QGraphicsItem): #class SegmentationContours(QtWidgets.QGraphicsItem):
# def __init__(self, parent, contours=[], pos=(0,0)): # def __init__(self, parent, contours=[], pos=(0,0)):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment