Commit 25423ad8 authored by Josef Brandt's avatar Josef Brandt

Further bugfixes and comort functions

Color mode is fixed (bgr2rgb not needed),
More hotkeys,
Preparation for Renishaw interface (handles raman measurement differently),
"Measure fraction of particles" now keeps all particles, but measures only a fraction of them,
Better Navigation in Analysisview (button press responses)
parent ad95af53
......@@ -14,3 +14,7 @@ external/build/
.idea/
*.pyd
ramancom/renishawcom.py
ramancom/renishawtesting.py
......@@ -205,12 +205,17 @@ class GEPARDMainWindow(QtWidgets.QMainWindow):
self.configRamanCtrlAct.setDisabled(True)
self.noOverlayAct = QtWidgets.QAction("&No Overlay", self)
self.noOverlayAct.setShortcut("1")
self.selOverlayAct = QtWidgets.QAction("&Selected Overlay", self)
self.selOverlayAct.setShortcut("2")
self.fullOverlayAct = QtWidgets.QAction("&Full Overlay", self)
self.fullOverlayAct.setShortcut("3")
self.transpAct = QtWidgets.QAction("&Transparent Overlay", self)
self.transpAct.setShortcut("T")
self.hideLabelAct = QtWidgets.QAction('&Hide Spectra Numbers', self)
self.hideLabelAct.setShortcut("H")
self.darkenAct = QtWidgets.QAction("&Darken Image", self)
self.darkenAct.setShortcut("D")
self.seedAct = QtWidgets.QAction("&Set Color Seed", self)
for act in [self.noOverlayAct, self.selOverlayAct, self.fullOverlayAct, self.hideLabelAct, self.transpAct, self.darkenAct, self.seedAct]:
......
......@@ -209,12 +209,18 @@ class PolymerNavigationToolbar(QtWidgets.QGroupBox):
self.particleSelector.setValue(partIndices.index(particleIndex)+1)
specIndices = self.particleContainer.getSpectraIndicesOfParticle(self.currentParticleIndex)
if len(specIndices) > 0:
self.spectrumSelector.setDisabled(False)
self.spectrumSelector.setValue(1)
self.spectrumSelector.setMaximum(len(specIndices))
self.spectrumNumberLabel.setText(f'of {len(specIndices)} spectra')
self.currentSpectrumIndex = specIndices[self.spectrumSelector.value()-1]
self.specNumberSelector.setValue(self.currentSpectrumIndex+1)
else:
self.spectrumSelector.setDisabled(True)
self.spectrumSelector.setValue(0)
self.spectrumSelector.setMaximum(0)
self.spectrumNumberLabel.setText(f'of {len(specIndices)} spectra')
self.typeSelectorCombo.currentIndexChanged.connect(self.setTypeSelector)
self.spectrumSelector.valueChanged.connect(self.setSpecSelector)
......@@ -232,10 +238,6 @@ class PolymerNavigationToolbar(QtWidgets.QGroupBox):
def setParticleSelector(self):
assignment = self.typeSelectorCombo.currentText()
if assignment != '':
# if self.lastParticleIndex is not None:
# self.currentParticleIndex = self.lastParticleIndex
# self.lastParticleIndex = None
# else:
partIndices = self.particleContainer.getIndicesOfParticleType(assignment)
self.currentParticleIndex = partIndices[self.particleSelector.value()-1]
......@@ -246,23 +248,23 @@ class PolymerNavigationToolbar(QtWidgets.QGroupBox):
self.setSpecSelector()
def setSpecSelector(self):
# if self.lastSpecIndex is not None:
# self.currentSpectrumIndex = self.lastSpecIndex
# self.lastSpecIndex = None
# else:
specIndices = self.particleContainer.getSpectraIndicesOfParticle(self.currentParticleIndex)
self.currentSpectrumIndex = specIndices[self.spectrumSelector.value()-1]
if len(specIndices) == 0:
self.spectrumSelector.setDisabled(True)
else:
self.spectrumSelector.setDisabled(False)
self.currentSpectrumIndex = specIndices[self.spectrumSelector.value()-1]
self.specNumberSelector.setValue(self.currentSpectrumIndex+1)
self.WidgetsUpdated.emit()
self.JumpToIndicatedSpec.emit()
if self.lastSpecIndex is not None:
self.currentParticleIndex = self.particleContainer.getParticleIndexContainingSpecIndex(self.lastSpecIndex)
self.lastSpecIndex = None
self.setWidgetsToNewParticleIndex(self.currentParticleIndex)
self.JumpToIndicatedSpec.emit()
self.WidgetsUpdated.emit()
class FindColoredParticleWindow(QtWidgets.QWidget):
ParticleOfIndexSelected = QtCore.pyqtSignal(int)
......
......@@ -76,7 +76,6 @@ class ExpExcelDialog(QtWidgets.QDialog):
polymers = np.array(self.particleContainer.getListOfParticleAssignments())
sizes = np.array(self.particleContainer.getSizesOfAllParticles())
for box in self.checkBoxes:
if box.isChecked() == True:
if box.text() != 'Size Classes':
......
......@@ -121,7 +121,6 @@ class LoadTrueMatchResults(QtWidgets.QWidget):
print('spectra in batch:', len(resBatch))
for result in resBatch:
specIndex, polymertype, additive, hqi, addhqi = self.interpretEntry(resBatchIndex, numSpectraInPreviousBatches, result, numhits, numcomps)
print('assigning currentSpecIndex', specIndex)
self.polymertypes[specIndex] = polymertype
self.hqis[specIndex] = hqi
if numcomps > 1:
......
......@@ -44,13 +44,19 @@ class Particle(object):
meas.setHQI(100)
def getParticleAssignment(self):
return self.getMeasAssignmentWithHighestHQI() #probably another method could be more suitable...
assignment = 'NotYetMeasured'
if len(self.measurements) > 0:
assignment = self.getMeasAssignmentWithHighestHQI() #probably another method could be more suitable...
return assignment
def getHighestHQI(self):
maxHQI = None
if len(self.measurements) > 0:
hqis = []
for meas in self.measurements:
hqis.append(meas.getHQI())
return max(hqis)
maxHQI = max(hqis)
return maxHQI
def getHQIOfMeasurementIndex(self, index):
for meas in self.measurements:
......
......@@ -239,7 +239,7 @@ def getParticleCenterPoint(contour):
return x, y
def loadFullimageFromDataset(dataset):
return cv2imread_fix(dataset.getImageName(), cv2.COLOR_BGR2RGB)
return cv2imread_fix(dataset.getImageName())
def loadZValImageFromDataset(dataset):
return cv2imread_fix(dataset.getZvalImageName(), cv2.IMREAD_GRAYSCALE)
\ No newline at end of file
......@@ -44,6 +44,8 @@ class ParticleContainer(object):
def clearMeasurements(self):
self.measurements = []
for particle in self.particles:
particle.measurements = []
def setMeasurementScanIndex(self, indexOfMeasurment, scanIndex):
self.measurements[indexOfMeasurment].ramanScanIndex = scanIndex
......@@ -94,7 +96,7 @@ class ParticleContainer(object):
particle.contour = contours[index]
def setParticleStats(self, particlestats):
assert len(self.particles) == len(particlestats)
assert len(self.particles) == len(particlestats), f'numParticles = {len(self.particles)}, len partStats = {len(particlestats)}'
for index, particle in enumerate(self.particles):
particle.__dict__.update(particlestats[index].__dict__)
......
......@@ -148,7 +148,7 @@ class DataSet(object):
'minparticlearea': 20,
'minparticledistance': 20,
'measurefrac': 1,
'compactness': 0.1,
'compactness': 0.0,
'seedRad': 3}
self.particleContainer = ParticleContainer(self)
......
......@@ -20,11 +20,14 @@ If not, see <https://www.gnu.org/licenses/>.
"""
import numpy as np
from PyQt5 import QtCore, QtWidgets, QtGui
from .segmentation import Segmentation
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg
import matplotlib.pyplot as plt
from threading import Thread
from .segmentation import Segmentation
from .analysis.particleCharacterization import getParticleStatsWithPixelScale, loadZValImageFromDataset
from .errors import InvalidParticleError
Nscreen = 1000
class HistWidget(QtWidgets.QWidget):
......@@ -377,8 +380,8 @@ class ParticleDetectionView(QtWidgets.QWidget):
grid.addWidget(label, i+1, 0, QtCore.Qt.AlignLeft)
grid.addWidget(self.seedradiusedit, i+1, 1, QtCore.Qt.AlignLeft)
grid.addWidget(self.showseedpoints, i+2, 0, 1, 2, QtCore.Qt.AlignLeft)
grid.addWidget(QtWidgets.QLabel("Use Ctrl for seeds and Ctrl+Shift for delete points"), i+3, 0, 1, 2, QtCore.Qt.AlignLeft)
grid.addWidget(QtWidgets.QLabel("Ctrl+Alt removes seeds near cursor"), i+4, 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)
group.setLayout(grid)
vbox.addWidget(group)
......@@ -565,18 +568,12 @@ class ParticleDetectionView(QtWidgets.QWidget):
self.seg.setParameters(**kwargs)
seedradius = self.seedradiusedit.value()
if showname is not None:
stepImg, imgtype = self.seg.apply2Image(img, self.imglabel.seedpoints,
self.imglabel.seeddeletepoints,
seedradius,
self.dataset,
return_step=showname)
stepImg, imgtype = self.seg.apply2Image(img, self.imglabel.seedpoints, self.imglabel.seeddeletepoints,
seedradius, self.dataset, return_step=showname)
self.imglabel.showStep(stepImg, imgtype)
else:
measurementpoints, contours, particlestats = self.seg.apply2Image(img,
self.imglabel.seedpoints,
self.imglabel.seeddeletepoints,
seedradius,
self.dataset)
measurementpoints, contours = self.seg.apply2Image(img, self.imglabel.seedpoints, self.imglabel.seeddeletepoints,
seedradius, self.dataset)
self.imglabel.updateDetectionResults(contours, measurementpoints)
@QtCore.pyqtSlot()
......@@ -628,13 +625,14 @@ class ParticleDetectionView(QtWidgets.QWidget):
def checkOnComputation(self):
if self.thread is not None:
if not self.threadrunning:
#self.thread.join()
self.thread = None
self.unBlockUI()
self.pdetectall.setText("Detect all")
self.imageUpdate.emit(self.view.microscopeMode)
if self.dataset is not None:
self.setWindowTitle(str(self.dataset.particleContainer.getNumberOfParticles()) + " Particles")
numParticles = self.dataset.particleContainer.getNumberOfParticles()
numMeasurements = self.dataset.particleContainer.getNumberOfMeasurements()
self.setWindowTitle(f'{numParticles} Particles ({numMeasurements} Measurements)')
else:
self.timer.start(100.)
......@@ -648,27 +646,27 @@ class ParticleDetectionView(QtWidgets.QWidget):
kwargs[name] = valuefunc()
seedradius = self.seedradiusedit.value()
self.seg.setParameters(**kwargs)
measurementPoints, contours, particlestats = 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
return
if self.dataset is not None:
self.applyResultsToDataset(measurementPoints, contours, particlestats)
self.applyResultsToDataset(measurementPoints, contours)
self.threadrunning = False
def applyResultsToDataset(self, measurementPoints, contours, particlestats):
def applyResultsToDataset(self, measurementPoints, contours):
self.dataset.ramanscandone = False
particlestats = self.getParticleStats(contours)
particleContainer = self.dataset.particleContainer
numParticles = len(contours)
particleContainer.initializeParticles(numParticles)
particleContainer.setParticleContours(contours)
particleContainer.setParticleStats(particlestats)
particleContainer.clearMeasurements()
for particleIndex in measurementPoints.keys():
measPoints = measurementPoints[particleIndex]
for index, point in enumerate(measPoints):
......@@ -680,3 +678,16 @@ class ParticleDetectionView(QtWidgets.QWidget):
self.dataset.particleDetectionDone = True
self.dataset.mode = "prepareraman"
self.dataset.save()
def getParticleStats(self, contours):
particlestats = []
zvalimg = loadZValImageFromDataset(self.dataset)
for contour in contours:
try:
stats = getParticleStatsWithPixelScale(contour, self.dataset, fullimage=self.img, zimg=zvalimg)
particlestats.append(stats)
except InvalidParticleError:
print('invalid contour in detection, skipping partile. Contour is:', contour)
continue
return particlestats
\ No newline at end of file
......@@ -77,6 +77,7 @@ def legacyConversion(dset, recreatefullimage=False):
del dset.particleimgs
dset.version = 1
dset.save()
if dset.version == 1:
print("Converting legacy version 1 to 2")
......@@ -95,17 +96,20 @@ def legacyConversion(dset, recreatefullimage=False):
dset.particles2spectra = [[int(np.where(dset.ramanscansortindex == i)[0])] for i in range(len(dset.ramanscansortindex))]
dset.version = 2
dset.save()
if dset.version == 2:
print("Converting legacy version 2 to 3")
transferParticleStatsToParticleContainer(dset)
dset.version = 3
dset.save()
if dset.version == 3:
print("Converting legacy version 3 to 4")
updateParticleStats(dset)
removeLegacyAttributes(dset)
dset.version = 4
dset.save()
# add later conversion for higher version numbers here
......
......@@ -93,7 +93,7 @@ class BackGroundManager(QtWidgets.QWidget):
QtWidgets.QMessageBox.about(self, 'Warning', 'No Background Image is aquired')
return
else:
from opticalscan import loadAndPasteImage
from .opticalscan import loadAndPasteImage
self.dataset = self.parentOSwidget.dataset
#acquire images in 3x3 area to preview quality of background subtraction
......
......@@ -94,7 +94,7 @@ def loadAndPasteImage(srcnames, fullimage, fullzval, width, height,
curImg = cv2imread_fix(name)
if background is not None:
curImg = subtractBackground(curImg, background)
colimgs.append(cv2.cvtColor(curImg, cv2.COLOR_BGR2RGB))
colimgs.append(curImg)
img, zval = imageStacking(colimgs)
x, y = p
......@@ -276,7 +276,7 @@ class OpticalScan(QtWidgets.QWidget):
self.zmaxedit.setMaximumWidth(100)
label3 = QtWidgets.QLabel("Focus steps:", self)
self.nzedit = QtWidgets.QSpinBox(self)
self.nzedit.setRange(2,20)
self.nzedit.setRange(1,20)
self.nzedit.setValue(3)
self.nzedit.setMaximumWidth(100)
self.hdrcheck = QtWidgets.QCheckBox("High dynamic range", self)
......@@ -451,7 +451,7 @@ class OpticalScan(QtWidgets.QWidget):
width, height, rotationvalue = self.ramanctrl.getImageDimensions(self.view.microscopeMode)
pshift = self.ramanctrl.getRamanPositionShift()
self.dataset.pshift = pshift
img = cv2.cvtColor(cv2imread_fix(self.dataset.getTmpImageName()), cv2.COLOR_BGR2RGB)
img = cv2imread_fix(self.dataset.getTmpImageName())
self.dataset.imagedim_bf = self.ramanctrl.getImageDimensions('bf')
self.dataset.pixelscale_bf = self.dataset.imagedim_bf[0]/img.shape[1] #=imagedim_width/shape[1]
......
......@@ -205,7 +205,7 @@ class WITecCOM(RamanBase):
z = self.PosZCurUserFloatMan.GetSingleValueAsDouble()[1]
return z
def moveToAbsolutePosition(self, x, y, z=None, epsxy=0.11, epsz=0.011, debugReturn=False, measurementRunning=False):
def moveToAbsolutePosition(self, x, y, z=None, epsxy=0.11, epsz=0.011):
assert self.connected
initpos = self.getPosition()
# move only if new position is really different; repeat if new position is ignored (happens some times)
......
......@@ -45,7 +45,7 @@ class RamanBase(object):
def getUserZ(self):
raise NotImplementedError
def moveToAbsolutePosition(self, x, y, z=None, epsxy=0.11, epsz=0.011, debugReturn=False, measurementRunning=False):
def moveToAbsolutePosition(self, x, y, z=None, epsxy=0.11, epsz=0.011):
raise NotImplementedError
def moveZto(self, z, epsz=0.011):
......
......@@ -39,10 +39,10 @@ class SimulatedRaman(RamanBase):
self.currentZ = 0.
# some plausible data to simulate consecutively changing positions
self.positionlist = np.array([[ -1201, 1376, -1290],
[ -1195, -9200, -1279],
[ 1097, -9254, -1297],
[ 2704.1, -1788.2, -138.1],
[ 3884. , -2650.8, -138.1]])
[ -1195, -1200, -1279],
[ 1097, -1254, -1297],
[ 2704.1, 1288.2, -1381],
[ 1884. , -1500.8, -1381]])
self.znum = 4
self.gridnum = 36
self.positionindex = 0
......@@ -78,7 +78,7 @@ class SimulatedRaman(RamanBase):
else:
return self.currentZ
def moveToAbsolutePosition(self, x, y, z=None, epsxy=0.11, epsz=0.011, debugReturn=False, measurementRunning=False):
def moveToAbsolutePosition(self, x, y, z=None, epsxy=0.11, epsz=0.011):
assert self.connected
print('moving to:', x, y, z, file=stdout)
if z is None:
......
......@@ -67,7 +67,7 @@ def scan(ramanSettings, positions, controlclass, dataqueue, stopevent,
x, y, z = p
print("time:", time(), flush=True)
print("position:", x, y, z, flush=True)
ramanctrl.moveToAbsolutePosition(x, y, z, measurementRunning=True)
ramanctrl.moveToAbsolutePosition(x, y, z)
print("move done", flush=True)
ramanctrl.triggerMeasurement(i)
print("trigger done", flush=True)
......@@ -145,7 +145,6 @@ class RamanScanUI(QtWidgets.QWidget):
self.setLayout(vbox)
self.setWindowTitle("Raman Scan")
#self.show()
self.setVisible(False)
def makeGetFnameLambda(self, msg, path, fileType, btn):
......@@ -159,9 +158,10 @@ class RamanScanUI(QtWidgets.QWidget):
def resetDataset(self, ds):
self.dataset = ds
numParticles = self.dataset.particleContainer.getNumberOfParticles()
numMeasurements = self.dataset.particleContainer.getNumberOfMeasurements()
if numParticles>0:
self.prun.setEnabled(True)
self.setWindowTitle(str(numParticles) + " Particles")
self.setWindowTitle(f'{numParticles} Particles ({numMeasurements} Measurements)')
@QtCore.pyqtSlot()
def stopScan(self):
......@@ -234,6 +234,17 @@ class RamanScanUI(QtWidgets.QWidget):
self.view.saveDataSet()
self.view.prepareAnalysis()
self.view.zoomDisplay(2.0)
if self.ramanctrl.name == 'RenishawCOM':
QtWidgets.QMessageBox.about(self, "Info", "Control is headed over to Renishaw Instrument, Gepard is stopping here")
ramanSettings['Points'] = scanpoints
self.ramanctrl.initiateMeasurement(ramanSettings)
self.ramanctrl.disconnect()
self.dataset.ramanscandone = True
self.view.saveDataSet()
self.close()
return
else:
self.view.highLightRamanIndex(0)
self.view.blockUI()
self.group2.setEnabled(False)
......
......@@ -193,7 +193,6 @@ class SampleView(QtWidgets.QGraphicsView):
self.oscanwidget.setVisible(False)
if self.detectionwidget is not None:
self.detectionwidget.close()
self.detectionwidget.destroy()
self.detectionwidget = None
self.ramanwidget.setVisible(False)
self.mode = mode
......@@ -530,7 +529,6 @@ class SampleView(QtWidgets.QGraphicsView):
if self.mode == "ParticleDetection" or self.mode == "ParticleAnalysis":
self.resetParticleContours()
if data is None and os.path.exists(fname):
# data = cv2.cvtColor(cv2imread_fix(fname), cv2.COLOR_BGR2RGB) ##With this line the B and R channel are swapped, which leads to a wrong presentation of the image in gepard..... Why was this line here?
data = cv2imread_fix(fname)
self.imgdata = data
if data is not None:
......@@ -579,10 +577,17 @@ class SampleView(QtWidgets.QGraphicsView):
Removes items from the GraphicsScene. ContourItems remain, however..
:return:
"""
for itemList in [self.fititems, self.scanitems, self.ramanscanitems]:
for item in itemList:
for item in self.fititems:
self.scene().removeItem(item)
itemList = []
self.fititems = []
for item in self.scanitems:
self.scene().removeItem(item)
self.scanitems = []
for item in self.ramanscanitems:
self.scene().removeItem(item)
self.ramanscanitems = []
edges, nodes = self.boundaryitems
for item in edges:
......@@ -591,7 +596,6 @@ class SampleView(QtWidgets.QGraphicsView):
self.scene().removeItem(item)
self.boundaryitems = [], []
@QtCore.pyqtSlot()
def resetScanPositions(self):
"""
......
......@@ -26,25 +26,15 @@ from scipy.interpolate import InterpolatedUnivariateSpline
from scipy import ndimage as ndi
from skimage.feature import peak_local_max
from skimage.morphology import watershed
from random import random
from .errors import InvalidParticleError
import random
def closeHolesOfSubImage(subimg):
#Add padding to TrehsholdImage
subimg = cv2.copyMakeBorder(subimg, 1, 1, 1, 1, 0)
# Copy the thresholded image.
im_floodfill = subimg.copy()
# Mask used to flood filling.
# Notice the size needs to be 2 pixels than the image.
h, w = subimg.shape[:2]
mask = np.zeros((h+2, w+2), np.uint8)
# Floodfill from point (0, 0)
cv2.floodFill(im_floodfill, mask, (0,0), 255);
# Invert floodfilled image
im_floodfill_inv = cv2.bitwise_not(im_floodfill)
# Combine the two images to get the foreground.
im_out = subimg | im_floodfill_inv
return im_out[1:-1, 1:-1]
......@@ -83,11 +73,12 @@ class Segmentation(object):
'invertThresh': False,
'maxholebrightness': 0.5,
'minparticlearea': 20,
'maxparticlearea': 10000,
'enableMaxArea': False,
'maxparticlearea': 100000,
'minparticledistance': 20,
'closeBackground': True,
'measurefrac': 1,
'compactness': 0.,
'compactness': 0.0,
'seedRad': 3}
if dataset is not None:
self.detectParams = dataset.detectParams
......@@ -111,6 +102,7 @@ class Segmentation(object):
Parameter("upThresh", float, self.detectParams['upThresh'], .01, 1.0, 2, .02, helptext="Upper threshold", show=True),
Parameter("maxholebrightness", float, self.detectParams['maxholebrightness'], 0, 1, 2, 0.02, helptext="Close holes brighter than..", show = True),
Parameter("minparticlearea", int, self.detectParams['minparticlearea'], 1, 1000, 0, 50, helptext="Min. particle pixel area", show=False),
Parameter("enableMaxArea", np.bool, self.detectParams['enableMaxArea'], helptext="enable filtering for maximal pixel area", show=False, linkedParameter='maxparticlearea'),
Parameter("maxparticlearea", int, self.detectParams['maxparticlearea'], 10, 1E9, 0, 50, helptext="Max. particle pixel area", show=True),
Parameter("minparticledistance", int, self.detectParams['minparticledistance'], 5, 1000, 0, 5, helptext="Min. distance between particles", show=False),
Parameter("measurefrac", float, self.detectParams['measurefrac'], 0, 1, 2, stepsize = 0.05, helptext="measure fraction of particles", show=False),
......@@ -256,10 +248,18 @@ class Segmentation(object):
subdist = cv2.distanceTransform(subimg, cv2.DIST_L2,3)
subfg = np.uint8(peak_local_max(subdist, mindistance, indices = False))
if subfg.max() > 0 and random() < self.measurefrac: #i.e., at least one maximum value was added
# if subfg.max() > 0 and random() < self.measurefrac: #i.e., at least one maximum value was added
# sure_fg[up:(up+height), left:(left+width)] += subfg
#
# elif random() < self.measurefrac:
# #simply get maximum of subdist
# submax = np.where(subdist == subdist.max())
# sure_fg[up+submax[0][0], left+submax[1][0]] = 1
if subfg.max() > 0: #i.e., at least one maximum value was added
sure_fg[up:(up+height), left:(left+width)] += subfg
elif random() < self.measurefrac:
else:
#simply get maximum of subdist
submax = np.where(subdist == subdist.max())
sure_fg[up+submax[0][0], left+submax[1][0]] = 1
......@@ -360,7 +360,11 @@ class Segmentation(object):
if self.cancelcomputation:
return None, None, None
thresh = self.filterThresholdByAreas(thresh, self.minparticlearea, self.maxparticlearea)
if self.enableMaxArea:
maxArea = self.maxparticlearea
else:
maxArea = np.inf
thresh = self.filterThresholdByAreas(thresh, self.minparticlearea, maxArea)
print('filter threshold by areas')
if return_step == 'maxparticlearea': return thresh, 0
if self.cancelcomputation:
......@@ -386,6 +390,7 @@ class Segmentation(object):
for p in np.int32(seedpoints):
cv2.circle(sure_fg, tuple([p[0], p[1]]), int(p[2]), 1, -1)
cv2.circle(sure_bg, tuple([p[0], p[1]]), int(p[2]), 1, -1)
for p in np.int32(deletepoints):
cv2.circle(sure_fg, tuple([p[0], p[1]]), int(p[2]), 0, -1)
cv2.circle(sure_bg, tuple([p[0], p[1]]), int(p[2]), 0, -1)
......@@ -413,43 +418,38 @@ class Segmentation(object):
print("distanceTransform")
if self.cancelcomputation:
return None, None, None
twatershed = time()
#ich habe jetzt nur noch den Skimage Watershed integriert. Oben auskommentiert der opencv watershed, falls wir ihn doch nochmal für irgendwas brauchen...
markers = ndi.label(sure_fg)[0]
markers = watershed(-dist_transform, markers, mask=sure_bg, compactness = self.compactness, watershed_line = True) #labels = 0 for background, 1... for particles
print("watershed")
print("watershed, elapsed time:", time()-twatershed, "seconds")
if self.cancelcomputation:
return None, None, None
if return_step=="watershed":
return np.uint8(255*(markers!=0)), 0
tcont = time()
if cv2.__version__ > '3.5':