예제 #1
0
class FlipRotateMixin(base.BaseTransformMixin):
    """Rotate & Crop mixin class, to be mixed with a class providing the 
    get_plot method, like ImageDialog or FlipRotateWidget (see below)"""
    ROTATION_ANGLES = [str((i-1)*90) for i in range(4)]

    #------BaseTransformMixin API----------------------------------------------
    def add_buttons_to_layout(self, layout):
        """Add tool buttons to layout"""
         # Image orientation
        angle_label = QLabel(_("Angle (°):"))
        layout.addWidget(angle_label)
        self.angle_combo = QComboBox(self)
        self.angle_combo.addItems(self.ROTATION_ANGLES)
        self.angle_combo.setCurrentIndex(1)
        self.angle_combo.currentIndexChanged.connect(
                                 lambda index: self.apply_transformation())
        layout.addWidget(self.angle_combo)
        layout.addSpacing(10)
        
        # Image flipping
        flip_label = QLabel(_("Flip:"))
        layout.addWidget(flip_label)
        hflip = create_toolbutton(self, text="", icon=get_icon("hflip.png"),
                          toggled=lambda state: self.apply_transformation(),
                          autoraise=False)
        self.hflip_btn = hflip
        layout.addWidget(hflip)
        vflip = create_toolbutton(self, text="", icon=get_icon("vflip.png"),
                          toggled=lambda state: self.apply_transformation(),
                          autoraise=False)
        self.vflip_btn = vflip
        layout.addWidget(vflip)
        layout.addSpacing(15)
        
        self.add_reset_button(layout)
    
    def reset_transformation(self):
        """Reset transformation"""
        self.angle_combo.setCurrentIndex(1)
        self.hflip_btn.setChecked(False)
        self.vflip_btn.setChecked(False)

    def apply_transformation(self):
        """Apply transformation, e.g. crop or rotate"""
        angle, hflip, vflip = self.get_parameters()
        x, y, _a, px, py, _hf, _vf = self.item.get_transform()
        self.item.set_transform(x, y, angle*np.pi/180, px, py, hflip, vflip)
        self.get_plot().replot()
    
    def compute_transformation(self):
        """Compute transformation, return compute output array"""
        angle, hflip, vflip = self.get_parameters()
        data = self.item.data.copy()
        if hflip:
            data = np.fliplr(data)
        if vflip:
            data = np.flipud(data)
        if angle:
            k = int( (-angle % 360)/90 )
            data = np.rot90(data, k)
        return data
    
    #------Public API----------------------------------------------------------
    def get_parameters(self):
        """Return transform parameters"""
        angle = int(str(self.angle_combo.currentText()))
        hflip = self.hflip_btn.isChecked()
        vflip = self.vflip_btn.isChecked()
        return angle, hflip, vflip

    def set_parameters(self, angle, hflip, vflip):
        """Set transform parameters"""
        angle_index = self.ROTATION_ANGLES.index(str(angle))
        self.angle_combo.setCurrentIndex(angle_index)
        self.hflip_btn.setChecked(hflip)
        self.vflip_btn.setChecked(vflip)
예제 #2
0
class GreatEyesUi(QSplitter):
    '''
    Handling user interface to manage greateys cameras
    '''
    newPlotData = Signal(object, object)
    message = Signal(object)
    def __init__(self, parent):
        super().__init__(parent)

        self.camera = None
        self.cameraSettings = None
        self.aquireData = False
        self.directory = 'N:/4all/mpsd_drive/xtsfasta/Data'

        layoutWidget = QWidget()
        layout = QGridLayout()
        layoutWidget.setLayout(layout)

        ###############
        # GUI elements
        self.openCamBtn = QPushButton('Connect camera')
        self.startAquBtn = QPushButton('Start aquisiton')
        self.readoutSpeedCombo = QComboBox()
        # this really should not be hard coded but received from dll
        self.readoutSpeedCombo.addItems(["1 MHz", 
            "1.8 MHz",
            "2.3 MHz",
            "2.8 MHz",
            "250 kHz",
            "500 kHz"])
        self.exposureTimeSpin = QSpinBox()
        self.exposureTimeSpin.setRange(1, 1e6)
        self.exposureTimeSpin.setValue(1e3) # default exposure 1s
        self.exposureTimeSpin.setSingleStep(100)
        self.exposureTimeSpin.setSuffix(' ms')
        #self.exposureTimeSpin.setValidator(QIntValidator(1, 2**31)) # ms
        self.binningXCombo = QComboBox()
        self.binningXCombo.addItems(["No binning",
                  "Binning of 2 columns",
                  "Binning of 4 columns",
                  "Binning of 8 columns",
                  "Binning of 16 columns",
                  "Binning of 32 columns",
                  "Binning of 64 columns",
                  "Binning of 128 columns",
                  "Full horizontal binning"])
        self.binningYCombo = QComboBox()
        self.binningYCombo.addItems(["No binning",
                  "Binning of 2 lines",
                  "Binning of 4 lines",
                  "Binning of 8 lines",
                  "Binning of 16 lines",
                  "Binning of 32 lines",
                  "Binning of 64 lines",
                  "Binning of 128 lines",
                  "Binning of 256 lines"])
        self.temperatureSpin = QSpinBox()
        self.temperatureSpin.setRange(-100, 20)
        self.temperatureSpin.setValue(-10)
        self.temperatureSpin.setSuffix('°C')
        self.updateInterSpin = QSpinBox()
        self.updateInterSpin.setRange(1, 3600)
        self.updateInterSpin.setValue(5)
        self.updateInterSpin.setSuffix(' s')
        #self.updateInterSpin.setText("2")
        #self.updateInterEdit.setValidator(QIntValidator(1, 3600))
        self.loi = QSpinBox()
        self.loi.setRange(1, 511) # one pixel less as the camera has
        self.deltaPixels = QSpinBox()
        self.deltaPixels.setRange(0, 256)
        self.autoSave = QCheckBox("Auto save")
        self.getDirectory = QPushButton('Choose Dir')
        self.dirPath = QLineEdit(self.directory)
        self.comment = QPlainTextEdit()

        ##############
        # put elements in layout
        layout.addWidget(self.openCamBtn, 0, 0)
        layout.addWidget(self.startAquBtn, 0, 1)
        layout.addWidget(QLabel('readout speed'), 1, 0)
        layout.addWidget(self.readoutSpeedCombo, 1, 1)
        layout.addWidget(QLabel('exposure time'), 2, 0)
        layout.addWidget(self.exposureTimeSpin, 2, 1)
        layout.addWidget(QLabel('binning X'), 3, 0)
        layout.addWidget(self.binningXCombo, 3, 1)
        layout.addWidget(QLabel('binning Y'), 4, 0)
        layout.addWidget(self.binningYCombo, 4, 1)
        layout.addWidget(QLabel('temperature'), 5, 0)
        layout.addWidget(self.temperatureSpin, 5, 1)
        layout.addWidget(QLabel('update every n-seconds'), 6, 0)
        layout.addWidget(self.updateInterSpin, 6, 1)
        layout.addWidget(QLabel('Pixel of interest'), 7, 0)
        layout.addWidget(self.loi, 7, 1)
        layout.addWidget(QLabel('Δ pixels'), 8, 0)
        layout.addWidget(self.deltaPixels, 8, 1)
        layout.addWidget(self.autoSave, 9, 1)
        layout.addWidget(self.getDirectory, 10, 0)
        layout.addWidget(self.dirPath, 10, 1)
        layout.addWidget(QLabel('Comment:'), 11, 0)
        layout.addWidget(self.comment, 12, 0, 1, 2)
        layout.setRowStretch(13, 10)

        self.addWidget(layoutWidget)


        #################
        # connect elements for functionality
        self.openCamBtn.released.connect(self.__openCam)
        self.getDirectory.released.connect(self.__chooseDir)
        self.temperatureSpin.valueChanged.connect(self.__setTemperature)
        self.exposureTimeSpin.valueChanged.connect(self.__setCamParameter)
        self.readoutSpeedCombo.currentIndexChanged.connect(self.__setCamParameter)
        self.startAquBtn.released.connect(self.__startCurrImageThr)
        
        ################
        # thread for updating position
        self.currImage_thread = QThread() # create the QThread
        self.currImage_thread.start()

        # This causes my_worker.run() to eventually execute in my_thread:
        self.currImage_worker = GenericWorker(self.__getCurrImage)
        self.currImage_worker.moveToThread(self.currImage_thread)
 
        self.startAquBtn.setEnabled(False) 
        self.readoutSpeedCombo.setEnabled(False)
        self.exposureTimeSpin.setEnabled(False)
        self.binningXCombo.setEnabled(False)
        self.binningYCombo.setEnabled(False)
        self.temperatureSpin.setEnabled(False)
        self.updateInterSpin.setEnabled(False)
      


    def __openCam(self):
        self.camera = greatEyes()
        if not self.camera.connected:
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Critical)
            msg.setText('Sorry, could not connect to camera :(\n' + 
                    self.camera.status)
            msg.exec_()
            return
        self.openCamBtn.setText('Connected')
        self.message.emit('Camera connected')
        self.openCamBtn.setStyleSheet('QPushButton {color: green;}')

        self.readoutSpeedCombo.setEnabled(True)
        self.exposureTimeSpin.setEnabled(True)
        self.binningXCombo.setEnabled(False)
        self.binningYCombo.setEnabled(False)
        self.temperatureSpin.setEnabled(True)
        self.updateInterSpin.setEnabled(True)

        self.openCamBtn.setEnabled(False)
        self.startAquBtn.setEnabled(True) 

    def __chooseDir(self):
        self.directory = QFileDialog.getExistingDirectory(self,
                "Choose directory",
                self.directory)
        self.dirPath.setText(self.directory)


    def __startCurrImageThr(self):
        if not self.aquireData:
            self.aquireData = True
            self.currImage_worker.start.emit()
            self.startAquBtn.setText('Stop aquisition')
            self.message.emit('Starting aqusition')
        else:
            self.__stopCurrImageThr()
            self.startAquBtn.setText('Start aquisition')
            self.message.emit('Stopping aqusition')
    def __stopCurrImageThr(self):
        self.aquireData = False
        #while(self.currPosThr.isRunning()):
        #    time.sleep(0.03)
    def __getCurrImage(self):
        #from scipy import mgrid
        #import numpy as np
        #X, Y = mgrid[-256:256, -1024:1025]
        i = self.updateInterSpin.value()
        while self.aquireData:
            # seconds over which to record a new image
            imageIntervall = self.updateInterSpin.value()
            # sleep for n seconds to check if intervall was changed
            sleepy = 1
            if i >= imageIntervall:
                # dummy image
                #z = np.exp(-0.5*(X**2+Y**2)/np.random.uniform(30000, 40000))*np.cos(0.1*X+0.1*Y)
                z = self.camera.getImage()
                timeStamp = datetime.datetime.now()
                self.cameraSettings = {
                        'temperature': self.camera.getTemperature(),
                        'exposure_time': self.exposureTimeSpin.value(),
                        'readout_speed': self.readoutSpeedCombo.currentText()
                        'time_stamp': timeStamp}
                self.newPlotData.emit(z, timeStamp)
                i = 0 # restart counter
            i += sleepy
            time.sleep(sleepy)

    def __setTemperature(self, temp):
        self.camera.setTemperture(temp)
        self.message.emit('Temperature set to {:d}°C'.format(temp))

    def __setCamParameter(self, param):
        self.camera.setCameraParameter(
                self.readoutSpeedCombo.currentIndex(), 
                self.exposureTimeSpin.value(), 
                0, 0)
        self.message.emit('Readout: {:s}, Exposure: {:d}, binningX: 0, binningY: 0'.format(self.readoutSpeedCombo.currentText(),
               self.exposureTimeSpin.value()))
예제 #3
0
파일: fliprotate.py 프로젝트: gyenney/Tools
class FlipRotateMixin(base.BaseTransformMixin):
    """Rotate & Crop mixin class, to be mixed with a class providing the 
    get_plot method, like ImageDialog or FlipRotateWidget (see below)"""
    ROTATION_ANGLES = [str((i - 1) * 90) for i in range(4)]

    #------BaseTransformMixin API----------------------------------------------
    def add_buttons_to_layout(self, layout):
        """Add tool buttons to layout"""
        # Image orientation
        angle_label = QLabel(_("Angle (°):"))
        layout.addWidget(angle_label)
        self.angle_combo = QComboBox(self)
        self.angle_combo.addItems(self.ROTATION_ANGLES)
        self.angle_combo.setCurrentIndex(1)
        self.angle_combo.currentIndexChanged.connect(
            lambda index: self.apply_transformation())
        layout.addWidget(self.angle_combo)
        layout.addSpacing(10)

        # Image flipping
        flip_label = QLabel(_("Flip:"))
        layout.addWidget(flip_label)
        hflip = create_toolbutton(
            self,
            text="",
            icon=get_icon("hflip.png"),
            toggled=lambda state: self.apply_transformation(),
            autoraise=False)
        self.hflip_btn = hflip
        layout.addWidget(hflip)
        vflip = create_toolbutton(
            self,
            text="",
            icon=get_icon("vflip.png"),
            toggled=lambda state: self.apply_transformation(),
            autoraise=False)
        self.vflip_btn = vflip
        layout.addWidget(vflip)
        layout.addSpacing(15)

        self.add_reset_button(layout)

    def reset_transformation(self):
        """Reset transformation"""
        self.angle_combo.setCurrentIndex(1)
        self.hflip_btn.setChecked(False)
        self.vflip_btn.setChecked(False)

    def apply_transformation(self):
        """Apply transformation, e.g. crop or rotate"""
        angle, hflip, vflip = self.get_parameters()
        x, y, _a, px, py, _hf, _vf = self.item.get_transform()
        self.item.set_transform(x, y, angle * np.pi / 180, px, py, hflip,
                                vflip)
        self.get_plot().replot()

    def compute_transformation(self):
        """Compute transformation, return compute output array"""
        angle, hflip, vflip = self.get_parameters()
        data = self.item.data.copy()
        if hflip:
            data = np.fliplr(data)
        if vflip:
            data = np.flipud(data)
        if angle:
            k = int((-angle % 360) / 90)
            data = np.rot90(data, k)
        return data

    #------Public API----------------------------------------------------------
    def get_parameters(self):
        """Return transform parameters"""
        angle = int(str(self.angle_combo.currentText()))
        hflip = self.hflip_btn.isChecked()
        vflip = self.vflip_btn.isChecked()
        return angle, hflip, vflip

    def set_parameters(self, angle, hflip, vflip):
        """Set transform parameters"""
        angle_index = self.ROTATION_ANGLES.index(str(angle))
        self.angle_combo.setCurrentIndex(angle_index)
        self.hflip_btn.setChecked(hflip)
        self.vflip_btn.setChecked(vflip)
예제 #4
0
파일: widgets.py 프로젝트: HaMF/bbfmr
class OperationsWidget(QWidget):
    operations_changed = QtCore.pyqtSignal()
    operation_changed = QtCore.pyqtSignal(dict, int)
    operation_added = QtCore.pyqtSignal(dict, int)

    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        self.widget_layout = QVBoxLayout()

        title_layout = QHBoxLayout()
        title_layout.addStretch()
        style = "<span style=\'color: #444444\'><b>%s</b></span>"
        title = QLabel(style % "Operations")
        title_layout.addWidget(title)
        title_layout.addStretch()
        self.widget_layout.addLayout(title_layout)

        # Create ListWidget and add 10 items to move around.
        self.list_widget = QListWidget()

        # self.list_widget.setDragDropMode(QAbstractItemView.InternalMove)
        self.list_widget.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.list_widget.setSortingEnabled(False)
        self.list_widget.currentItemChanged.connect(self._populate_settings_update)
        self.widget_layout.addWidget(self.list_widget)

        otitle_layout = QHBoxLayout()
        otitle_layout.addStretch()
        otitle = QLabel(style % "Operation settings")
        otitle_layout.addWidget(otitle)
        otitle_layout.addStretch()
        self.widget_layout.addLayout(otitle_layout)

        self.operations_combo = QComboBox()
        self.operations_combo.currentIndexChanged.connect(self._populate_settings_add)
        self.widget_layout.addWidget(self.operations_combo)

        self.operation_settings = GenericOperationWidget()
        self.widget_layout.addWidget(self.operation_settings)

        self.toolbar = QToolBar()
        self.toolbar.addAction(get_icon('apply.png'), "Apply/Replace",
                               self._change_operation)
        self.toolbar.addAction(get_icon('editors/edit_add.png'), "Add after",
                               self._add_operation)
        self.toolbar.addAction(get_icon('trash.png'), "Remove",
                               self._remove_operation)


        self.widget_layout.addWidget(self.toolbar)
        self.setLayout(self.widget_layout)

    def populate_available_operations(self, dict):
        """
        Populate combobox with available operation names
        """
        self.operations_combo.addItems(dict)

    def set_operations(self, operations_dict):
        """
        Populate operations list with given dict of operations
        """
        self.list_widget.clear()
        for op in operations_dict:
            self.list_widget.addItem(Operation(op))

    def get_operations(self):
        """
        Return list of operations.
        """
        operations = []
        for i in range(self.list_widget.count()):
            op = self.list_widget.item(i)
            operations.append(op._op)

        return operations

    def _remove_operation(self):
        self.list_widget.takeItem(self.list_widget.currentRow())
        self.operations_changed.emit()

    def _add_operation(self):
        """
        Add operation currently in self.operation_settings to the operation
        list.

        Signals:
        ========
        Emits self.opeartion_added and self.operations_changed on success
        """
        op = self.operation_settings.get_operation()
        current_row = self.list_widget.currentRow()
        self.list_widget.insertItem(current_row + 1, Operation(op))
        index = self.list_widget.model().index(current_row + 1, 0)
        self.list_widget.setCurrentIndex(index)
        self.operation_added.emit(op, current_row + 1)
        self.operations_changed.emit()

    def _change_operation(self):
        """
        Replace currently selected operation with operation in
        self.operation_settings (apply changed settings or replace operation).

        Signals:
        ========
        Emits self.operation_changed and self.operations_changed on success
        """
        op = self.operation_settings.get_operation()
        current_row = self.list_widget.currentRow()
        self.list_widget.takeItem(self.list_widget.currentRow())
        self.list_widget.insertItem(current_row, Operation(op))
        index = self.list_widget.model().index(current_row, 0)
        self.list_widget.setCurrentIndex(index)

        self.operation_changed.emit(op, current_row)
        self.operations_changed.emit()


    def _populate_settings_update(self, item):
        """
        Fill self.operation_settings with details of currently selected
        operation.
        """
        try:
            idx = self.operations_combo.findText(item._op["module"])
            if idx >= 0:
                self.operations_combo.setCurrentIndex(idx)
            self.operation_settings.set_operation(item._op)
        except AttributeError:
            pass

    def _populate_settings_add(self, index):
        self.operation_settings.set_operation({"module": self.operations_combo.currentText()})