Commit 38f99d4e authored by Josef Brandt's avatar Josef Brandt

Merge remote-tracking branch 'origin/SegmentationRefactoring' into Tiling2Develop

parents f1fcb2d7 2efa7d08
...@@ -27,6 +27,7 @@ from threading import Thread ...@@ -27,6 +27,7 @@ from threading import Thread
from .segmentation import Segmentation from .segmentation import Segmentation
from .analysis.particleCharacterization import getParticleStatsWithPixelScale, loadZValImageFromDataset from .analysis.particleCharacterization import getParticleStatsWithPixelScale, loadZValImageFromDataset
from .errors import InvalidParticleError from .errors import InvalidParticleError
from .uielements import TimeEstimateProgressbar
from .scenePyramid import ScenePyramid from .scenePyramid import ScenePyramid
Nscreen = 1000 Nscreen = 1000
...@@ -290,8 +291,10 @@ class ParticleDetectionView(QtWidgets.QWidget): ...@@ -290,8 +291,10 @@ class ParticleDetectionView(QtWidgets.QWidget):
self.img = pyramid.getFullImage() self.img = pyramid.getFullImage()
self.imgclip = 0, 0, 0, 0 self.imgclip = 0, 0, 0, 0
self.seg = Segmentation(self.dataset, self) self.seg = Segmentation(self.dataset, self)
self.seg.detectionState.connect(self.updateDetectionState)
self.thread = None self.thread = None
self.view : QtWidgets.QGraphicsView = parent self.threadrunning = False
self.view = parent
vbox = QtWidgets.QVBoxLayout() vbox = QtWidgets.QVBoxLayout()
hbox = QtWidgets.QHBoxLayout() hbox = QtWidgets.QHBoxLayout()
...@@ -315,7 +318,7 @@ class ParticleDetectionView(QtWidgets.QWidget): ...@@ -315,7 +318,7 @@ class ParticleDetectionView(QtWidgets.QWidget):
self.showseedpoints.setChecked(True) self.showseedpoints.setChecked(True)
self.setImageCenter() self.setImageCenter()
group = QtWidgets.QGroupBox("Detection settings", self) self.detectParamsGroup = QtWidgets.QGroupBox("Detection settings", self)
grid = QtWidgets.QGridLayout() grid = QtWidgets.QGridLayout()
self.parameters = [] self.parameters = []
checkBoxesToLink = {} checkBoxesToLink = {}
...@@ -397,8 +400,8 @@ class ParticleDetectionView(QtWidgets.QWidget): ...@@ -397,8 +400,8 @@ class ParticleDetectionView(QtWidgets.QWidget):
grid.addWidget(self.showseedpoints, i+2, 0, 1, 2, QtCore.Qt.AlignLeft) grid.addWidget(self.showseedpoints, i+2, 0, 1, 2, QtCore.Qt.AlignLeft)
grid.addWidget(QtWidgets.QLabel("Click mouse to add seeds, Click+Shift to add deletepoints"), i+3, 0, 1, 2, QtCore.Qt.AlignLeft) grid.addWidget(QtWidgets.QLabel("Click mouse to add seeds, Click+Shift to add deletepoints"), i+3, 0, 1, 2, QtCore.Qt.AlignLeft)
grid.addWidget(QtWidgets.QLabel("Click+Alt removes seeds near cursor"), i+4, 0, 1, 2, QtCore.Qt.AlignLeft) grid.addWidget(QtWidgets.QLabel("Click+Alt removes seeds near cursor"), i+4, 0, 1, 2, QtCore.Qt.AlignLeft)
group.setLayout(grid) self.detectParamsGroup.setLayout(grid)
vbox.addWidget(group) vbox.addWidget(self.detectParamsGroup)
self.updateSeedsInSampleViewBtn = QtWidgets.QPushButton("Update Seedpoints in fullimage view", self) self.updateSeedsInSampleViewBtn = QtWidgets.QPushButton("Update Seedpoints in fullimage view", self)
self.updateSeedsInSampleViewBtn.released.connect(self.updateSeedsInSampleview) self.updateSeedsInSampleViewBtn.released.connect(self.updateSeedsInSampleview)
...@@ -419,6 +422,9 @@ class ParticleDetectionView(QtWidgets.QWidget): ...@@ -419,6 +422,9 @@ class ParticleDetectionView(QtWidgets.QWidget):
self.autoUpdateCheckBox.setMaximumWidth(200) self.autoUpdateCheckBox.setMaximumWidth(200)
self.autoUpdateCheckBox.setChecked(True) self.autoUpdateCheckBox.setChecked(True)
vbox.addWidget(self.autoUpdateCheckBox) vbox.addWidget(self.autoUpdateCheckBox)
self.progressbar = TimeEstimateProgressbar()
vbox.addWidget(self.progressbar)
hbox2 = QtWidgets.QHBoxLayout() hbox2 = QtWidgets.QHBoxLayout()
self.pdetectsub = QtWidgets.QPushButton("Detect", self) self.pdetectsub = QtWidgets.QPushButton("Detect", self)
...@@ -634,21 +640,22 @@ class ParticleDetectionView(QtWidgets.QWidget): ...@@ -634,21 +640,22 @@ class ParticleDetectionView(QtWidgets.QWidget):
self.updateImageSeeds() self.updateImageSeeds()
def detectShow(self, showname): def detectShow(self, showname):
self.saveDetectParams(self.dataset) if not self.threadrunning:
img = self.subimg.copy() self.saveDetectParams(self.dataset)
kwargs = {} img = self.subimg.copy()
for ui, name, valuefunc, showbtn in self.parameters: kwargs = {}
kwargs[name] = valuefunc() for ui, name, valuefunc, showbtn in self.parameters:
self.seg.setParameters(**kwargs) kwargs[name] = valuefunc()
seedradius = self.seedradiusedit.value() self.seg.setParameters(**kwargs)
if showname is not None: seedradius = self.seedradiusedit.value()
stepImg, imgtype = self.seg.apply2Image(img, self.imglabel.seedpoints, self.imglabel.seeddeletepoints, if showname is not None:
seedradius, self.dataset, return_step=showname) stepImg, imgtype = self.seg.apply2Image(img, self.imglabel.seedpoints, self.imglabel.seeddeletepoints,
self.imglabel.showStep(stepImg, imgtype) seedradius, self.dataset, return_step=showname)
else: self.imglabel.showStep(stepImg, imgtype)
measurementpoints, contours = self.seg.apply2Image(img, self.imglabel.seedpoints, self.imglabel.seeddeletepoints, else:
seedradius, self.dataset) measurementpoints, contours = self.seg.apply2Image(img, self.imglabel.seedpoints, self.imglabel.seeddeletepoints,
self.imglabel.updateDetectionResults(contours, measurementpoints) seedradius, self.dataset)
self.imglabel.updateDetectionResults(contours, measurementpoints)
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def clearDetection(self): def clearDetection(self):
...@@ -671,16 +678,26 @@ class ParticleDetectionView(QtWidgets.QWidget): ...@@ -671,16 +678,26 @@ class ParticleDetectionView(QtWidgets.QWidget):
def blockUI(self): def blockUI(self):
self.pdetectsub.setEnabled(False) self.pdetectsub.setEnabled(False)
self.pclear.setEnabled(False) self.pclear.setEnabled(False)
self.detectParamsGroup.setEnabled(False)
self.updateSeedsInSampleViewBtn.setEnabled(False)
self.hideSeedsInSampleViewBtn.setEnabled(False)
def unBlockUI(self): def unBlockUI(self):
self.pdetectsub.setEnabled(True) self.pdetectsub.setEnabled(True)
self.pclear.setEnabled(True) self.pclear.setEnabled(True)
self.detectParamsGroup.setEnabled(True)
self.updateSeedsInSampleViewBtn.setEnabled(True)
self.hideSeedsInSampleViewBtn.setEnabled(True)
def raiseWarning(self, warning): def raiseWarning(self, warning):
QtWidgets.QMessageBox.critical(self, "Warning", warning) QtWidgets.QMessageBox.critical(self, "Warning", warning)
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def detectParticles(self): def detectParticles(self):
"""
Detect all particles
:return:
"""
self.saveDetectParams(self.dataset) self.saveDetectParams(self.dataset)
if self.thread is not None and self.thread.is_alive(): if self.thread is not None and self.thread.is_alive():
self.cancelThread() self.cancelThread()
...@@ -700,6 +717,7 @@ class ParticleDetectionView(QtWidgets.QWidget): ...@@ -700,6 +717,7 @@ class ParticleDetectionView(QtWidgets.QWidget):
if self.thread is not None: if self.thread is not None:
if not self.threadrunning: if not self.threadrunning:
self.thread = None self.thread = None
self.progressbar.disable()
self.unBlockUI() self.unBlockUI()
self.pdetectall.setText("Detect all") self.pdetectall.setText("Detect all")
self.imageUpdate.emit(self.view.microscopeMode) self.imageUpdate.emit(self.view.microscopeMode)
...@@ -709,6 +727,25 @@ class ParticleDetectionView(QtWidgets.QWidget): ...@@ -709,6 +727,25 @@ class ParticleDetectionView(QtWidgets.QWidget):
self.setWindowTitle(f'{numParticles} Particles ({numMeasurements} Measurements)') self.setWindowTitle(f'{numParticles} Particles ({numMeasurements} Measurements)')
else: else:
self.timer.start(100.) self.timer.start(100.)
@QtCore.pyqtSlot(str)
def updateDetectionState(self, message):
"""
Updates the progressbar and its text-label to the current state of the detection
:return:
"""
if message.find('DO') == -1:
self.progressbar.setMessage(message)
else:
if message.find('setup') != -1:
self.progressbar.resetTimerAndCounter()
self.progressbar.enable()
elif message.find('maxVal') != -1:
maxVal = int(message.split('=')[-1])
self.progressbar.setMaxValue(maxVal)
elif message.find('newVal') != -1:
newVal = int(message.split('=')[-1])
self.progressbar.setValue(newVal)
def _worker(self): def _worker(self):
kwargs = {} kwargs = {}
...@@ -720,8 +757,9 @@ class ParticleDetectionView(QtWidgets.QWidget): ...@@ -720,8 +757,9 @@ class ParticleDetectionView(QtWidgets.QWidget):
kwargs[name] = valuefunc() kwargs[name] = valuefunc()
seedradius = self.seedradiusedit.value() seedradius = self.seedradiusedit.value()
self.seg.setParameters(**kwargs) self.seg.setParameters(**kwargs)
measurementPoints, contours= self.seg.apply2Image(self.img, seedpoints, deletepoints, seedradius, self.dataset) measurementPoints, contours= self.seg.apply2Image(self.img, seedpoints, deletepoints, seedradius, self.dataset)
if measurementPoints is None: # computation was canceled if measurementPoints is None: # computation was canceled
return return
......
...@@ -28,8 +28,9 @@ import sys, os ...@@ -28,8 +28,9 @@ import sys, os
import cv2 import cv2
from .helperfunctions import cv2imread_fix, cv2imwrite_fix from .helperfunctions import cv2imread_fix, cv2imwrite_fix
from time import time from time import time
import datetime import sys
from .opticalbackground import BackGroundManager from .opticalbackground import BackGroundManager
from .uielements import TimeEstimateProgressbar
from .zlevelsetter import ZLevelSetter from .zlevelsetter import ZLevelSetter
from .scenePyramid import ScenePyramid from .scenePyramid import ScenePyramid
...@@ -337,13 +338,10 @@ class OpticalScan(QtWidgets.QWidget): ...@@ -337,13 +338,10 @@ class OpticalScan(QtWidgets.QWidget):
self.prun.released.connect(self.run) self.prun.released.connect(self.run)
self.pexit.released.connect(self.stopScan) self.pexit.released.connect(self.stopScan)
self.prun.setEnabled(False) self.prun.setEnabled(False)
self.timelabeltext = "Estimated time to finish: " self.progressbar = TimeEstimateProgressbar()
self.progressbar = QtWidgets.QProgressBar(self) self.progressbar.disable()
self.progresstime = QtWidgets.QLabel(self.timelabeltext, self)
self.progresstime.setEnabled(False)
self.progressbar.setEnabled(False)
radioGroup = QtWidgets.QGroupBox('Shape') radioGroup = QtWidgets.QGroupBox('Shape')
radioLayout = QtWidgets.QHBoxLayout() radioLayout = QtWidgets.QHBoxLayout()
self.circlerad = QtWidgets.QRadioButton("Circle") self.circlerad = QtWidgets.QRadioButton("Circle")
...@@ -404,7 +402,6 @@ class OpticalScan(QtWidgets.QWidget): ...@@ -404,7 +402,6 @@ class OpticalScan(QtWidgets.QWidget):
optionsLayout.addLayout(vbox2) optionsLayout.addLayout(vbox2)
mainLayout.addLayout(optionsLayout) mainLayout.addLayout(optionsLayout)
mainLayout.addWidget(self.progresstime)
mainLayout.addWidget(self.progressbar) mainLayout.addWidget(self.progressbar)
mainLayout.addLayout(btnLayout) mainLayout.addLayout(btnLayout)
...@@ -441,6 +438,7 @@ class OpticalScan(QtWidgets.QWidget): ...@@ -441,6 +438,7 @@ class OpticalScan(QtWidgets.QWidget):
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.Yes |
QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No) QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No)
if reply == QtWidgets.QMessageBox.Yes: if reply == QtWidgets.QMessageBox.Yes:
self.progressbar.resetTimerAndCounter()
self.timer.stop() self.timer.stop()
self.processstopevent.set() self.processstopevent.set()
self.process.join() self.process.join()
...@@ -684,12 +682,9 @@ class OpticalScan(QtWidgets.QWidget): ...@@ -684,12 +682,9 @@ class OpticalScan(QtWidgets.QWidget):
self.dataqueue, self.processstopevent, self.dataqueue, self.processstopevent,
self.logpath, self.hdrcheck.isChecked())) self.logpath, self.hdrcheck.isChecked()))
self.process.start() self.process.start()
self.starttime = time() self.progressbar.enable()
self.progresstime.setEnabled(True) self.progressbar.resetTimerAndCounter()
self.progressbar.setEnabled(True) self.progressbar.setMaxValue(len(self.dataset.grid))
self.progressbar.setRange(0, len(self.dataset.grid))
self.progressbar.setValue(0)
#self.view.imgdata = None
self.pyramid.resetScene() self.pyramid.resetScene()
self.view.blockUI() self.view.blockUI()
grid = np.asarray(self.dataset.grid) grid = np.asarray(self.dataset.grid)
...@@ -734,14 +729,7 @@ class OpticalScan(QtWidgets.QWidget): ...@@ -734,14 +729,7 @@ class OpticalScan(QtWidgets.QWidget):
removeSrcTiles(names, self.dataset.getScanPath()) removeSrcTiles(names, self.dataset.getScanPath())
self.progressbar.setValue(i+1) self.progressbar.setValue(i+1)
if i > 3: self.imageUpdate.emit(self.view.microscopeMode)
timerunning = time()-self.starttime
ttot = timerunning*Ngrid/(i+1)
time2go = ttot - timerunning
self.progresstime.setText(self.timelabeltext + str(datetime.timedelta(seconds=round(time2go))))
# reload image in sampleview, calls loadPixmap
# not needed anymore as the scene gets manipulated directly via self.pyramid
# self.imageUpdate.emit(self.view.microscopeMode)
if i==Ngrid-1: if i==Ngrid-1:
# cv2imwrite_fix(self.dataset.getImageName(), cv2.cvtColor(self.view.imgdata, cv2.COLOR_RGB2BGR)) # cv2imwrite_fix(self.dataset.getImageName(), cv2.cvtColor(self.view.imgdata, cv2.COLOR_RGB2BGR))
...@@ -756,9 +744,8 @@ class OpticalScan(QtWidgets.QWidget): ...@@ -756,9 +744,8 @@ class OpticalScan(QtWidgets.QWidget):
self.view.saveDataSet() self.view.saveDataSet()
self.view.unblockUI() self.view.unblockUI()
self.view.switchMode("ParticleDetection") self.view.switchMode("ParticleDetection")
self.progressbar.setValue(0) self.progressbar.resetTimerAndCounter()
self.progressbar.setEnabled(False) self.progressbar.disable()
self.progresstime.setEnabled(False)
self.close() self.close()
return return
self.timer.start(100.) self.timer.start(100.)
......
...@@ -24,10 +24,10 @@ import numpy as np ...@@ -24,10 +24,10 @@ import numpy as np
from multiprocessing import Process, Queue, Event from multiprocessing import Process, Queue, Event
import queue import queue
from time import time from time import time
from .external import tsp
import datetime
import sys import sys
import os import os
from .external import tsp
from .uielements import TimeEstimateProgressbar
def reorder(points, N=20): def reorder(points, N=20):
y0, y1 = points[:,1].min(), points[:,1].max() y0, y1 = points[:,1].min(), points[:,1].max()
...@@ -110,18 +110,15 @@ class RamanScanUI(QtWidgets.QWidget): ...@@ -110,18 +110,15 @@ class RamanScanUI(QtWidgets.QWidget):
self.pexit = QtWidgets.QPushButton("Cancel", self) self.pexit = QtWidgets.QPushButton("Cancel", self)
self.pexit.released.connect(self.stopScan) self.pexit.released.connect(self.stopScan)
self.prun.setEnabled(False) self.prun.setEnabled(False)
self.progressbar = QtWidgets.QProgressBar(self)
self.timelabeltext = "Estimated time to finish: " self.progressbar = TimeEstimateProgressbar()
self.progresstime = QtWidgets.QLabel(self.timelabeltext, self) self.progressbar.disable()
self.progresstime.setEnabled(False)
self.progressbar.setEnabled(False)
hbox.addStretch() hbox.addStretch()
hbox.addWidget(self.pexit) hbox.addWidget(self.pexit)
vbox.addWidget(self.paramsGroup) vbox.addWidget(self.paramsGroup)
vbox.addLayout(hbox) vbox.addLayout(hbox)
vbox.addWidget(self.progresstime)
vbox.addWidget(self.progressbar) vbox.addWidget(self.progressbar)
self.setLayout(vbox) self.setLayout(vbox)
...@@ -189,6 +186,7 @@ class RamanScanUI(QtWidgets.QWidget): ...@@ -189,6 +186,7 @@ class RamanScanUI(QtWidgets.QWidget):
QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No) QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No)
if reply == QtWidgets.QMessageBox.Yes: if reply == QtWidgets.QMessageBox.Yes:
self.timer.stop() self.timer.stop()
self.progressbar.resetTimerAndCounter()
self.processstopevent.set() self.processstopevent.set()
self.process.join() self.process.join()
self.dataqueue.close() self.dataqueue.close()
...@@ -264,10 +262,9 @@ class RamanScanUI(QtWidgets.QWidget): ...@@ -264,10 +262,9 @@ class RamanScanUI(QtWidgets.QWidget):
self.view.highLightRamanIndex(0) self.view.highLightRamanIndex(0)
self.view.blockUI() self.view.blockUI()
self.paramsGroup.setEnabled(False) self.paramsGroup.setEnabled(False)
self.progresstime.setEnabled(True) self.progressbar.enable()
self.progressbar.setEnabled(True) self.progressbar.resetTimerAndCounter()
self.progressbar.setRange(0, len(scanpoints)) self.progressbar.setMaxValue(len(scanpoints))
self.progressbar.setValue(0)
self.ramanctrl.disconnect() self.ramanctrl.disconnect()
self.processstopevent = Event() self.processstopevent = Event()
self.dataqueue = Queue() self.dataqueue = Queue()
...@@ -295,11 +292,6 @@ class RamanScanUI(QtWidgets.QWidget): ...@@ -295,11 +292,6 @@ class RamanScanUI(QtWidgets.QWidget):
self.view.highLightRamanIndex(i+1) #go to next scanmarker self.view.highLightRamanIndex(i+1) #go to next scanmarker
Npoints = len(self.dataset.particleContainer.getMeasurementPixelCoords()) Npoints = len(self.dataset.particleContainer.getMeasurementPixelCoords())
if i>3:
timerunning = time()-self.starttime
ttot = timerunning*Npoints/(i+1)
time2go = ttot - timerunning
self.progresstime.setText(self.timelabeltext + str(datetime.timedelta(seconds=round(time2go))))
if i==Npoints-1: if i==Npoints-1:
self.process.join() self.process.join()
self.dataqueue.close() self.dataqueue.close()
...@@ -307,9 +299,8 @@ class RamanScanUI(QtWidgets.QWidget): ...@@ -307,9 +299,8 @@ class RamanScanUI(QtWidgets.QWidget):
self.dataset.ramanscandone = True self.dataset.ramanscandone = True
self.view.saveDataSet() self.view.saveDataSet()
self.view.unblockUI() self.view.unblockUI()
self.progressbar.setValue(0) self.progressbar.resetTimerAndCounter()
self.progressbar.setEnabled(False) self.progressbar.disable()
self.progresstime.setEnabled(False)
self.close() self.close()
return return
self.timer.start(100.) self.timer.start(100.)
......
...@@ -28,6 +28,8 @@ from skimage.feature import peak_local_max ...@@ -28,6 +28,8 @@ from skimage.feature import peak_local_max
from skimage.morphology import watershed from skimage.morphology import watershed
import skfuzzy as fuzz import skfuzzy as fuzz
import random import random
from PyQt5 import QtCore
def closeHolesOfSubImage(subimg): def closeHolesOfSubImage(subimg):
subimg = cv2.copyMakeBorder(subimg, 1, 1, 1, 1, 0) subimg = cv2.copyMakeBorder(subimg, 1, 1, 1, 1, 0)
...@@ -63,8 +65,10 @@ class MeasurementPoint(object): ...@@ -63,8 +65,10 @@ class MeasurementPoint(object):
self.x = x self.x = x
self.y = y self.y = y
class Segmentation(object): class Segmentation(QtCore.QObject):
def __init__(self, dataset=None, parent=None): detectionState = QtCore.pyqtSignal(str)
def __init__(self, dataset=None, parent=None):
super(Segmentation, self).__init__()
self.cancelcomputation = False self.cancelcomputation = False
self.parent = parent self.parent = parent
self.defaultParams = {'adaptiveHistEqu': False, self.defaultParams = {'adaptiveHistEqu': False,
...@@ -84,6 +88,7 @@ class Segmentation(object): ...@@ -84,6 +88,7 @@ class Segmentation(object):
'minparticledistance': 20, 'minparticledistance': 20,
'closeBackground': False, 'closeBackground': False,
'fuzzycluster': False, 'fuzzycluster': False,
'maxComponentSize': 20000,
'measurefrac': 1, 'measurefrac': 1,
'compactness': 0.0, 'compactness': 0.0,
'seedRad': 3} 'seedRad': 3}
...@@ -115,6 +120,7 @@ class Segmentation(object): ...@@ -115,6 +120,7 @@ class Segmentation(object):
Parameter("measurefrac", float, self.detectParams['measurefrac'], 0, 1, 2, stepsize = 0.05, helptext="measure fraction of particles", show=False), Parameter("measurefrac", float, self.detectParams['measurefrac'], 0, 1, 2, stepsize = 0.05, helptext="measure fraction of particles", show=False),
Parameter("closeBackground", np.bool, self.detectParams['closeBackground'], helptext="close holes in sure background", show=False), Parameter("closeBackground", np.bool, self.detectParams['closeBackground'], helptext="close holes in sure background", show=False),
Parameter("fuzzycluster", np.bool, self.detectParams['fuzzycluster'], helptext='Enable Fuzzy Clustering', show=False), Parameter("fuzzycluster", np.bool, self.detectParams['fuzzycluster'], helptext='Enable Fuzzy Clustering', show=False),
Parameter("maxComponentSize", int, self.detectParams['maxComponentSize'], 100, 1E6, 0, 100, helptext='Maximum size in x or y of connected component.\nLarger components are scaled down accordingly', show=False),
Parameter("sure_fg", None, helptext="Show sure foreground", show=True), Parameter("sure_fg", None, helptext="Show sure foreground", show=True),
Parameter("compactness", float, self.detectParams['compactness'], 0, 1, 2, 0.05, helptext="watershed compactness", show=False), Parameter("compactness", float, self.detectParams['compactness'], 0, 1, 2, 0.05, helptext="watershed compactness", show=False),
Parameter("watershed", None, helptext="Show watershed markers", show=True), Parameter("watershed", None, helptext="Show watershed markers", show=True),
...@@ -140,8 +146,10 @@ class Segmentation(object): ...@@ -140,8 +146,10 @@ class Segmentation(object):
:return: :return:
""" """
t0 = time() t0 = time()
self.detectionState.emit('DO: setup')
gray = self.convert2Gray(img) gray = self.convert2Gray(img)
self.detectionState.emit('finished GrayScale')
print("gray") print("gray")
if self.adaptiveHistEqu: if self.adaptiveHistEqu:
...@@ -149,6 +157,7 @@ class Segmentation(object): ...@@ -149,6 +157,7 @@ class Segmentation(object):
numTilesY = round(img.shape[0]/self.claheTileSize) numTilesY = round(img.shape[0]/self.claheTileSize)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(numTilesY,numTilesX)) clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(numTilesY,numTilesX))
gray = clahe.apply(gray) gray = clahe.apply(gray)
self.detectionState.emit('finished CLAHE')
if return_step=="claheTileSize": return gray, 0 if return_step=="claheTileSize": return gray, 0
print("adaptive Histogram Adjustment") print("adaptive Histogram Adjustment")
...@@ -158,7 +167,8 @@ class Segmentation(object): ...@@ -158,7 +167,8 @@ class Segmentation(object):
if self.activateContrastCurve: if self.activateContrastCurve:
xi, arr = self.calculateHistFunction(self.contrastCurve) xi, arr = self.calculateHistFunction(self.contrastCurve)
gray = arr[gray] gray = arr[gray]
print("contrast curve") print("contrast curve")
self.detectionState.emit('finished Contrast Curve')
if self.cancelcomputation: if self.cancelcomputation:
return None, None return None, None
...@@ -171,6 +181,7 @@ class Segmentation(object): ...@@ -171,6 +181,7 @@ class Segmentation(object):
del gray del gray
if return_step=="blurRadius": return blur, 0 if return_step=="blurRadius": return blur, 0
self.detectionState.emit('finished Blurring')
print("blur") print("blur")
if self.cancelcomputation: if self.cancelcomputation:
return None, None return None, None
...@@ -215,6 +226,7 @@ class Segmentation(object): ...@@ -215,6 +226,7 @@ class Segmentation(object):
thresh = self.closeBrightHoles(thresh, blur, self.maxholebrightness) thresh = self.closeBrightHoles(thresh, blur, self.maxholebrightness)
del blur del blur
print("thresholded") print("thresholded")
self.detectionState.emit('finished thresholding')
# modify thresh with seedpoints and deletepoints # modify thresh with seedpoints and deletepoints
for p in np.int32(seedpoints): for p in np.int32(seedpoints):
...@@ -235,6 +247,8 @@ class Segmentation(object): ...@@ -235,6 +247,8 @@ class Segmentation(object):
'''the peak_local_max function takes the min distance between peaks. Unfortunately, that means that individual '''the peak_local_max function takes the min distance between peaks. Unfortunately, that means that individual
particles smaller than that distance are consequently disregarded. Hence, we need a connectec_components approach''' particles smaller than that distance are consequently disregarded. Hence, we need a connectec_components approach'''
n, labels, stats, centroids = cv2.connectedComponentsWithStats(thresh, 8, cv2.CV_32S) n, labels, stats, centroids = cv2.connectedComponentsWithStats(thresh, 8, cv2.CV_32S)
self.detectionState.emit('finished connected components search')
self.detectionState.emit(f'DO: maxVal={n-1}')
del thresh del thresh
measurementPoints = {} measurementPoints = {}
...@@ -249,7 +263,6 @@ class Segmentation(object): ...@@ -249,7 +263,6 @@ class Segmentation(object):
else: else:
previewImage = np.zeros(img.shape[:2]) previewImage = np.zeros(img.shape[:2])
for label in range(1, n): for label in range(1, n):
area = stats[label, cv2.CC_STAT_AREA] area = stats[label, cv2.CC_STAT_AREA]
if self.minparticlearea < area < maxArea: if self.minparticlearea < area < maxArea:
...@@ -257,83 +270,110 @@ class Segmentation(object): ...@@ -257,83 +270,110 @@ class Segmentation(object):
left = stats[label, cv2.CC_STAT_LEFT] left = stats[label, cv2.CC_STAT_LEFT]
width = stats[label, cv2.CC_STAT_WIDTH] width = stats[label, cv2.CC_STAT_WIDTH]
height = stats[label, cv2.CC_STAT_HEIGHT] height = stats[label, cv2.CC_STAT_HEIGHT]
# if width > 25000 or height > 25000:
if False: subthresh = np.uint8(255 * (labels[up:(up+height), left:(left+width)] == label))
print(f'skipping{label} of {n} compontents, too large: {width} x {height} pixel!!!')