Commit 48537f7f authored by Josef Brandt's avatar Josef Brandt

Added the following features:
In optical scan: BackgroundManager for subtraction of background images
In segmentation: CLAHE and multiple thresholding
parent 8fc15b1e
......@@ -347,6 +347,9 @@ class DataSet(object):
def getLegacyDetectImageName(self):
return os.path.join(self.path, "detectimage.png")
def getBackgroundImageName(self):
return os.path.join(self.path, "background.bmp")
def getDetectImageName(self):
raise NotImplementedError("No longer implemented due to change in API")
......
......@@ -101,13 +101,24 @@ class MeasureParticleWindow(QtWidgets.QMainWindow):
fileName = QtWidgets.QFileDialog.getSaveFileName(self, "Create New Project",
defaultPath, "*.pkl")[0]
if fileName:
if fileName.find(' ') < 0:
isValid, msg = self.testFilename(fileName)
if isValid:
self.fname = str(fileName)
self.view.new(self.fname)
self.scalingChanged(1.)
else:
QtWidgets.QMessageBox.critical(self, "Error", "File path must not contain spaces.")
QtWidgets.QMessageBox.critical(self, "Error", msg)
@QtCore.pyqtSlot()
def testFilename(self, fileName):
if self.view.ramanctrl.name == 'RenishawCOM': #the renishawCom does not allow Spaces within filePath
if fileName.find(' ') == 0:
return False, "File path must not contain spaces."
else:
return True, ""
else:
return True, ""
@QtCore.pyqtSlot()
def about(self):
QtWidgets.QMessageBox.about(self, 'GEPARD',
......@@ -193,7 +204,7 @@ class MeasureParticleWindow(QtWidgets.QMainWindow):
self.configRamanCtrlAct.triggered.connect(self.view.configureRamanControl)
if self.view.simulatedRaman:
self.configRamanCtrlAct.setDisabled(True)
def updateModes(self, active=None, maxenabled=None):
ose, osc, pde, pdc, rse, rsc, pae, pac = [False]*8
if maxenabled=="OpticalScan":
......
......@@ -48,15 +48,17 @@ def imageStacking(colimgs):
return im, zval
def combineImages(path, nx, ny, nk, width, height, angle):
imgs = []
full = None
for i in range(nx):
for j in range(ny):
colimgs = []
for k in range(nk):
colimgs.append(cv2.imread(path + f'test_{i}_{j}_{k}.bmp'))
img = imageStacking(colimgs)
imgs.append(img)
if nk > 1:
colimgs = []
for k in range(nk):
colimgs.append(cv2.imread(path + f'test_{i}_{j}_{k}.bmp'))
img = imageStacking(colimgs)
else:
img = cv2.imread(path + f'test_{i}_{j}_1.bmp')
dx = i*.9*img.shape[1]
dy = j*.8*img.shape[0]
c, s = np.cos(np.radians(angle)), np.sin(np.radians(angle))
......@@ -67,6 +69,7 @@ def combineImages(path, nx, ny, nk, width, height, angle):
full = dst
else:
full = cv2.max(full,dst)
cv2.imwrite("full_dunkel.png", full)
......
# -*- coding: utf-8 -*-
"""
GEPARD - Gepard-Enabled PARticle Detection
Copyright (C) 2018 Lars Bittrich and Josef Brandt, Leibniz-Institut für
Polymerforschung Dresden e. V. <bittrich-lars@ipfdd.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program, see COPYING.
If not, see <https://www.gnu.org/licenses/>.
"""
from PyQt5 import QtCore, QtWidgets, QtGui
import cv2
import numpy as np
import os
from helperfunctions import cv2imread_fix
class BackGroundManager(QtWidgets.QWidget):
managerClosed = QtCore.pyqtSignal()
readBackground = QtCore.pyqtSignal(int)
def __init__(self, parentOSwidget):
super(BackGroundManager, self).__init__()
self.setFixedSize(1500, 900)
self.setWindowTitle('Optical Background Manager')
self.parentOSwidget = parentOSwidget
self.parentOSwidget.backGroundSavedToPath.connect(self.updateChildImage)
self.ramanctrl = self.parentOSwidget.ramanctrl
layout = QtWidgets.QHBoxLayout()
self.setLayout(layout)
self.imagesGroup = QtWidgets.QGroupBox('Current Background Images')
self.imagesLayout = QtWidgets.QGridLayout()
self.imgContainers = []
self.avgImg = None
self.presetIndividualImages()
self.previewImage = QtWidgets.QGraphicsView()
self.setupGraphicsView(self.previewImage, scaleFactor=0.8)
previewGroup = QtWidgets.QGroupBox()
previewLayout = QtWidgets.QVBoxLayout()
self.blurspinbox = QtWidgets.QSpinBox(self)
self.blurspinbox.setMinimum(3)
self.blurspinbox.setMaximum(99)
self.blurspinbox.setSingleStep(2)
self.blurspinbox.setValue(5)
self.blurspinbox.valueChanged.connect(self.calculateAverageImage)
self.blurspinbox.setMaximumWidth(150)
self.previewCurrentViewBtn = QtWidgets.QPushButton('Acquire 3x3 area and preview subtracted result')
self.previewCurrentViewBtn.clicked.connect(self.previewStitchedArea)
self.previewArea = QtWidgets.QGraphicsView()
self.setupGraphicsView(self.previewArea, scaleFactor=0.5)
previewLayout.addWidget(QtWidgets.QLabel('Radius for blur'))
previewLayout.addWidget(self.blurspinbox)
previewLayout.addWidget(QtWidgets.QLabel('Preview of averaged and smoothed image'))
previewLayout.addWidget(self.previewImage)
previewLayout.addWidget(self.previewCurrentViewBtn)
previewLayout.addWidget(self.previewArea)
previewGroup.setLayout(previewLayout)
layout.addWidget(self.imagesGroup)
layout.addWidget(previewGroup)
def presetIndividualImages(self, nrows=3, ncols=2):
index = 0
for row in range(nrows):
for col in range(ncols):
self.imgContainers.append(SingleImageContainer(self, index))
self.imagesLayout.addWidget(self.imgContainers[-1], row, col)
index += 1
self.imagesGroup.setLayout(self.imagesLayout)
def previewStitchedArea(self):
if self.avgImg is None:
QtWidgets.QMessageBox.about(self, 'Warning', 'No Background Image is aquired')
return
else:
from opticalscan import loadAndPasteImage
self.dataset = self.parentOSwidget.dataset
#acquire images in 3x3 area to preview quality of background subtraction
x, y, z = self.ramanctrl.getPosition()
micMode = self.parentOSwidget.view.microscopeMode
width, height, angle = self.ramanctrl.getImageDimensions(micMode)
startPoint = [x-width, y-height]
endPoint = [x+width, y+height]
points = np.concatenate(([startPoint], [endPoint]), axis=0)
p0 = [points[:,0].min(), points[:,1].max()]
p1 = [points[:,0].max(), points[:,1].min()]
reply = QtWidgets.QMessageBox.question(self, 'Message',f"The stage will move {round(3*width)} in x and {round(3*height)} in y.\nContinue?",
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No)
if reply == QtWidgets.QMessageBox.Yes:
fullimg = None
zimg = None
for row in range(3):
for col in range(3):
curPoint = [startPoint[0] + row*width, startPoint[1] + col*height]
self.ramanctrl.moveToAbsolutePosition(curPoint[0], curPoint[1])
self.ramanctrl.saveImage(self.dataset.getTmpImageName())
fullimg, zimg = loadAndPasteImage([self.dataset.getTmpImageName()], fullimg, zimg, width, height, angle, p0, p1, curPoint, background=self.avgImg)
self.updateGraphicsView(self.previewArea, fullimg, convertColors=True)
def setupGraphicsView(self, graphView, scaleFactor=1.):
graphView.item = QtWidgets.QGraphicsPixmapItem()
scene = QtWidgets.QGraphicsScene(graphView)
scene.addItem(graphView.item)
graphView.setScene(scene)
graphView.scale(scaleFactor, scaleFactor)
def updateGraphicsView(self, graphView, img, convertColors=False):
if img is not None:
prevImg = img
else:
prevImg = np.zeros((300, 300))
if convertColors:
prevImg = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
height, width = prevImg.shape[:2]
bytesPerLine = 3 * width
pix = QtGui.QPixmap()
pix.convertFromImage(QtGui.QImage(prevImg, width, height, bytesPerLine, QtGui.QImage.Format_RGB888))
graphView.item.setPixmap(pix)
@QtCore.pyqtSlot(int, str)
def updateChildImage(self, index, path):
self.imgContainers[index].updateImage(path)
self.calculateAverageImage()
def calculateAverageImage(self):
curImgs = [i.getImage() for i in self.imgContainers if i.getImage() is not None]
if len(curImgs) > 0:
curImgs = np.array(curImgs)
self.avgImg = np.sum(curImgs, axis=0)/len(curImgs)
radius = self.blurspinbox.value()
if radius %2 == 0:
radius += 1
if radius < 0:
radius = 1
self.avgImg = cv2.GaussianBlur(self.avgImg, (radius, radius), 0)
self.avgImg = np.uint8(self.avgImg)
self.parentOSwidget.writeBackGroundImage(self.avgImg)
else:
self.avgImg = None
self.parentOSwidget.deleteBackGroundImage()
self.updateGraphicsView(self.previewImage, self.avgImg)
def closeEvent(self, event):
self.managerClosed.emit()
event.accept()
class SingleImageContainer(QtWidgets.QGroupBox):
def __init__(self, parent, index):
super(SingleImageContainer, self).__init__()
self.index = index
self.parent = parent
layout = QtWidgets.QVBoxLayout()
layout.addWidget(QtWidgets.QLabel(f'Background {index+1}'))
readBtn = QtWidgets.QPushButton('ReadImage')
readBtn.clicked.connect(self.readImage)
self.image = ImagePixmap()
delBtn = QtWidgets.QPushButton('Delete Image')
delBtn.clicked.connect(self.clearImage)
layout.addWidget(readBtn)
layout.addWidget(self.image)
layout.addWidget(delBtn)
self.setLayout(layout)
def readImage(self):
self.parent.readBackground.emit(self.index)
def updateImage(self, path):
self.image.updateImage(path)
def clearImage(self):
self.image.clearImage()
self.parent.calculateAverageImage()
def getImage(self):
return self.image.imgdata
class ImagePixmap(QtWidgets.QGraphicsView):
def __init__(self):
super(ImagePixmap, self).__init__()
self.item = QtWidgets.QGraphicsPixmapItem()
self.item.setPos(0, 0)
self.item.setAcceptedMouseButtons(QtCore.Qt.NoButton)
self.imgdata = None
scene = QtWidgets.QGraphicsScene(self)
scene.addItem(self.item)
self.setScene(scene)
self.scale(0.4, 0.4)
self.updateImage()
def updateImage(self, img_path=None):
if img_path is None:
self.loadImageIntoPixmap(self.createBlancImage())
elif os.path.exists(img_path):
self.imgdata = cv2.cvtColor(cv2imread_fix(img_path), cv2.COLOR_BGR2RGB)
self.loadImageIntoPixmap(self.imgdata)
def createBlancImage(self):
blancImg = np.zeros((300, 500, 3))
cv2.putText(blancImg, 'None selected', (150, 150), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 255, 255), 2)
return blancImg
def loadImageIntoPixmap(self, img):
height, width = img.shape[:2]
bytesPerLine = 3 * width
pix = QtGui.QPixmap()
pix.convertFromImage(QtGui.QImage(img, width, height, bytesPerLine, QtGui.QImage.Format_RGB888))
self.item.setPixmap(pix)
def clearImage(self):
self.imgdata = None
self.updateImage()
......@@ -30,12 +30,13 @@ from helperfunctions import cv2imread_fix, cv2imwrite_fix
from time import time
import datetime
import sys
from opticalbackground import BackGroundManager
def scan(path, sol, zpositions, grid, controlclass, dataqueue,
stopevent, logpath='', ishdr=False):
if ishdr:
merge_mertens = cv2.createMergeMertens()
fp = None
if logpath != '':
try:
......@@ -81,17 +82,24 @@ def scan(path, sol, zpositions, grid, controlclass, dataqueue,
if fp is not None:
fp.close()
def subtractBackground(image, background):
avg = np.mean(background)
subtracted = np.clip(np.array(image - background + avg, dtype = np.uint8), 0, 255)
return subtracted
def loadAndPasteImage(srcnames, fullimage, fullzval, width, height,
rotationvalue, p0, p1, p, halfResolution = False):
rotationvalue, p0, p1, p, background=None):
colimgs = []
for name in srcnames:
colimgs.append(cv2.cvtColor(cv2imread_fix(name), cv2.COLOR_BGR2RGB))
curImg = cv2imread_fix(name)
if background is not None:
curImg = subtractBackground(curImg, background)
colimgs.append(cv2.cvtColor(curImg, cv2.COLOR_BGR2RGB))
img, zval = imageStacking(colimgs)
if halfResolution: #halve resolution, if fullimage would become too large otherwise
img = cv2.resize(img, None, fx = 0.5, fy = 0.5, interpolation = cv2.INTER_CUBIC)
zval= cv2.resize(zval, None, fx = 0.5, fy = 0.5, interpolation = cv2.INTER_CUBIC)
# if halfResolution: #halve resolution, if fullimage would become too large otherwise
# img = cv2.resize(img, None, fx = 0.5, fy = 0.5, interpolation = cv2.INTER_CUBIC)
# zval= cv2.resize(zval, None, fx = 0.5, fy = 0.5, interpolation = cv2.INTER_CUBIC)
x, y = p
Nx, Ny = int((p1[0]-p0[0]+width)/width*img.shape[1]), int((p0[1]-p1[1]+height)/height*img.shape[0]) + 10 # + 10 because of rotation and hopefully it will be small
......@@ -179,18 +187,20 @@ class PointCoordinates(QtWidgets.QGridLayout):
self.itemAtPosition(i+1,5).setVisible(False)
self.itemAtPosition(i+1,6).setVisible(False)
self.N = N
for i, p in pointsgiven:
wx, wy, wz = self.dswidgets[i]
x, y, z = p
wx.setValue(x)
wy.setValue(y)
wz.setValue(z)
self.validpoints[i] = True
for i in range(len(pointsgiven), N):
wx, wy, wz = self.dswidgets[i]
wx.setValue(0)
wy.setValue(0)
wz.setValue(0)
self.setGivenPoints(pointsgiven, N)
# for i, p in pointsgiven:
# wx, wy, wz = self.dswidgets[i]
# x, y, z = p
# wx.setValue(x)
# wy.setValue(y)
# wz.setValue(z)
# self.validpoints[i] = True
# for i in range(len(pointsgiven), N):
# wx, wy, wz = self.dswidgets[i]
# wx.setValue(0)
# wy.setValue(0)
# wz.setValue(0)
self.update()
......@@ -216,10 +226,26 @@ class PointCoordinates(QtWidgets.QGridLayout):
else:
points[i,:] = np.nan
return points
def setGivenPoints(self, pointsgiven, N):
for i, p in pointsgiven:
wx, wy, wz = self.dswidgets[i]
x, y, z = p
wx.setValue(x)
wy.setValue(y)
wz.setValue(z)
self.validpoints[i] = True
for i in range(len(pointsgiven), N):
wx, wy, wz = self.dswidgets[i]
wx.setValue(0)
wy.setValue(0)
wz.setValue(0)
class OpticalScan(QtWidgets.QWidget):
imageUpdate = QtCore.pyqtSignal(str, name='imageUpdate') #str = 'df' (= darkfield) or 'bf' (=bright field)
boundaryUpdate = QtCore.pyqtSignal()
backGroundSavedToPath = QtCore.pyqtSignal(int, str)
def __init__(self, ramanctrl, dataset, logpath='', parent=None):
super().__init__(parent, QtCore.Qt.Window)
......@@ -235,6 +261,22 @@ class OpticalScan(QtWidgets.QWidget):
pointgroup.setLayout(self.points)
self.points.readPoint.connect(self.takePoint)
bkggroup = QtWidgets.QGroupBox('Manage Background Images')
self.enableBackGround = QtWidgets.QCheckBox('Enable BackgroundSubtraction')
self.enableBackGround.setChecked(False)
self.enableBackGround.stateChanged.connect(self.enableDisableBackground)
self.backGroundManager = BackGroundManager(self)
self.backGroundManager.managerClosed.connect(self.managerWasClosed)
self.backGroundManager.readBackground.connect(self.readBackground)
self.showBgkManagerBtn = QtWidgets.QPushButton('Show Background Manager Window')
self.showBgkManagerBtn.setDisabled(True)
self.showBgkManagerBtn.clicked.connect(self.showHideBackgroundWindow)
bkglayout = QtWidgets.QVBoxLayout()
bkglayout.addWidget(self.enableBackGround)
bkglayout.addWidget(self.showBgkManagerBtn)
bkggroup.setLayout(bkglayout)
self.pareaselect = QtWidgets.QPushButton("Area select", self)
label = QtWidgets.QLabel("Size increase:", self)
self.radiusincreaseedit = QtWidgets.QDoubleSpinBox(self)
......@@ -253,7 +295,7 @@ class OpticalScan(QtWidgets.QWidget):
self.zmaxedit.setMaximumWidth(100)
label3 = QtWidgets.QLabel("Focus steps:", self)
self.nzedit = QtWidgets.QSpinBox(self)
self.nzedit.setRange(2,10)
self.nzedit.setRange(2,20)
self.nzedit.setValue(3)
self.nzedit.setMaximumWidth(100)
self.hdrcheck = QtWidgets.QCheckBox("High dynamic range", self)
......@@ -294,9 +336,9 @@ class OpticalScan(QtWidgets.QWidget):
micModeLayout.addWidget(self.bf_btn)
micModeGroup.setLayout(micModeLayout)
self.halfResChecker = QtWidgets.QCheckBox('Half resolution')
self.halfResChecker.setChecked(False)
self.halfResChecker.setToolTip('Enable for very high resolution images.\nFull resolution slows down the scan too much..')
# self.halfResChecker = QtWidgets.QCheckBox('Half resolution') #TODO: Consider removing, as soon as tiling works
# self.halfResChecker.setChecked(False)
# self.halfResChecker.setToolTip('Enable for very high resolution images.\nFull resolution slows down the scan too much..')
self.deleteImgChecker = QtWidgets.QCheckBox('Delete image files after run')
self.deleteImgChecker.setChecked(True)
......@@ -318,16 +360,16 @@ class OpticalScan(QtWidgets.QWidget):
furtherOptionsLayout.addRow(label3, self.nzedit)
furtherOptionsLayout.addRow(self.hdrcheck)
furtherOptionsLayout.addRow(self.deleteImgChecker)
furtherOptionsLayout.addRow(self.halfResChecker)
# furtherOptionsLayout.addRow(self.halfResChecker) #TODO: Consider removing, as soon as tiling works
furtherOptionsGroup.setLayout(furtherOptionsLayout)
btnLayout = QtWidgets.QHBoxLayout()
btnLayout.addWidget(self.prun)
btnLayout.addWidget(self.pexit)
btnLayout.addStretch()
vbox.addWidget(pointgroup)
vbox.addWidget(bkggroup)
vbox.addWidget(self.areaOptionsGroup)
vbox.addWidget(furtherOptionsGroup)
vbox.addLayout(btnLayout)
......@@ -335,9 +377,27 @@ class OpticalScan(QtWidgets.QWidget):
vbox.addWidget(self.progressbar)
self.setLayout(vbox)
#self.show()
self.setVisible(False)
def enableDisableBackground(self):
self.showBgkManagerBtn.setEnabled(self.enableBackGround.isChecked())
if self.enableBackGround.isChecked():
self.backGroundManager.calculateAverageImage()
else:
self.deleteBackGroundImage()
def showHideBackgroundWindow(self):
if self.backGroundManager.isHidden():
self.backGroundManager.show()
self.showBgkManagerBtn.setText('Hide Background Manager Window')
else:
self.backGroundManager.hide()
self.showBgkManagerBtn.setText('Show Background Manager Window')
def managerWasClosed(self):
self.showBgkManagerBtn.setText('Show Background Manager Window')
@QtCore.pyqtSlot()
def stopScan(self):
if self.process is not None and self.process.is_alive():
......@@ -418,16 +478,14 @@ class OpticalScan(QtWidgets.QWidget):
pshift = self.ramanctrl.getRamanPositionShift()
self.dataset.pshift = pshift
img = cv2.cvtColor(cv2imread_fix(self.dataset.getTmpImageName()), cv2.COLOR_BGR2RGB)
if self.halfResChecker.isChecked():
img = cv2.resize(img, None, fx = 0.5, fy = 0.5, interpolation = cv2.INTER_CUBIC)
# if self.halfResChecker.isChecked():
# img = cv2.resize(img, None, fx = 0.5, fy = 0.5, interpolation = cv2.INTER_CUBIC)
self.dataset.imagedim_bf = self.ramanctrl.getImageDimensions('bf')
self.dataset.pixelscale_bf = self.dataset.imagedim_bf[0]/img.shape[1] #=imagedim_width/shape[1]
self.dataset.imagedim_df = self.ramanctrl.getImageDimensions('df')
self.dataset.pixelscale_df = self.dataset.imagedim_df[0]/img.shape[1] #=imagedim_width/shape[1]
points = self.points.getPoints()
ind = np.isfinite(points[:,0])
self.dataset.fitindices = np.arange(points.shape[0])[ind]
......@@ -457,7 +515,8 @@ class OpticalScan(QtWidgets.QWidget):
full = cv2.warpAffine(full, M, (Nx, Ny)) #fails, if image dimensions are >32767x32767px...
dst = cv2.max(full, dst)
except:
QtWidgets.QMessageBox.critical(self, 'Error', 'Image is too large\nPlease repeat with "scale image" checked.')
QtWidgets.QMessageBox.critical(self, 'Error', 'Image is too large\nSelect smaller region.')
raise
return
self.view.imgdata = dst
......@@ -466,6 +525,19 @@ class OpticalScan(QtWidgets.QWidget):
self.dataset.readin = False
self.imageUpdate.emit(self.view.microscopeMode)
@QtCore.pyqtSlot(int)
def readBackground(self, indexOfCallingImage):
tmp_path = self.dataset.getTmpImageName()
self.ramanctrl.saveImage(tmp_path)
self.backGroundSavedToPath.emit(indexOfCallingImage, tmp_path)
def writeBackGroundImage(self, backgroundImg):
cv2imwrite_fix(self.dataset.getBackgroundImageName(), cv2.cvtColor(backgroundImg, cv2.COLOR_RGB2BGR))
def deleteBackGroundImage(self):
if os.path.exists(self.dataset.getBackgroundImageName()):
os.remove(self.dataset.getBackgroundImageName())
@QtCore.pyqtSlot()
def run(self):
if self.dataset.ramanscansortindex is not None:
......@@ -485,6 +557,14 @@ class OpticalScan(QtWidgets.QWidget):
else:
return
if os.path.exists(self.dataset.getBackgroundImageName()):
reply = QtWidgets.QMessageBox.critical(self, 'Background correction info.',
"A background image was saved. All acquired images will be corrected. Continue?\nOtherwise delete images in background manager",
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.Yes)
if reply != QtWidgets.QMessageBox.Yes:
return
self.view.imparent.ramanSwitch.df_btn.setChecked(self.df_btn.isChecked())
self.view.imparent.ramanSwitch.setDisabled(True)
self.view.setMicroscopeMode()
......@@ -544,11 +624,6 @@ class OpticalScan(QtWidgets.QWidget):
QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No)
if reply == QtWidgets.QMessageBox.Yes:
# if self.halfResChecker.isChecked():
# #reset pixelscales!!!
# self.dataset.pixelscale_df /= 2
# self.dataset.pixelscale_bf /= 2
self.prun.setEnabled(False)
self.ramanctrl.disconnect()
self.processstopevent = Event()
......@@ -593,8 +668,15 @@ class OpticalScan(QtWidgets.QWidget):
width, height, rotationvalue = (self.dataset.imagedim_df if self.view.imparent.ramanSwitch.df_btn.isChecked() else self.dataset.imagedim_bf)
p = self.dataset.grid[i]
p0, p1 = self.dataset.maxdim[:2], self.dataset.maxdim[2:]
if os.path.exists(self.dataset.getBackgroundImageName()):
background_img = cv2imread_fix(self.dataset.getBackgroundImageName())
else:
background_img = None
self.view.imgdata, self.dataset.zvalimg = loadAndPasteImage(names, self.view.imgdata, self.dataset.zvalimg, width, height,
rotationvalue, p0, p1, p, halfResolution = self.halfResChecker.isChecked())
rotationvalue, p0, p1, p, background=background_img)
self.progressbar.setValue(i+1)
if i>3:
timerunning = time()-self.starttime
......@@ -627,6 +709,10 @@ class OpticalScan(QtWidgets.QWidget):
self.close()
return
self.timer.start(100.)
def closeEvent(self, event):
self.backGroundManager.close()
event.accept()
if __name__ == "__main__":
from ramancom.simulatedraman import SimulatedRaman
......
......@@ -47,6 +47,7 @@ class WITecCOM(RamanBase):
def __init__(self, hostname=None):
super().__init__()
self.name = 'WITecCOM'
if hostname is None:
hostname = gethostname()
self.IBUCSAccess = win32com.client.DispatchEx(self.CLSID, machine=hostname,
......@@ -210,9 +211,22 @@ class WITecCOM(RamanBase):
# move only if new position is really different; repeat if new position is ignored (happens some times)
while max(abs(initpos[0]-x), abs(initpos[1]-y))>epsxy:
t0 = time()
self.PosXFloatMan.SetValue(x)
self.PosYFloatMan.SetValue(y)
self.GoToTrigger.OperateTrigger()
numFails = 0
maxFails = 50
positionSubmitted = False
while numFails < maxFails and not positionSubmitted:
try:
self.PosXFloatMan.SetValue(x)
self.PosYFloatMan.SetValue(y)
self.GoToTrigger.OperateTrigger()
positionSubmitted = True
except pythoncom.com_error:
numFails += 1
sleep(.1)
if numFails > 0:
print(f'{numFails} of max. {maxFails} unsuccessfull position submits to Position: {x}, {y}', flush=True)
if not positionSubmitted:
print(f'Error setting Position: {x}, {y}\nExpecting \"signal ignored\" warning', flush=True)
# wait till position is found within accuracy of epsxy; check if position changes at all
distance = 2*epsxy
......@@ -296,7 +310,6 @@ class WITecCOM(RamanBase):
print("Waiting for measurement ready...")
t1 = time()
def triggerMeasurement(self, num):
assert self.timeseries
self.TimeSeriesSlowNextMan.OperateTrigger()
......
......@@ -21,6 +21,7 @@ If not, see <https://www.gnu.org/licenses/>.
class RamanBase(object):
def __init__(self):
self.nme = None
self.connected = False
self.timeseries = False
......
......@@ -32,6 +32,7 @@ class SimulatedRaman(RamanBase):
ramanParameters = {}
def __init__(self):
super().__init__()
self.name = 'SimulatedRaman'
self.currentpos = None, 0., 0.
self.currentZ = 0.
# some plausible data to simulate consecutively changing positions
......
......@@ -268,7 +268,8 @@ class RamanScanUI(QtWidgets.QWidget):
if i>=0:
self.progressbar.setValue(i+1)
self.view.highLightRamanIndex(i+1)
self.view.highLightRamanIndex(i+1) #go to next scanmarker
# self.view.centerOnRamanIndex(i+1)
Npoints = len(self.dataset.ramanpoints)
if i>3:
timerunning = time()-self.starttime
......
......@@ -169,9 +169,9 @@ class SampleView(QtWidgets.QGraphicsView):
return
assert mode in ["OpticalScan", "ParticleDetection", "RamanScan", "ParticleAnalysis"]
self.oscanwidget.setVisible(False)
if self.detectionwidget is not None:
self.detectionwidget.close()
self.detectionwidget.destroy()
# if self.detectionwidget is not None:
# self.detectionwidget.close()
# self.detectionwidget.destroy()
self.ramanwidget.setVisible(False)
self.contouritem.resetContours([])
self.mode = mode
......
......@@ -45,22 +45,25 @@ class Segmentation(object):
def __init__(self, dataset=None, parent=None):
self.cancelcomputation = False