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

Added the following features:
In optical scan: BackgroundManager for subtraction of background images
In segmentation: CLAHE and multiple thresholding
parent 8fc15b1e
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -347,6 +347,9 @@ class DataSet(object):
    def getLegacyDetectImageName(self):
    def getLegacyDetectImageName(self):
        return os.path.join(self.path, "detectimage.png")
        return os.path.join(self.path, "detectimage.png")
    
    
    def getBackgroundImageName(self):
        return os.path.join(self.path, "background.bmp")
    
    def getDetectImageName(self):
    def getDetectImageName(self):
        raise NotImplementedError("No longer implemented due to change in API")
        raise NotImplementedError("No longer implemented due to change in API")
    
    
+15 −4
Original line number Original line Diff line number Diff line
@@ -101,12 +101,23 @@ class MeasureParticleWindow(QtWidgets.QMainWindow):
            fileName = QtWidgets.QFileDialog.getSaveFileName(self, "Create New Project",
            fileName = QtWidgets.QFileDialog.getSaveFileName(self, "Create New Project",
                                        defaultPath, "*.pkl")[0]
                                        defaultPath, "*.pkl")[0]
        if fileName:
        if fileName:
            if fileName.find(' ') < 0:
            isValid, msg = self.testFilename(fileName)
            if isValid:
                self.fname = str(fileName)
                self.fname = str(fileName)
                self.view.new(self.fname)  
                self.view.new(self.fname)  
                self.scalingChanged(1.)
                self.scalingChanged(1.)
            else:
            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() 
    @QtCore.pyqtSlot() 
    def about(self):
    def about(self):
+9 −6
Original line number Original line Diff line number Diff line
@@ -48,15 +48,17 @@ def imageStacking(colimgs):
    return im, zval
    return im, zval


def combineImages(path, nx, ny, nk, width, height, angle):
def combineImages(path, nx, ny, nk, width, height, angle):
    imgs = []
    full = None
    full = None
    for i in range(nx):
    for i in range(nx):
        for j in range(ny):
        for j in range(ny):
            if nk > 1:
                colimgs = []
                colimgs = []
                for k in range(nk):
                for k in range(nk):
                    colimgs.append(cv2.imread(path + f'test_{i}_{j}_{k}.bmp'))
                    colimgs.append(cv2.imread(path + f'test_{i}_{j}_{k}.bmp'))
                img = imageStacking(colimgs)
                img = imageStacking(colimgs)
            imgs.append(img)
            else:
                img = cv2.imread(path + f'test_{i}_{j}_1.bmp')

            dx = i*.9*img.shape[1]
            dx = i*.9*img.shape[1]
            dy = j*.8*img.shape[0]
            dy = j*.8*img.shape[0]
            c, s = np.cos(np.radians(angle)), np.sin(np.radians(angle))
            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
                full = dst
            else:
            else:
                full = cv2.max(full,dst)
                full = cv2.max(full,dst)

    cv2.imwrite("full_dunkel.png", full)
    cv2.imwrite("full_dunkel.png", full)
    
    
    
    

opticalbackground.py

0 → 100644
+251 −0
Original line number Original line Diff line number Diff line
# -*- 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()
+122 −36
Original line number Original line Diff line number Diff line
@@ -30,6 +30,7 @@ from helperfunctions import cv2imread_fix, cv2imwrite_fix
from time import time
from time import time
import datetime
import datetime
import sys
import sys
from opticalbackground import BackGroundManager


def scan(path, sol, zpositions, grid, controlclass, dataqueue, 
def scan(path, sol, zpositions, grid, controlclass, dataqueue, 
         stopevent, logpath='', ishdr=False):
         stopevent, logpath='', ishdr=False):
@@ -81,17 +82,24 @@ def scan(path, sol, zpositions, grid, controlclass, dataqueue,
    if fp is not None:
    if fp is not None:
        fp.close()
        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, 
def loadAndPasteImage(srcnames, fullimage, fullzval, width, height, 
                      rotationvalue, p0, p1, p, halfResolution = False):
                      rotationvalue, p0, p1, p, background=None):
    colimgs = []
    colimgs = []
    for name in srcnames:
    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)
    img, zval = imageStacking(colimgs)


    if halfResolution:              #halve resolution, if fullimage would become too large otherwise
#    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)
#        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)
#        zval= cv2.resize(zval, None, fx = 0.5, fy = 0.5, interpolation = cv2.INTER_CUBIC)


    x, y = p
    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
    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,5).setVisible(False)
            self.itemAtPosition(i+1,6).setVisible(False)
            self.itemAtPosition(i+1,6).setVisible(False)
        self.N = N
        self.N = N
        for i, p in pointsgiven:
        
            wx, wy, wz = self.dswidgets[i]
        self.setGivenPoints(pointsgiven, N)
            x, y, z = p
#        for i, p in pointsgiven:
            wx.setValue(x)
#            wx, wy, wz = self.dswidgets[i]
            wy.setValue(y)        
#            x, y, z = p
            wz.setValue(z)
#            wx.setValue(x)
            self.validpoints[i] = True
#            wy.setValue(y)        
        for i in range(len(pointsgiven), N):
#            wz.setValue(z)
            wx, wy, wz = self.dswidgets[i]
#            self.validpoints[i] = True
            wx.setValue(0)
#        for i in range(len(pointsgiven), N):
            wy.setValue(0)        
#            wx, wy, wz = self.dswidgets[i]
            wz.setValue(0)
#            wx.setValue(0)
#            wy.setValue(0)        
#            wz.setValue(0)
        
        
        self.update()
        self.update()
        
        
@@ -217,9 +227,25 @@ class PointCoordinates(QtWidgets.QGridLayout):
                points[i,:] = np.nan
                points[i,:] = np.nan
        return points
        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):
class OpticalScan(QtWidgets.QWidget):
    imageUpdate = QtCore.pyqtSignal(str, name='imageUpdate')    #str = 'df' (= darkfield) or 'bf' (=bright field)
    imageUpdate = QtCore.pyqtSignal(str, name='imageUpdate')    #str = 'df' (= darkfield) or 'bf' (=bright field)
    boundaryUpdate = QtCore.pyqtSignal()
    boundaryUpdate = QtCore.pyqtSignal()
    backGroundSavedToPath = QtCore.pyqtSignal(int, str)
    
    
    def __init__(self, ramanctrl, dataset, logpath='', parent=None):
    def __init__(self, ramanctrl, dataset, logpath='', parent=None):
        super().__init__(parent, QtCore.Qt.Window)
        super().__init__(parent, QtCore.Qt.Window)
@@ -235,6 +261,22 @@ class OpticalScan(QtWidgets.QWidget):
        pointgroup.setLayout(self.points)
        pointgroup.setLayout(self.points)
        self.points.readPoint.connect(self.takePoint)
        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)
        self.pareaselect = QtWidgets.QPushButton("Area select", self)
        label = QtWidgets.QLabel("Size increase:", self)
        label = QtWidgets.QLabel("Size increase:", self)
        self.radiusincreaseedit = QtWidgets.QDoubleSpinBox(self)
        self.radiusincreaseedit = QtWidgets.QDoubleSpinBox(self)
@@ -253,7 +295,7 @@ class OpticalScan(QtWidgets.QWidget):
        self.zmaxedit.setMaximumWidth(100)
        self.zmaxedit.setMaximumWidth(100)
        label3 = QtWidgets.QLabel("Focus steps:", self)
        label3 = QtWidgets.QLabel("Focus steps:", self)
        self.nzedit = QtWidgets.QSpinBox(self)
        self.nzedit = QtWidgets.QSpinBox(self)
        self.nzedit.setRange(2,10)
        self.nzedit.setRange(2,20)
        self.nzedit.setValue(3)
        self.nzedit.setValue(3)
        self.nzedit.setMaximumWidth(100)
        self.nzedit.setMaximumWidth(100)
        self.hdrcheck = QtWidgets.QCheckBox("High dynamic range", self)
        self.hdrcheck = QtWidgets.QCheckBox("High dynamic range", self)
@@ -294,9 +336,9 @@ class OpticalScan(QtWidgets.QWidget):
        micModeLayout.addWidget(self.bf_btn)
        micModeLayout.addWidget(self.bf_btn)
        micModeGroup.setLayout(micModeLayout)
        micModeGroup.setLayout(micModeLayout)
        
        
        self.halfResChecker = QtWidgets.QCheckBox('Half resolution')
#        self.halfResChecker = QtWidgets.QCheckBox('Half resolution')  #TODO: Consider removing, as soon as tiling works
        self.halfResChecker.setChecked(False)
#        self.halfResChecker.setChecked(False)
        self.halfResChecker.setToolTip('Enable for very high resolution images.\nFull resolution slows down the scan too much..')
#        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 = QtWidgets.QCheckBox('Delete image files after run')
        self.deleteImgChecker.setChecked(True)
        self.deleteImgChecker.setChecked(True)
@@ -318,16 +360,16 @@ class OpticalScan(QtWidgets.QWidget):
        furtherOptionsLayout.addRow(label3, self.nzedit)
        furtherOptionsLayout.addRow(label3, self.nzedit)
        furtherOptionsLayout.addRow(self.hdrcheck)
        furtherOptionsLayout.addRow(self.hdrcheck)
        furtherOptionsLayout.addRow(self.deleteImgChecker)
        furtherOptionsLayout.addRow(self.deleteImgChecker)
        furtherOptionsLayout.addRow(self.halfResChecker)
#        furtherOptionsLayout.addRow(self.halfResChecker)    #TODO: Consider removing, as soon as tiling works
        furtherOptionsGroup.setLayout(furtherOptionsLayout)
        furtherOptionsGroup.setLayout(furtherOptionsLayout)
        
        
        
        btnLayout = QtWidgets.QHBoxLayout()
        btnLayout = QtWidgets.QHBoxLayout()
        btnLayout.addWidget(self.prun)
        btnLayout.addWidget(self.prun)
        btnLayout.addWidget(self.pexit)
        btnLayout.addWidget(self.pexit)
        btnLayout.addStretch()
        btnLayout.addStretch()
        
        
        vbox.addWidget(pointgroup)
        vbox.addWidget(pointgroup)
        vbox.addWidget(bkggroup)
        vbox.addWidget(self.areaOptionsGroup)
        vbox.addWidget(self.areaOptionsGroup)
        vbox.addWidget(furtherOptionsGroup)
        vbox.addWidget(furtherOptionsGroup)
        vbox.addLayout(btnLayout)
        vbox.addLayout(btnLayout)
@@ -335,9 +377,27 @@ class OpticalScan(QtWidgets.QWidget):
        vbox.addWidget(self.progressbar)
        vbox.addWidget(self.progressbar)
        
        
        self.setLayout(vbox)
        self.setLayout(vbox)
        #self.show()
        self.setVisible(False)
        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()
    @QtCore.pyqtSlot()
    def stopScan(self):
    def stopScan(self):
        if self.process is not None and self.process.is_alive():
        if self.process is not None and self.process.is_alive():
@@ -418,16 +478,14 @@ class OpticalScan(QtWidgets.QWidget):
        pshift = self.ramanctrl.getRamanPositionShift()
        pshift = self.ramanctrl.getRamanPositionShift()
        self.dataset.pshift = pshift
        self.dataset.pshift = pshift
        img = cv2.cvtColor(cv2imread_fix(self.dataset.getTmpImageName()), cv2.COLOR_BGR2RGB)
        img = cv2.cvtColor(cv2imread_fix(self.dataset.getTmpImageName()), cv2.COLOR_BGR2RGB)
        if self.halfResChecker.isChecked():
#        if self.halfResChecker.isChecked():
            img = cv2.resize(img, None, fx = 0.5, fy = 0.5, interpolation = cv2.INTER_CUBIC)
#            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.imagedim_bf = self.ramanctrl.getImageDimensions('bf')
        self.dataset.pixelscale_bf = self.dataset.imagedim_bf[0]/img.shape[1]          #=imagedim_width/shape[1]
        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.imagedim_df = self.ramanctrl.getImageDimensions('df')
        self.dataset.pixelscale_df = self.dataset.imagedim_df[0]/img.shape[1]          #=imagedim_width/shape[1]
        self.dataset.pixelscale_df = self.dataset.imagedim_df[0]/img.shape[1]          #=imagedim_width/shape[1]
        
        

        
        points = self.points.getPoints()
        points = self.points.getPoints()
        ind = np.isfinite(points[:,0])
        ind = np.isfinite(points[:,0])
        self.dataset.fitindices = np.arange(points.shape[0])[ind]
        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...
                full = cv2.warpAffine(full, M, (Nx, Ny))            #fails, if image dimensions are >32767x32767px...
                dst = cv2.max(full, dst)
                dst = cv2.max(full, dst)
            except:
            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
                return
        
        
        self.view.imgdata = dst
        self.view.imgdata = dst
@@ -466,6 +525,19 @@ class OpticalScan(QtWidgets.QWidget):
        self.dataset.readin = False
        self.dataset.readin = False
        self.imageUpdate.emit(self.view.microscopeMode)
        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() 
    @QtCore.pyqtSlot() 
    def run(self):
    def run(self):
        if self.dataset.ramanscansortindex is not None:
        if self.dataset.ramanscansortindex is not None:
@@ -485,6 +557,14 @@ class OpticalScan(QtWidgets.QWidget):
            else:
            else:
                return
                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.df_btn.setChecked(self.df_btn.isChecked())
        self.view.imparent.ramanSwitch.setDisabled(True)
        self.view.imparent.ramanSwitch.setDisabled(True)
        self.view.setMicroscopeMode()
        self.view.setMicroscopeMode()
@@ -544,11 +624,6 @@ class OpticalScan(QtWidgets.QWidget):
            QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No)
            QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No)


        if reply == QtWidgets.QMessageBox.Yes:
        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.prun.setEnabled(False)
            self.ramanctrl.disconnect()
            self.ramanctrl.disconnect()
            self.processstopevent = Event()
            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)
            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]
            p = self.dataset.grid[i]
            p0, p1 = self.dataset.maxdim[:2], self.dataset.maxdim[2:]
            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, 
            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)
            self.progressbar.setValue(i+1)
            if i>3:
            if i>3:
                timerunning = time()-self.starttime
                timerunning = time()-self.starttime
@@ -628,6 +710,10 @@ class OpticalScan(QtWidgets.QWidget):
                return
                return
        self.timer.start(100.)
        self.timer.start(100.)
        
        
    def closeEvent(self, event):
        self.backGroundManager.close()
        event.accept()
            
if __name__ == "__main__":
if __name__ == "__main__":
    from ramancom.simulatedraman import SimulatedRaman
    from ramancom.simulatedraman import SimulatedRaman
    from dataset import DataSet
    from dataset import DataSet
Loading