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
from .segmentation import Segmentation
from .analysis.particleCharacterization import getParticleStatsWithPixelScale, loadZValImageFromDataset
from .errors import InvalidParticleError
from .uielements import TimeEstimateProgressbar
from .scenePyramid import ScenePyramid
Nscreen = 1000
......@@ -290,8 +291,10 @@ class ParticleDetectionView(QtWidgets.QWidget):
self.img = pyramid.getFullImage()
self.imgclip = 0, 0, 0, 0
self.seg = Segmentation(self.dataset, self)
self.seg.detectionState.connect(self.updateDetectionState)
self.thread = None
self.view : QtWidgets.QGraphicsView = parent
self.threadrunning = False
self.view = parent
vbox = QtWidgets.QVBoxLayout()
hbox = QtWidgets.QHBoxLayout()
......@@ -315,7 +318,7 @@ class ParticleDetectionView(QtWidgets.QWidget):
self.showseedpoints.setChecked(True)
self.setImageCenter()
group = QtWidgets.QGroupBox("Detection settings", self)
self.detectParamsGroup = QtWidgets.QGroupBox("Detection settings", self)
grid = QtWidgets.QGridLayout()
self.parameters = []
checkBoxesToLink = {}
......@@ -397,8 +400,8 @@ class ParticleDetectionView(QtWidgets.QWidget):
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+Alt removes seeds near cursor"), i+4, 0, 1, 2, QtCore.Qt.AlignLeft)
group.setLayout(grid)
vbox.addWidget(group)
self.detectParamsGroup.setLayout(grid)
vbox.addWidget(self.detectParamsGroup)
self.updateSeedsInSampleViewBtn = QtWidgets.QPushButton("Update Seedpoints in fullimage view", self)
self.updateSeedsInSampleViewBtn.released.connect(self.updateSeedsInSampleview)
......@@ -419,6 +422,9 @@ class ParticleDetectionView(QtWidgets.QWidget):
self.autoUpdateCheckBox.setMaximumWidth(200)
self.autoUpdateCheckBox.setChecked(True)
vbox.addWidget(self.autoUpdateCheckBox)
self.progressbar = TimeEstimateProgressbar()
vbox.addWidget(self.progressbar)
hbox2 = QtWidgets.QHBoxLayout()
self.pdetectsub = QtWidgets.QPushButton("Detect", self)
......@@ -634,21 +640,22 @@ class ParticleDetectionView(QtWidgets.QWidget):
self.updateImageSeeds()
def detectShow(self, showname):
self.saveDetectParams(self.dataset)
img = self.subimg.copy()
kwargs = {}
for ui, name, valuefunc, showbtn in self.parameters:
kwargs[name] = valuefunc()
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)
self.imglabel.showStep(stepImg, imgtype)
else:
measurementpoints, contours = self.seg.apply2Image(img, self.imglabel.seedpoints, self.imglabel.seeddeletepoints,
seedradius, self.dataset)
self.imglabel.updateDetectionResults(contours, measurementpoints)
if not self.threadrunning:
self.saveDetectParams(self.dataset)
img = self.subimg.copy()
kwargs = {}
for ui, name, valuefunc, showbtn in self.parameters:
kwargs[name] = valuefunc()
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)
self.imglabel.showStep(stepImg, imgtype)
else:
measurementpoints, contours = self.seg.apply2Image(img, self.imglabel.seedpoints, self.imglabel.seeddeletepoints,
seedradius, self.dataset)
self.imglabel.updateDetectionResults(contours, measurementpoints)
@QtCore.pyqtSlot()
def clearDetection(self):
......@@ -671,16 +678,26 @@ class ParticleDetectionView(QtWidgets.QWidget):
def blockUI(self):
self.pdetectsub.setEnabled(False)
self.pclear.setEnabled(False)
self.detectParamsGroup.setEnabled(False)
self.updateSeedsInSampleViewBtn.setEnabled(False)
self.hideSeedsInSampleViewBtn.setEnabled(False)
def unBlockUI(self):
self.pdetectsub.setEnabled(True)
self.pclear.setEnabled(True)
self.detectParamsGroup.setEnabled(True)
self.updateSeedsInSampleViewBtn.setEnabled(True)
self.hideSeedsInSampleViewBtn.setEnabled(True)
def raiseWarning(self, warning):
QtWidgets.QMessageBox.critical(self, "Warning", warning)
@QtCore.pyqtSlot()
def detectParticles(self):
"""
Detect all particles
:return:
"""
self.saveDetectParams(self.dataset)
if self.thread is not None and self.thread.is_alive():
self.cancelThread()
......@@ -700,6 +717,7 @@ class ParticleDetectionView(QtWidgets.QWidget):
if self.thread is not None:
if not self.threadrunning:
self.thread = None
self.progressbar.disable()
self.unBlockUI()
self.pdetectall.setText("Detect all")
self.imageUpdate.emit(self.view.microscopeMode)
......@@ -709,6 +727,25 @@ class ParticleDetectionView(QtWidgets.QWidget):
self.setWindowTitle(f'{numParticles} Particles ({numMeasurements} Measurements)')
else:
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):
kwargs = {}
......@@ -720,8 +757,9 @@ class ParticleDetectionView(QtWidgets.QWidget):
kwargs[name] = valuefunc()
seedradius = self.seedradiusedit.value()
self.seg.setParameters(**kwargs)
measurementPoints, contours= self.seg.apply2Image(self.img, seedpoints, deletepoints, seedradius, self.dataset)
if measurementPoints is None: # computation was canceled
return
......
......@@ -28,8 +28,9 @@ import sys, os
import cv2
from .helperfunctions import cv2imread_fix, cv2imwrite_fix
from time import time
import datetime
import sys
from .opticalbackground import BackGroundManager
from .uielements import TimeEstimateProgressbar
from .zlevelsetter import ZLevelSetter
from .scenePyramid import ScenePyramid
......@@ -337,13 +338,10 @@ class OpticalScan(QtWidgets.QWidget):
self.prun.released.connect(self.run)
self.pexit.released.connect(self.stopScan)
self.prun.setEnabled(False)
self.timelabeltext = "Estimated time to finish: "
self.progressbar = QtWidgets.QProgressBar(self)
self.progresstime = QtWidgets.QLabel(self.timelabeltext, self)
self.progresstime.setEnabled(False)
self.progressbar.setEnabled(False)
self.progressbar = TimeEstimateProgressbar()
self.progressbar.disable()
radioGroup = QtWidgets.QGroupBox('Shape')
radioLayout = QtWidgets.QHBoxLayout()
self.circlerad = QtWidgets.QRadioButton("Circle")
......@@ -404,7 +402,6 @@ class OpticalScan(QtWidgets.QWidget):
optionsLayout.addLayout(vbox2)
mainLayout.addLayout(optionsLayout)
mainLayout.addWidget(self.progresstime)
mainLayout.addWidget(self.progressbar)
mainLayout.addLayout(btnLayout)
......@@ -441,6 +438,7 @@ class OpticalScan(QtWidgets.QWidget):
QtWidgets.QMessageBox.Yes |
QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No)
if reply == QtWidgets.QMessageBox.Yes:
self.progressbar.resetTimerAndCounter()
self.timer.stop()
self.processstopevent.set()
self.process.join()
......@@ -684,12 +682,9 @@ class OpticalScan(QtWidgets.QWidget):
self.dataqueue, self.processstopevent,
self.logpath, self.hdrcheck.isChecked()))
self.process.start()
self.starttime = time()
self.progresstime.setEnabled(True)
self.progressbar.setEnabled(True)
self.progressbar.setRange(0, len(self.dataset.grid))
self.progressbar.setValue(0)
#self.view.imgdata = None
self.progressbar.enable()
self.progressbar.resetTimerAndCounter()
self.progressbar.setMaxValue(len(self.dataset.grid))
self.pyramid.resetScene()
self.view.blockUI()
grid = np.asarray(self.dataset.grid)
......@@ -734,14 +729,7 @@ class OpticalScan(QtWidgets.QWidget):
removeSrcTiles(names, self.dataset.getScanPath())
self.progressbar.setValue(i+1)
if i > 3:
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)
self.imageUpdate.emit(self.view.microscopeMode)
if i==Ngrid-1:
# cv2imwrite_fix(self.dataset.getImageName(), cv2.cvtColor(self.view.imgdata, cv2.COLOR_RGB2BGR))
......@@ -756,9 +744,8 @@ class OpticalScan(QtWidgets.QWidget):
self.view.saveDataSet()
self.view.unblockUI()
self.view.switchMode("ParticleDetection")
self.progressbar.setValue(0)
self.progressbar.setEnabled(False)
self.progresstime.setEnabled(False)
self.progressbar.resetTimerAndCounter()
self.progressbar.disable()
self.close()
return
self.timer.start(100.)
......
......@@ -24,10 +24,10 @@ import numpy as np
from multiprocessing import Process, Queue, Event
import queue
from time import time
from .external import tsp
import datetime
import sys
import os
from .external import tsp
from .uielements import TimeEstimateProgressbar
def reorder(points, N=20):
y0, y1 = points[:,1].min(), points[:,1].max()
......@@ -110,18 +110,15 @@ class RamanScanUI(QtWidgets.QWidget):
self.pexit = QtWidgets.QPushButton("Cancel", self)
self.pexit.released.connect(self.stopScan)
self.prun.setEnabled(False)
self.progressbar = QtWidgets.QProgressBar(self)
self.timelabeltext = "Estimated time to finish: "
self.progresstime = QtWidgets.QLabel(self.timelabeltext, self)
self.progresstime.setEnabled(False)
self.progressbar.setEnabled(False)
self.progressbar = TimeEstimateProgressbar()
self.progressbar.disable()
hbox.addStretch()
hbox.addWidget(self.pexit)
vbox.addWidget(self.paramsGroup)
vbox.addLayout(hbox)
vbox.addWidget(self.progresstime)
vbox.addWidget(self.progressbar)
self.setLayout(vbox)
......@@ -189,6 +186,7 @@ class RamanScanUI(QtWidgets.QWidget):
QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No)
if reply == QtWidgets.QMessageBox.Yes:
self.timer.stop()
self.progressbar.resetTimerAndCounter()
self.processstopevent.set()
self.process.join()
self.dataqueue.close()
......@@ -264,10 +262,9 @@ class RamanScanUI(QtWidgets.QWidget):
self.view.highLightRamanIndex(0)
self.view.blockUI()
self.paramsGroup.setEnabled(False)
self.progresstime.setEnabled(True)
self.progressbar.setEnabled(True)
self.progressbar.setRange(0, len(scanpoints))
self.progressbar.setValue(0)
self.progressbar.enable()
self.progressbar.resetTimerAndCounter()
self.progressbar.setMaxValue(len(scanpoints))
self.ramanctrl.disconnect()
self.processstopevent = Event()
self.dataqueue = Queue()
......@@ -295,11 +292,6 @@ class RamanScanUI(QtWidgets.QWidget):
self.view.highLightRamanIndex(i+1) #go to next scanmarker
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:
self.process.join()
self.dataqueue.close()
......@@ -307,9 +299,8 @@ class RamanScanUI(QtWidgets.QWidget):
self.dataset.ramanscandone = True
self.view.saveDataSet()
self.view.unblockUI()
self.progressbar.setValue(0)
self.progressbar.setEnabled(False)
self.progresstime.setEnabled(False)
self.progressbar.resetTimerAndCounter()
self.progressbar.disable()
self.close()
return
self.timer.start(100.)
......
......@@ -28,6 +28,8 @@ from skimage.feature import peak_local_max
from skimage.morphology import watershed
import skfuzzy as fuzz
import random
from PyQt5 import QtCore
def closeHolesOfSubImage(subimg):
subimg = cv2.copyMakeBorder(subimg, 1, 1, 1, 1, 0)
......@@ -63,8 +65,10 @@ class MeasurementPoint(object):
self.x = x
self.y = y
class Segmentation(object):
def __init__(self, dataset=None, parent=None):
class Segmentation(QtCore.QObject):
detectionState = QtCore.pyqtSignal(str)
def __init__(self, dataset=None, parent=None):
super(Segmentation, self).__init__()
self.cancelcomputation = False
self.parent = parent
self.defaultParams = {'adaptiveHistEqu': False,
......@@ -84,6 +88,7 @@ class Segmentation(object):
'minparticledistance': 20,
'closeBackground': False,
'fuzzycluster': False,
'maxComponentSize': 20000,
'measurefrac': 1,
'compactness': 0.0,
'seedRad': 3}
......@@ -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("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("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("compactness", float, self.detectParams['compactness'], 0, 1, 2, 0.05, helptext="watershed compactness", show=False),
Parameter("watershed", None, helptext="Show watershed markers", show=True),
......@@ -140,8 +146,10 @@ class Segmentation(object):
:return:
"""
t0 = time()
self.detectionState.emit('DO: setup')
gray = self.convert2Gray(img)
self.detectionState.emit('finished GrayScale')
print("gray")
if self.adaptiveHistEqu:
......@@ -149,6 +157,7 @@ class Segmentation(object):
numTilesY = round(img.shape[0]/self.claheTileSize)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(numTilesY,numTilesX))
gray = clahe.apply(gray)
self.detectionState.emit('finished CLAHE')
if return_step=="claheTileSize": return gray, 0
print("adaptive Histogram Adjustment")
......@@ -158,7 +167,8 @@ class Segmentation(object):
if self.activateContrastCurve:
xi, arr = self.calculateHistFunction(self.contrastCurve)
gray = arr[gray]
print("contrast curve")
print("contrast curve")
self.detectionState.emit('finished Contrast Curve')
if self.cancelcomputation:
return None, None
......@@ -171,6 +181,7 @@ class Segmentation(object):
del gray
if return_step=="blurRadius": return blur, 0
self.detectionState.emit('finished Blurring')
print("blur")
if self.cancelcomputation:
return None, None
......@@ -215,6 +226,7 @@ class Segmentation(object):
thresh = self.closeBrightHoles(thresh, blur, self.maxholebrightness)
del blur
print("thresholded")
self.detectionState.emit('finished thresholding')
# modify thresh with seedpoints and deletepoints
for p in np.int32(seedpoints):
......@@ -235,6 +247,8 @@ class Segmentation(object):
'''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'''
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
measurementPoints = {}
......@@ -249,7 +263,6 @@ class Segmentation(object):
else:
previewImage = np.zeros(img.shape[:2])
for label in range(1, n):
area = stats[label, cv2.CC_STAT_AREA]
if self.minparticlearea < area < maxArea:
......@@ -257,83 +270,110 @@ class Segmentation(object):
left = stats[label, cv2.CC_STAT_LEFT]
width = stats[label, cv2.CC_STAT_WIDTH]
height = stats[label, cv2.CC_STAT_HEIGHT]
# if width > 25000 or height > 25000:
if False:
print(f'skipping{label} of {n} compontents, too large: {width} x {height} pixel!!!')
else:
print(f'processing {label} of {n} compontents, {width} x {height} pixel')
subthresh = np.uint8(255 * (labels[up:(up+height), left:(left+width)] == label))
subdist = cv2.distanceTransform(subthresh, cv2.DIST_L2, 3)
sure_fg = self.getSureForeground(subthresh, subdist, self.minparticledistance)
sure_bg = cv2.dilate(subthresh, np.ones((5, 5)), iterations = 1)
if self.closeBackground:
sure_bg = self.closeHoles(sure_bg)
# modify sure_fg and sure_bg with seedpoints and deletepoints
for p in np.int32(seedpoints):
cv2.circle(sure_fg, tuple([p[0]-left, p[1]-up]), int(p[2]), 1, -1)
cv2.circle(sure_bg, tuple([p[0]-left, p[1]-up]), int(p[2]), 1, -1)
for p in np.int32(deletepoints):
cv2.circle(sure_fg, tuple([p[0]-left, p[1]-up]), int(p[2]), 0, -1)
cv2.circle(sure_bg, tuple([p[0]-left, p[1]-up]), int(p[2]), 0, -1)
if self.cancelcomputation:
return None, None
if return_step=="sure_fg":
preview_surefg = self.addToPreviewImage(sure_fg, up, left, preview_surefg)
preview_surebg = self.addToPreviewImage(sure_bg, up, left, preview_surebg)
continue
unknown = cv2.subtract(sure_bg, sure_fg)
ret, markers = cv2.connectedComponents(sure_fg)
markers = markers+1
markers[unknown==255] = 0
markers = ndi.label(sure_fg)[0]
subthresh = np.uint8(255 * (labels[up:(up+height), left:(left+width)] == label))
scaleFactor = 1.0
if width > self.maxComponentSize or height > self.maxComponentSize:
scaleFactor = max([width/self.maxComponentSize, height/self.maxComponentSize])
subthresh = cv2.resize(subthresh, None, fx=1/scaleFactor, fy=1/scaleFactor)
subdist = cv2.distanceTransform(subthresh, cv2.DIST_L2, 3)
minDistance = round(self.minparticledistance / scaleFactor)
sure_fg = self.getSureForeground(subthresh, subdist, minDistance)
sure_bg = cv2.dilate(subthresh, np.ones((5, 5)), iterations = 1)
if self.closeBackground:
sure_bg = self.closeHoles(sure_bg)
# modify sure_fg and sure_bg with seedpoints and deletepoints
for p in np.int32(seedpoints):
x = int(round(p[0] / scaleFactor)-left)
y = int(round(p[1] / scaleFactor) - up)
radius = int(round(p[2] / scaleFactor))
cv2.circle(sure_fg, (x, y), radius, 1, -1)
cv2.circle(sure_bg, (x, y), radius, 1, -1)
for p in np.int32(deletepoints):
x = int(round(p[0] / scaleFactor) - left)
y = int(round(p[1] / scaleFactor) - up)
radius = int(round(p[2] / scaleFactor))
cv2.circle(sure_fg, (x, y), radius, 1, -1)
cv2.circle(sure_bg, (x, y), radius, 1, -1)
if self.cancelcomputation:
return None, None
if return_step=="sure_fg":
preview_surefg = self.addToPreviewImage(sure_fg, up, left, preview_surefg)
preview_surebg = self.addToPreviewImage(sure_bg, up, left, preview_surebg)
continue
unknown = cv2.subtract(sure_bg, sure_fg)
ret, markers = cv2.connectedComponents(sure_fg)
markers = markers+1
markers[unknown==255] = 0
markers = ndi.label(sure_fg)[0]
try:
markers = watershed(-subdist, markers, mask=sure_bg, compactness = self.compactness, watershed_line = True) #labels = 0 for background, 1... for particles
if self.cancelcomputation:
return None, None
except MemoryError:
self.parent.raiseWarning('Segmentation failed due to large connected components.\nPlease reduce maximal connected Component Size.')
return None, None
if self.cancelcomputation:
return None, None
if return_step=="watershed":
previewImage = self.addToPreviewImage(markers, up, left, previewImage)
continue
if cv2.__version__ > '3.5':
contours, hierarchy = cv2.findContours(markers, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
else:
temp, contours, hierarchy = cv2.findContours(markers, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
if self.cancelcomputation:
return None, None
if return_step=="watershed":
previewImage = self.addToPreviewImage(markers, up, left, previewImage)
continue
if cv2.__version__ > '3.5':
contours, hierarchy = cv2.findContours(markers, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
else:
temp, contours, hierarchy = cv2.findContours(markers, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
if self.cancelcomputation:
return None, None
tmpcontours = [contours[i] for i in range(len(contours)) if hierarchy[0,i,3]<0]
for cnt in tmpcontours:
contourArea = cv2.contourArea(cnt) * scaleFactor**2
if contourArea >= self.minparticlearea:
tmplabel = markers[cnt[0,0,1],cnt[0,0,0]]
if tmplabel ==0:
continue
x0, x1 = cnt[:,0,0].min(), cnt[:,0,0].max()
y0, y1 = cnt[:,0,1].min(), cnt[:,0,1].max()
tmpcontours = [contours[i] for i in range(len(contours)) if hierarchy[0,i,3]<0]
for cnt in tmpcontours:
if cv2.contourArea(cnt) >= self.minparticlearea:
label = markers[cnt[0,0,1],cnt[0,0,0]]
if label==0:
continue
x0, x1 = cnt[:,0,0].min(), cnt[:,0,0].max()
y0, y1 = cnt[:,0,1].min(), cnt[:,0,1].max()
subimg = (markers[y0:y1+1,x0:x1+1]).copy()
subimg[subimg!=label] = 0
y, x = self.getMeasurementPoints(subimg)
subimg = (markers[y0:y1+1,x0:x1+1]).copy()
subimg[subimg!=tmplabel ] = 0
y, x = self.getMeasurementPoints(subimg)
if scaleFactor != 1:
x0 = int(round(x0 * scaleFactor))
y0 = int(round(y0 * scaleFactor))
x = [int(round(subX * scaleFactor)) for subX in x]
y = [int(round(subY * scaleFactor)) for subY in y]
for i in range(len(cnt)):
cnt[i][0][0] += left
cnt[i][0][1] += up
cnt[i][0][0] = int(round(cnt[i][0][0] * scaleFactor))
cnt[i][0][1] = int(round(cnt[i][0][1] * scaleFactor))
finalcontours.append(cnt)
measurementPoints[particleIndex] = []
for i in range(len(cnt)):
cnt[i][0][0] += left
cnt[i][0][1] += up
finalcontours.append(cnt)
measurementPoints[particleIndex] = []
for index in range(0, len(x)):
newMeasPoint = MeasurementPoint(particleIndex, x[index] + x0 + left, y[index] + y0 + up)
measurementPoints[particleIndex].append(newMeasPoint)
for index in range(0, len(x)):
newMeasPoint = MeasurementPoint(particleIndex, x[index] + x0 + left, y[index] + y0 + up)
measurementPoints[particleIndex].append(newMeasPoint)
particleIndex += 1
particleIndex += 1
self.detectionState.emit(f'DO: newVal={label}')
if return_step == 'sure_fg':
img = np.zeros_like(preview_surefg)
......@@ -360,6 +400,8 @@ class Segmentation(object):
total_time = time()-t0
print('segmentation took', total_time, 'seconds')