Ejemplo n.º 1
0
 def testFloatSignal(self):
     foo1 = QDoubleSpinBox()
     foo2 = QDoubleSpinBox()
     foo1.valueChanged[float].connect(foo2.setValue)
     foo2.valueChanged[float].connect(foo1.setValue)
     foo1.setValue(0.42)
     self.assertEqual(foo1.value(), foo2.value())
Ejemplo n.º 2
0
class WidgetConfig(QGroupBox):
    def __init__(self):
        super(WidgetConfig, self).__init__()

        HEIGHT = 30

        grid = QGridLayout()

        # 使用默认摄像头复选框
        self.check_camera = QCheckBox('Use default camera')
        self.check_camera.setChecked(False)
        self.check_camera.stateChanged.connect(self.slot_check_camera)

        grid.addWidget(self.check_camera, 0, 0, 1, 3)  # 一行三列

        # 选择视频文件
        label_video = QLabel('Detect File')
        self.line_video = QLineEdit()
        if 'video' in GLOBAL.config:
            self.line_video.setText(GLOBAL.config['video'])
        self.line_video.setFixedHeight(HEIGHT)
        self.line_video.setEnabled(False)
        self.line_video.editingFinished.connect(
            lambda: GLOBAL.record_config({'video': self.line_video.text()}))

        self.btn_video = QPushButton('Choose')
        self.btn_video.setFixedHeight(HEIGHT)
        self.btn_video.setEnabled(False)
        self.btn_video.clicked.connect(self.choose_video_file)

        self.slot_check_camera()

        grid.addWidget(label_video, 1, 0)
        grid.addWidget(self.line_video, 1, 1)
        grid.addWidget(self.btn_video, 1, 2)

        # 选择权重文件
        label_weights = QLabel('Weights File')
        self.line_weights = QLineEdit()
        if 'weights' in GLOBAL.config:
            self.line_weights.setText(GLOBAL.config['weights'])
        self.line_weights.setFixedHeight(HEIGHT)
        self.line_weights.editingFinished.connect(lambda: GLOBAL.record_config(
            {'weights': self.line_weights.text()}))

        self.btn_weights = QPushButton('Choose')
        self.btn_weights.setFixedHeight(HEIGHT)
        self.btn_weights.clicked.connect(self.choose_weights_file)

        grid.addWidget(label_weights, 2, 0)
        grid.addWidget(self.line_weights, 2, 1)
        grid.addWidget(self.btn_weights, 2, 2)

        # 是否使用GPU
        label_device = QLabel('CUDA device')
        self.line_device = QLineEdit('gpu')
        if 'device' in GLOBAL.config:
            self.line_device.setText(GLOBAL.config['device'])
        else:
            self.line_device.setText('cpu')
        self.line_device.setPlaceholderText('cpu or 0 or 0,1,2,3')
        self.line_device.setFixedHeight(HEIGHT)
        self.line_device.editingFinished.connect(
            lambda: GLOBAL.record_config({'device': self.line_device.text()}))

        grid.addWidget(label_device, 3, 0)
        grid.addWidget(self.line_device, 3, 1, 1, 2)

        # 设置图像大小
        label_size = QLabel('Img Size')
        self.combo_size = QComboBox()
        self.combo_size.setFixedHeight(HEIGHT)
        self.combo_size.setStyleSheet(
            'QAbstractItemView::item {height: 40px;}')
        self.combo_size.setView(QListView())
        self.combo_size.addItem('320', 320)
        self.combo_size.addItem('416', 416)
        self.combo_size.addItem('480', 480)
        self.combo_size.addItem('544', 544)
        self.combo_size.addItem('640', 640)
        self.combo_size.setCurrentIndex(2)
        self.combo_size.currentIndexChanged.connect(
            lambda: GLOBAL.record_config(
                {'img_size': self.combo_size.currentData()}))

        grid.addWidget(label_size, 4, 0)
        grid.addWidget(self.combo_size, 4, 1, 1, 2)

        #choose net camera
        label_stream = QLabel('NetVedioStream')
        self.combo_stream = QComboBox()
        self.combo_stream.setFixedHeight(HEIGHT)
        self.combo_stream.setStyleSheet(
            'QAbstractItemView::item {height: 40px;}')
        self.combo_stream.setView(QListView())
        self.combo_stream.addItem('rtsp://*****:*****@192.168.0.65/',
                                  'rtsp://*****:*****@192.168.0.65/')
        self.combo_stream.addItem('rtsp://*****:*****@192.168.0.66/',
                                  'rtsp://*****:*****@192.168.0.66/')
        self.combo_stream.addItem('rtsp://*****:*****@192.168.0.67/',
                                  'rtsp://*****:*****@192.168.0.67/')
        self.combo_stream.addItem('rtsp://*****:*****@192.168.0.68/',
                                  'rtsp://*****:*****@192.168.0.68/')
        self.combo_stream.addItem('rtsp://*****:*****@192.168.0.65/',
                                  'rtsp://*****:*****@192.168.0.65/')
        self.combo_stream.setCurrentIndex(0)
        self.combo_stream.currentIndexChanged.connect(
            lambda: GLOBAL.record_config(
                {'netstreamvedio': self.combo_stream.currentData()}))

        grid.addWidget(label_stream, 5, 0)
        grid.addWidget(self.combo_stream, 5, 1, 1, 2)

        # 设置置信度阈值
        label_conf = QLabel('Confidence')
        self.spin_conf = QDoubleSpinBox()
        self.spin_conf.setFixedHeight(HEIGHT)
        self.spin_conf.setDecimals(1)
        self.spin_conf.setRange(0.1, 0.9)
        self.spin_conf.setSingleStep(0.1)
        if 'conf_thresh' in GLOBAL.config:
            self.spin_conf.setValue(GLOBAL.config['conf_thresh'])
        else:
            self.spin_conf.setValue(0.4)  # 默认值
            GLOBAL.record_config({'conf_thresh': 0.4})
        self.spin_conf.valueChanged.connect(lambda: GLOBAL.record_config(
            {'conf_thresh': round(self.spin_conf.value(), 1)}))

        grid.addWidget(label_conf, 6, 0)
        grid.addWidget(self.spin_conf, 6, 1, 1, 2)

        # 设置IOU阈值
        label_iou = QLabel('IOU')
        self.spin_iou = QDoubleSpinBox()
        self.spin_iou.setFixedHeight(HEIGHT)
        self.spin_iou.setDecimals(1)
        self.spin_iou.setRange(0.1, 0.9)
        self.spin_iou.setSingleStep(0.1)
        if 'iou_thresh' in GLOBAL.config:
            self.spin_iou.setValue(GLOBAL.config['iou_thresh'])
        else:
            self.spin_iou.setValue(0.5)  # 默认值
            GLOBAL.record_config({'iou_thresh': 0.5})
        self.spin_iou.valueChanged.connect(lambda: GLOBAL.record_config(
            {'iou_thresh': round(self.spin_iou.value(), 1)}))

        grid.addWidget(label_iou, 7, 0)
        grid.addWidget(self.spin_iou, 7, 1, 1, 2)

        # class-agnostic NMS
        self.check_agnostic = QCheckBox('Agnostic')
        if 'agnostic' in GLOBAL.config:
            self.check_agnostic.setChecked(GLOBAL.config['agnostic'])
        else:
            self.check_agnostic.setChecked(True)
        self.check_agnostic.stateChanged.connect(lambda: GLOBAL.record_config(
            {'agnostic': self.check_agnostic.isChecked()}))

        grid.addWidget(self.check_agnostic, 8, 0, 1, 3)  # 一行三列

        # augmented inference
        self.check_augment = QCheckBox('Augment')
        if 'augment' in GLOBAL.config:
            self.check_augment.setChecked(GLOBAL.config['augment'])
        else:
            self.check_augment.setChecked(True)
        self.check_augment.stateChanged.connect(lambda: GLOBAL.record_config(
            {'augment': self.check_augment.isChecked()}))

        grid.addWidget(self.check_augment, 9, 0, 1, 3)  # 一行三列

        self.setLayout(grid)  # 设置布局

    def slot_check_camera(self):
        check = self.check_camera.isChecked()
        GLOBAL.record_config({'use_camera': check})  # 保存配置
        if check:
            self.line_video.setEnabled(False)
            self.btn_video.setEnabled(False)
        else:
            self.line_video.setEnabled(True)
            self.btn_video.setEnabled(True)

    def choose_weights_file(self):
        """从系统中选择权重文件"""
        file = QFileDialog.getOpenFileName(
            self, "Pre-trained YOLOv5 Weights", "./",
            "Weights Files (*.pt);;All Files (*)")
        if file[0] != '':
            self.line_weights.setText(file[0])
            GLOBAL.record_config({'weights': file[0]})

    def choose_video_file(self):
        """从系统中选择视频文件"""
        file = QFileDialog.getOpenFileName(self, "Video Files", "./",
                                           "Video Files (*)")
        if file[0] != '':
            self.line_video.setText(file[0])
            GLOBAL.record_config({'video': file[0]})

    def save_config(self):
        """保存当前的配置到配置文件"""
        config = {
            'use_camera': self.check_camera.isChecked(),
            'video': self.line_video.text(),
            'weights': self.line_weights.text(),
            'device': self.line_device.text(),
            'img_size': self.combo_size.currentData(),
            'conf_thresh': round(self.spin_conf.value(), 1),
            'iou_thresh': round(self.spin_iou.value(), 1),
            'agnostic': self.check_agnostic.isChecked(),
            'augment': self.check_augment.isChecked(),
            'netstreamvedio': self.combo_stream.currentData()
        }
        GLOBAL.record_config(config)
Ejemplo n.º 3
0
class EUI(QDialog):
    def __init__(self, ip, port, sal, parent=None):
        super(EUI, self).__init__(parent)
        self.ip = ip
        self.port = port
        self.client = liveview.AsyncLiveViewClient(self.ip, self.port)
        self.event_loop = asyncio.get_event_loop()
        self.event_loop.run_until_complete(self.client.start())
        # self.sal = salobj.Remote(SALPY_GenericCamera, index=salIndex)
        self.sal = sal
        # self.sal.subscribeEvent

        self.layout = QHBoxLayout()
        self.controlsLayout = QVBoxLayout()
        self.imageLayout = QVBoxLayout()

        layout = QHBoxLayout()
        self.startLiveViewButton = QPushButton("Start Live")
        self.startLiveViewButton.clicked.connect(self.startLiveView)
        self.stopLiveViewButton = QPushButton("Stop Live")
        self.stopLiveViewButton.clicked.connect(self.stopLiveView)
        layout.addWidget(self.startLiveViewButton)
        layout.addWidget(self.stopLiveViewButton)
        self.controlsLayout.addLayout(layout)

        layout = QHBoxLayout()
        layout.addWidget(QLabel("Exposure"))
        self.exposureTimeEdit = QDoubleSpinBox()
        self.exposureTimeEdit.setRange(0, 900.0)
        self.exposureTimeEdit.setDecimals(6)
        layout.addWidget(self.exposureTimeEdit)
        self.controlsLayout.addLayout(layout)

        layout = QVBoxLayout()
        subLayout = QHBoxLayout()
        subLayout.addWidget(QLabel("Top"))
        self.roiTopEdit = QDoubleSpinBox()
        self.roiTopEdit.setRange(0, 4095)
        self.roiTopEdit.setDecimals(0)
        subLayout.addWidget(self.roiTopEdit)
        layout.addLayout(subLayout)
        subLayout = QHBoxLayout()
        subLayout.addWidget(QLabel("Left"))
        self.roiLeftEdit = QDoubleSpinBox()
        self.roiLeftEdit.setRange(0, 4095)
        self.roiLeftEdit.setDecimals(0)
        subLayout.addWidget(self.roiLeftEdit)
        layout.addLayout(subLayout)
        subLayout = QHBoxLayout()
        subLayout.addWidget(QLabel("Width"))
        self.roiWidthEdit = QDoubleSpinBox()
        self.roiWidthEdit.setRange(0, 4095)
        self.roiWidthEdit.setDecimals(0)
        subLayout.addWidget(self.roiWidthEdit)
        layout.addLayout(subLayout)
        subLayout = QHBoxLayout()
        subLayout.addWidget(QLabel("Height"))
        self.roiHeightEdit = QDoubleSpinBox()
        self.roiHeightEdit.setRange(0, 4095)
        self.roiHeightEdit.setDecimals(0)
        subLayout.addWidget(self.roiHeightEdit)
        layout.addLayout(subLayout)
        self.setROIButton = QPushButton("Set")
        self.setROIButton.clicked.connect(self.setROI)
        layout.addWidget(self.setROIButton)
        self.setFullFrameButton = QPushButton("Set Full Frame")
        self.setFullFrameButton.clicked.connect(self.setFullFrame)
        layout.addWidget(self.setFullFrameButton)
        self.controlsLayout.addLayout(layout)

        layout = QVBoxLayout()
        layout.addWidget(QLabel("File Path:"))
        self.filePathEdit = QTextEdit()
        layout.addWidget(self.filePathEdit)
        self.takeExposureButton = QPushButton("Take Images")
        self.takeExposureButton.clicked.connect(self.takeImages)
        layout.addWidget(self.takeExposureButton)
        self.controlsLayout.addLayout(layout)

        img = Image.fromarray(np.zeros((1024, 1014))).convert("I")
        img.save("/tmp/foo.png")

        self.pix = QPixmap("/tmp/foo.png")

        self.imageLabel = QLabel()
        self.imageLabel.setPixmap(self.pix)
        self.imageLabel.setGeometry(QtCore.QRect(40, 40, 800, 800))

        self.imageLayout.addWidget(self.imageLabel)

        self.layout.addLayout(self.controlsLayout)
        self.layout.addLayout(self.imageLayout)

        self.setLayout(self.layout)
        self.setFixedSize(1000, 880)

    def updateDisplays(self):
        print("updateDisplays - Here - 1")
        try:
            if self.client is None or self.client.reader is not None:
                try:
                    print("updateDisplays - Here - 2")
                    self.client = liveview.AsyncLiveViewClient(
                        self.ip, self.port)
                    self.event_loop.run_until_complete(self.client.start())
                except Exception:
                    print("Error on client!")
                    self.client = None
            print("updateDisplays - Here - 3")
            exposure = self.event_loop.run_until_complete(
                self.client.receive_exposure())
            print("New exposure.")
            # exposure.makeJPEG()
            # img = Image.open(BytesIO(exposure.buffer))
            # width = img.size[0]
            # height = img.size[1]
            # ratio = width / height
            # deltaWidth = width - 760
            # deltaHeight = height - 760
            # if deltaWidth > 0 or deltaHeight > 0:
            #     newWidth = 760
            #     newHeight = 760
            #     if deltaWidth > deltaHeight:
            #         newWidth = newWidth
            #         newHeight = newHeight / ratio
            #     elif deltaHeight > deltaWidth:
            #         newWidth = newWidth / ratio
            #         newHeight = newHeight
            #     img = img.resize((int(newWidth), int(newHeight)))
            as8 = exposure.buffer.astype(np.uint8)
            img = Image.fromarray(as8.reshape(exposure.height, exposure.width))
            img.save("/tmp/foo.png")

            self.pix = QPixmap("/tmp/foo.png")

            self.imageLabel.setPixmap(self.pix)
        except liveview.ImageReceiveError as e:
            print("updateDisplays - Exception")
            traceback.format_exc(e)
            pass

    def startLiveView(self):
        print("startLiveView - Start")
        # data = self.sal.cmd_startLiveView.DataType()
        # data.expTime = self.exposureTimeEdit.value()
        # asyncio.get_event_loop().run_until_complete(
        #     self.sal.cmd_startLiveView.start(data, timeout=10.0)
        # )
        self.sal.issueCommand_startLiveView(self.exposureTimeEdit.value())
        print("startLiveView - End")

    def stopLiveView(self):
        print("stopLiveView - Start")
        # asyncio.get_event_loop().run_until_complete(
        #     self.sal.cmd_stopLiveView.start(
        # self.sal.cmd_stopLiveView.DataType(), timeout=10.0))
        self.sal.issueCommand_stopLiveView(True)
        print("stopLiveView - End")

    def setROI(self):
        print("setROI - Start")
        # data = self.sal.cmd_setROI.DataType()
        # data.topPixel = int(self.roiTopEdit.value())
        # data.leftPixel = int(self.roiLeftEdit.value())
        # data.width = int(self.roiWidthEdit.value())
        # data.height = int(self.roiHeightEdit.value())
        # asyncio.get_event_loop().run_until_complete(
        #     self.sal.cmd_setROI.start(data, timeout=5.0)
        # )
        self.sal.issueCommand_setROI(
            int(self.roiTopEdit.value()),
            int(self.roiLeftEdit.value()),
            int(self.roiWidthEdit.value()),
            int(self.roiHeightEdit.value()),
        )
        print("setROI - End")

    def setFullFrame(self):
        print("setFullFrame - Start")
        # asyncio.get_event_loop().run_until_complete(self.sal.cmd_setFullFrame.start(
        # self.sal.cmd_setFullFrame.DataType(), timeout=5.0))
        self.sal.issueCommand_setFullFrame(True)
        print("setFullFrame - End")

    def takeImages(self):
        print("takeImages - Start")
        # data = self.sal.cmd_takeImages.DataType()
        # data.numImages = 1
        # data.expTime = self.exposureTimeEdit.value()
        # data.shutter = 1
        # data.imageSequenceName = "Foo"
        # asyncio.get_event_loop().run_until_complete(self.sal.cmd_takeImages.start(data,
        # timeout=30.0))
        self.sal.issueCommand_takeImages(1, self.exposureTimeEdit.value(), 1,
                                         "Foo")
        print("takeImages - End")
Ejemplo n.º 4
0
class SubtitleInfoDialog(QDialog):
    def __init__(self,
                 subtitles_name,
                 subtitles_delay,
                 subtitles_language,
                 subtitles_track_name,
                 subtitles_set_default,
                 subtitles_set_forced,
                 subtitles_default_value_delay,
                 subtitles_default_value_language,
                 subtitles_default_value_track_name,
                 subtitles_default_value_set_default,
                 subtitles_default_value_set_forced,
                 subtitle_set_default_disabled=False,
                 subtitle_set_forced_disabled=False,
                 disable_edit=False,
                 parent=None):
        super().__init__(parent)
        self.window_title = "Subtitle Info"
        self.state = "no"
        self.subtitles_count = len(subtitles_delay)

        self.messageIcon = QLabel()
        self.subtitle_tab_comboBox = InfoCellDialogTabComboBox(
            hint="Subtitles Groups")
        for i in range(self.subtitles_count):
            self.subtitle_tab_comboBox.addItem("Subtitle #" + str(i + 1))
        self.subtitle_tab_comboBox.setCurrentIndex(0)
        self.subtitle_tab_comboBox.currentIndexChanged.connect(
            self.update_current_subtitle_index)
        self.current_subtitle_index = 0

        self.disable_edit = disable_edit
        self.current_subtitle_name = subtitles_name
        self.current_subtitle_language = subtitles_language
        self.current_subtitle_delay = subtitles_delay
        self.current_subtitle_track_name = subtitles_track_name
        self.current_subtitle_set_default = subtitles_set_default
        self.current_subtitle_set_forced = subtitles_set_forced

        self.default_subtitle_language = subtitles_default_value_language
        self.default_subtitle_delay = subtitles_default_value_delay
        self.default_subtitle_track_name = subtitles_default_value_track_name
        self.default_subtitle_set_default = subtitles_default_value_set_default
        self.default_subtitle_set_forced = subtitles_default_value_set_forced

        self.subtitle_set_default_disabled = subtitle_set_default_disabled
        self.subtitle_set_forced_disabled = subtitle_set_forced_disabled

        self.subtitle_name_label = QLabel("Subtitle Name:")
        self.subtitle_name_value = QLabel(
            str(self.current_subtitle_name[self.current_subtitle_index]))
        width_to_be_fixed = 0
        for i in range(len(self.current_subtitle_name)):
            width_to_be_fixed = max(
                width_to_be_fixed,
                self.subtitle_name_value.fontMetrics().boundingRect(
                    self.current_subtitle_name[i]).width())
        self.subtitle_name_value.setFixedWidth(width_to_be_fixed + 10)
        self.subtitle_delay_label = QLabel("Subtitle Delay:")
        self.subtitle_delay_spin = QDoubleSpinBox()
        self.setup_subtitle_delay_spin()

        self.subtitle_language_label = QLabel("Subtitle Language:")
        self.subtitle_language_comboBox = QComboBox()
        self.setup_subtitle_language_comboBox()

        self.subtitle_track_name_label = QLabel("Subtitle Track Name:")
        self.subtitle_track_name_lineEdit = QLineEdit()
        self.setup_subtitle_track_name_lineEdit()

        self.subtitle_set_forced_label = QLabel("Subtitle Forced State:")
        self.subtitle_set_forced_checkBox = QCheckBox()
        self.setup_subtitle_set_forced_checkBox()

        self.subtitle_set_default_label = QLabel("Subtitle Default State:")
        self.subtitle_set_default_checkBox = QCheckBox()
        self.setup_subtitle_set_default_checkBox()

        self.yes_button = QPushButton("OK")
        self.no_button = QPushButton("Cancel")
        self.reset_button = QPushButton("Reset To Default")

        self.buttons_layout = QHBoxLayout()
        self.subtitle_delay_layout = QHBoxLayout()
        self.subtitle_language_layout = QHBoxLayout()
        self.subtitle_track_name_layout = QHBoxLayout()
        self.subtitle_set_default_layout = QHBoxLayout()
        self.subtitle_set_forced_layout = QHBoxLayout()
        self.buttons_layout.addWidget(QLabel(""), stretch=3)
        self.buttons_layout.addWidget(self.reset_button, stretch=2)
        self.buttons_layout.addWidget(self.yes_button, stretch=2)
        self.buttons_layout.addWidget(self.no_button, stretch=2)
        self.buttons_layout.addWidget(QLabel(""), stretch=3)
        self.subtitle_setting_layout = QGridLayout()
        self.subtitle_editable_setting_layout = QFormLayout()
        self.subtitle_editable_setting_layout.addRow(self.subtitle_name_label,
                                                     self.subtitle_name_value)
        self.subtitle_editable_setting_layout.addRow(
            self.subtitle_track_name_label, self.subtitle_track_name_lineEdit)
        self.subtitle_editable_setting_layout.addRow(
            self.subtitle_language_label, self.subtitle_language_comboBox)
        self.subtitle_editable_setting_layout.addRow(self.subtitle_delay_label,
                                                     self.subtitle_delay_spin)
        self.subtitle_editable_setting_layout.addRow(
            self.subtitle_set_default_label,
            self.subtitle_set_default_checkBox)
        self.subtitle_editable_setting_layout.addRow(
            self.subtitle_set_forced_label, self.subtitle_set_forced_checkBox)
        self.subtitle_setting_layout.addWidget(self.subtitle_tab_comboBox, 0,
                                               0)
        self.subtitle_setting_layout.addLayout(
            self.subtitle_editable_setting_layout, 1, 0, 5, 2)
        self.subtitle_setting_layout.addWidget(self.messageIcon, 1, 3, 5, -1)

        self.main_layout = QGridLayout()
        self.main_layout.addLayout(self.subtitle_setting_layout, 0, 0, 2, 3)
        self.main_layout.addLayout(self.buttons_layout, 2, 0, 1, -1)
        self.main_layout.setContentsMargins(20, 20, 20, 20)
        self.setLayout(self.main_layout)

        self.setup_ui()
        self.signal_connect()

    def setup_ui(self):
        self.disable_question_mark_window()
        self.messageIcon.setPixmap(
            QtGui.QPixmap(GlobalFiles.SubtitleIconPath).scaledToHeight(100))
        self.set_dialog_values()
        self.set_default_buttons()
        if self.subtitle_set_default_disabled:
            self.subtitle_set_default_disable()
        if self.subtitle_set_forced_disabled:
            self.subtitle_set_forced_disable()
        if self.disable_edit:
            self.subtitle_track_name_lineEdit.setEnabled(False)
            self.subtitle_language_comboBox.setEnabled(False)
            self.subtitle_delay_spin.setEnabled(False)
            self.subtitle_set_default_checkBox.setEnabled(False)
            self.subtitle_set_forced_checkBox.setEnabled(False)
            self.reset_button.setEnabled(False)

        self.setup_tool_tip_hint_subtitle_set_default()
        self.setup_tool_tip_hint_subtitle_set_forced()

    def signal_connect(self):
        self.subtitle_track_name_lineEdit.textEdited.connect(
            self.update_current_subtitle_track_name)
        self.subtitle_delay_spin.editingFinished.connect(
            self.update_current_subtitle_delay)
        self.subtitle_language_comboBox.currentTextChanged.connect(
            self.update_current_subtitle_language)
        self.subtitle_set_default_checkBox.stateChanged.connect(
            self.update_current_subtitle_set_default)
        self.subtitle_set_forced_checkBox.stateChanged.connect(
            self.update_current_subtitle_set_forced)
        self.yes_button.clicked.connect(self.click_yes)
        self.no_button.clicked.connect(self.click_no)
        self.reset_button.clicked.connect(self.reset_subtitle_setting)

    def click_yes(self):
        self.state = "yes"
        self.close()

    def click_no(self):
        self.state = "no"
        self.close()

    def set_dialog_values(self):
        self.setWindowTitle(self.window_title)
        self.setWindowIcon(GlobalFiles.InfoSettingIcon)

    def disable_question_mark_window(self):
        self.setWindowFlag(Qt.WindowContextHelpButtonHint, on=False)

    def increase_message_font_size(self, value):
        message_font = self.message.font()
        message_font.setPointSize(self.message.fontInfo().pointSize() + value)
        self.message.setFont(message_font)

    def set_default_buttons(self):
        self.yes_button.setDefault(True)
        self.yes_button.setFocus()

    def showEvent(self, a0: QtGui.QShowEvent) -> None:
        super().showEvent(a0)
        self.setFixedSize(self.size())

    def setup_subtitle_track_name_lineEdit(self):
        self.subtitle_track_name_lineEdit.setClearButtonEnabled(True)
        self.subtitle_track_name_lineEdit.setText(
            self.current_subtitle_track_name[self.current_subtitle_index])

    def setup_subtitle_language_comboBox(self):
        self.subtitle_language_comboBox.addItems(AllSubtitlesLanguages)
        self.subtitle_language_comboBox.setCurrentIndex(
            AllSubtitlesLanguages.index(
                self.current_subtitle_language[self.current_subtitle_index]))
        self.subtitle_language_comboBox.setMaxVisibleItems(8)
        self.subtitle_language_comboBox.setStyleSheet(
            "QComboBox { combobox-popup: 0; }")

    def setup_subtitle_delay_spin(self):
        # self.subtitle_delay_spin.setMaximumWidth(screen_size.width() // 16)
        self.subtitle_delay_spin.setDecimals(3)
        self.subtitle_delay_spin.setMinimum(-9999.0)
        self.subtitle_delay_spin.setMaximum(9999.0)
        self.subtitle_delay_spin.setSingleStep(0.5)
        self.subtitle_delay_spin.setValue(
            float(self.current_subtitle_delay[self.current_subtitle_index]))

    def setup_subtitle_set_default_checkBox(self):
        self.subtitle_set_default_checkBox.setText("Set Default")
        self.subtitle_set_default_checkBox.setChecked(
            bool(self.current_subtitle_set_default[
                self.current_subtitle_index]))

    def setup_subtitle_set_forced_checkBox(self):
        self.subtitle_set_forced_checkBox.setText("Set Forced")
        self.subtitle_set_forced_checkBox.setChecked(
            bool(
                self.current_subtitle_set_forced[self.current_subtitle_index]))

    def update_current_subtitle_track_name(self):
        self.current_subtitle_track_name[self.current_subtitle_index] = str(
            self.subtitle_track_name_lineEdit.text())

    def update_current_subtitle_delay(self):
        self.current_subtitle_delay[self.current_subtitle_index] = round(
            self.subtitle_delay_spin.value(), 5)

    def update_current_subtitle_language(self):
        self.current_subtitle_language[self.current_subtitle_index] = str(
            self.subtitle_language_comboBox.currentText())

    def update_current_subtitle_set_default(self):
        new_state = self.subtitle_set_default_checkBox.checkState(
        ) == Qt.Checked
        self.current_subtitle_set_default[
            self.current_subtitle_index] = new_state
        if new_state:
            for i in range(len(self.current_subtitle_set_default)):
                if i != self.current_subtitle_index:
                    self.current_subtitle_set_default[i] = False

    def update_current_subtitle_set_forced(self):
        new_state = self.subtitle_set_forced_checkBox.checkState(
        ) == Qt.Checked
        self.current_subtitle_set_forced[
            self.current_subtitle_index] = new_state
        if new_state:
            for i in range(len(self.current_subtitle_set_forced)):
                if i != self.current_subtitle_index:
                    self.current_subtitle_set_forced[i] = False

    def reset_subtitle_setting(self):
        self.current_subtitle_language[
            self.current_subtitle_index] = self.default_subtitle_language[
                self.current_subtitle_index]
        self.current_subtitle_delay[
            self.current_subtitle_index] = self.default_subtitle_delay[
                self.current_subtitle_index]
        self.current_subtitle_track_name[
            self.current_subtitle_index] = self.default_subtitle_track_name[
                self.current_subtitle_index]
        self.current_subtitle_set_default[
            self.current_subtitle_index] = self.default_subtitle_set_default[
                self.current_subtitle_index]
        self.current_subtitle_set_forced[
            self.current_subtitle_index] = self.default_subtitle_set_forced[
                self.current_subtitle_index]

        self.subtitle_language_comboBox.setCurrentIndex(
            AllSubtitlesLanguages.index(
                self.current_subtitle_language[self.current_subtitle_index]))
        self.subtitle_delay_spin.setValue(
            float(self.current_subtitle_delay[self.current_subtitle_index]))
        self.subtitle_track_name_lineEdit.setText(
            self.current_subtitle_track_name[self.current_subtitle_index])
        self.subtitle_set_default_checkBox.setChecked(
            bool(self.current_subtitle_set_default[
                self.current_subtitle_index]))
        self.subtitle_set_forced_checkBox.setChecked(
            bool(
                self.current_subtitle_set_forced[self.current_subtitle_index]))

    def subtitle_set_default_disable(self):
        self.subtitle_set_default_checkBox.setDisabled(True)

    def subtitle_set_forced_disable(self):
        self.subtitle_set_forced_checkBox.setDisabled(True)

    def setup_tool_tip_hint_subtitle_set_default(self):
        if self.subtitle_set_default_checkBox.isEnabled():
            self.subtitle_set_default_checkBox.setToolTip(
                "<nobr>set this subtitle to be the default subtitle track "
                "when play")
            self.subtitle_set_default_checkBox.setToolTipDuration(12000)
        else:
            self.subtitle_set_default_checkBox.setToolTip(
                "<nobr>set this subtitle to be the default subtitle track when play<br><b>Disabled</b> because "
                "option "
                "<b>make this subtitle default</b> is enabled on mux setting tab "
            )
            self.subtitle_set_default_checkBox.setToolTipDuration(12000)

    def setup_tool_tip_hint_subtitle_set_forced(self):
        if self.subtitle_set_forced_checkBox.isEnabled():
            self.subtitle_set_forced_checkBox.setToolTip(
                "<nobr>set this subtitle to be the forced subtitle track when "
                "play")
            self.subtitle_set_forced_checkBox.setToolTipDuration(12000)
        else:
            self.subtitle_set_forced_checkBox.setToolTip(
                "<nobr>set this subtitle to be the forced subtitle track when play<br><b>Disabled</b> because "
                "option "
                "<b>make this subtitle default and forced</b> is enabled on mux setting tab "
            )
            self.subtitle_set_forced_checkBox.setToolTipDuration(12000)

    def update_current_subtitle_index(self, new_index):
        self.current_subtitle_index = new_index
        self.subtitle_delay_spin.setValue(
            float(self.current_subtitle_delay[self.current_subtitle_index]))
        self.subtitle_set_default_checkBox.setChecked(
            bool(self.current_subtitle_set_default[
                self.current_subtitle_index]))
        self.subtitle_set_forced_checkBox.setChecked(
            bool(
                self.current_subtitle_set_forced[self.current_subtitle_index]))
        self.subtitle_language_comboBox.setCurrentIndex(
            AllSubtitlesLanguages.index(
                self.current_subtitle_language[self.current_subtitle_index]))
        self.subtitle_track_name_lineEdit.setText(
            self.current_subtitle_track_name[self.current_subtitle_index])
        self.subtitle_name_value.setText(
            str(self.current_subtitle_name[self.current_subtitle_index]))

    def execute(self):
        self.exec_()
Ejemplo n.º 5
0
 def testQRealSignal(self):
     foo1 = QDoubleSpinBox()
     effect = QGraphicsBlurEffect()
     effect.blurRadiusChanged['qreal'].connect(foo1.setValue) # check if qreal is a valid type
     effect.setBlurRadius(0.42)
     self.assertAlmostEqual(foo1.value(), effect.blurRadius())
Ejemplo n.º 6
0
class SettingsDialog(QDialog):
    def __init__(self):
        super(SettingsDialog, self).__init__()
        self.setWindowTitle('Settings')
        self.setWindowIcon(QIcon('img/yologo.png'))
        self.setWindowFlags(Qt.WindowCloseButtonHint)
        self.setMinimumWidth(600)

        HEIGHT = 30

        grid = QGridLayout()

        # 选择权重文件
        label_weights = QLabel('Weights')
        self.line_weights = QLineEdit()
        self.line_weights.setFixedHeight(HEIGHT)

        self.btn_weights = QPushButton('...')
        self.btn_weights.setFixedWidth(40)
        self.btn_weights.setFixedHeight(HEIGHT)
        self.btn_weights.clicked.connect(self.choose_weights_file)

        grid.addWidget(label_weights, 2, 0)
        grid.addWidget(self.line_weights, 2, 1, 1, 2)
        grid.addWidget(self.btn_weights, 2, 3)

        # 是否使用GPU
        label_device = QLabel('CUDA device')
        self.line_device = QLineEdit('cpu')
        self.line_device.setToolTip('cuda device, i.e. 0 or 0,1,2,3 or cpu')
        self.line_device.setPlaceholderText('cpu or 0 or 0,1,2,3')
        self.line_device.setFixedHeight(HEIGHT)

        grid.addWidget(label_device, 3, 0)
        grid.addWidget(self.line_device, 3, 1, 1, 3)

        # 设置图像大小
        label_size = QLabel('Img Size')
        self.combo_size = QComboBox()
        self.combo_size.setToolTip('inference size (pixels)')
        self.combo_size.setFixedHeight(HEIGHT)
        self.combo_size.setStyleSheet(
            'QAbstractItemView::item {height: 40px;}')
        self.combo_size.setView(QListView())
        self.combo_size.addItem('320', 320)
        self.combo_size.addItem('384', 384)
        self.combo_size.addItem('448', 448)
        self.combo_size.addItem('512', 512)
        self.combo_size.addItem('576', 576)
        self.combo_size.addItem('640', 640)

        grid.addWidget(label_size, 4, 0)
        grid.addWidget(self.combo_size, 4, 1, 1, 3)

        # 设置置信度阈值
        label_conf = QLabel('Confidence')
        self.spin_conf = QDoubleSpinBox()
        self.spin_conf.setToolTip('confidence threshold')
        self.spin_conf.setFixedHeight(HEIGHT)
        self.spin_conf.setDecimals(1)
        self.spin_conf.setRange(0.1, 0.9)
        self.spin_conf.setSingleStep(0.1)

        grid.addWidget(label_conf, 5, 0)
        grid.addWidget(self.spin_conf, 5, 1, 1, 3)

        # 设置IOU阈值
        label_iou = QLabel('IOU')
        self.spin_iou = QDoubleSpinBox()
        self.spin_iou.setToolTip('NMS IoU threshold')
        self.spin_iou.setFixedHeight(HEIGHT)
        self.spin_iou.setDecimals(1)
        self.spin_iou.setRange(0.1, 0.9)
        self.spin_iou.setSingleStep(0.1)

        grid.addWidget(label_iou, 6, 0)
        grid.addWidget(self.spin_iou, 6, 1, 1, 3)

        # maximum detections per image
        label_max_det = QLabel('maximum detections')
        self.spin_max_det = QDoubleSpinBox()
        self.spin_max_det.setToolTip('Maximum detections per image')
        self.spin_max_det.setFixedHeight(HEIGHT)
        self.spin_max_det.setDecimals(0)
        self.spin_max_det.setRange(10, 1000)
        self.spin_max_det.setSingleStep(10)

        grid.addWidget(label_max_det, 7, 0)
        grid.addWidget(self.spin_max_det, 7, 1, 1, 3)

        # class-agnostic NMS
        self.check_agnostic = QCheckBox('Agnostic')
        self.check_agnostic.setToolTip('class-agnostic NMS')

        # augmented inference
        self.check_augment = QCheckBox('Augment')
        self.check_augment.setToolTip('augmented inference')

        # half
        self.check_half = QCheckBox('Half')
        self.check_half.setToolTip('use FP16 half-precision inference')

        grid.addWidget(self.check_agnostic, 8, 0)
        grid.addWidget(self.check_augment, 8, 1)
        grid.addWidget(self.check_half, 8, 2)

        # use OpenCV DNN for ONNX inference
        self.check_dnn = QCheckBox('DNN')
        self.check_dnn.setToolTip('Use OpenCV DNN for ONNX inference')

        grid.addWidget(self.check_dnn, 9, 0)

        box = QGroupBox()
        box.setLayout(grid)

        hbox = QHBoxLayout()
        self.btn_cancel = QPushButton('Cancel')
        self.btn_cancel.clicked.connect(self.restore)
        self.btn_ok = QPushButton('Ok')
        self.btn_ok.clicked.connect(self.save_settings)
        hbox.addStretch()
        hbox.addWidget(self.btn_cancel)
        hbox.addWidget(self.btn_ok)

        vbox = QVBoxLayout()
        vbox.addWidget(box)
        vbox.addLayout(hbox)

        self.setLayout(vbox)

        self.load_settings()

    def choose_weights_file(self):
        """从系统中选择权重文件"""
        weights_path = '.'
        weights = gb.get_config('weights', '')
        if os.path.exists(weights):
            weights_path = os.path.dirname(weights)
        file = QFileDialog.getOpenFileName(
            self, "Pre-trained YOLOv5 Weights", weights_path,
            "Weights Files (*.pt);;All Files (*)")
        if file[0] != '':
            self.line_weights.setText(file[0])

    def load_settings(self):
        self.line_weights.setText(gb.get_config('weights', ''))
        self.line_device.setText(gb.get_config('device', 'cpu'))
        self.combo_size.setCurrentText(gb.get_config('img_size', '640'))
        self.spin_conf.setValue(gb.get_config('conf_thresh', 0.5))
        self.spin_iou.setValue(gb.get_config('iou_thresh', 0.5))
        self.spin_max_det.setValue(gb.get_config('max_det', 50))
        self.check_agnostic.setChecked(gb.get_config('agnostic', True))
        self.check_augment.setChecked(gb.get_config('augment', True))
        self.check_half.setChecked(gb.get_config('half', True))
        self.check_dnn.setChecked(gb.get_config('dnn', False))

    def save_settings(self):
        """更新配置"""
        config = {
            'weights': self.line_weights.text(),
            'device': self.line_device.text(),
            'img_size': self.combo_size.currentText(),
            'conf_thresh': round(self.spin_conf.value(), 1),
            'iou_thresh': round(self.spin_iou.value(), 1),
            'max_det': int(self.spin_max_det.value()),
            'agnostic': self.check_agnostic.isChecked(),
            'augment': self.check_augment.isChecked(),
            'half': self.check_half.isChecked(),
            'dnn': self.check_dnn.isChecked()
        }
        gb.record_config(config)
        self.accept()

    def restore(self):
        """恢复原配置"""
        self.load_settings()
        self.reject()

    def closeEvent(self, event):
        self.restore()
Ejemplo n.º 7
0
class Dicom_ImageToolsWidget(QWidget):
    __tab_name__ = 'Tools'
    pen_selected = Signal()
    mask_color: QColor() = QColor('green')
    pen: bool = False

    def __init__(self):
        super().__init__()
        self.width = 20
        self.init_ui()

    def init_ui(self):

        self.slider = self.__init_slider__()
        self.color_btn = ColorButton(self.mask_color)
        self.color_btn.clicked.connect(self.open_color_dialog)
        self.pen_btn = QPushButton('Pen')

        self.pen_size = QDoubleSpinBox()
        self.pen_size.setRange(1, 30)
        self.pen_size.setValue(1)
        self.pen_size.setDecimals(0)
        self.pen_size.setSingleStep(1)
        self.pen_btn.setCheckable(True)
        self.pen_btn.clicked.connect(self.pen_selected.emit)

        self.erase_btn = QPushButton('Erase')
        self.erase_btn.setCheckable(True)

        self.processing_btn = QPushButton('Segment with NN')
        self.nj_segment_btn = QPushButton('Semi automated segment')

        self.load_mask_btn = QPushButton('Load mask from NIFTI')
        self.save_mask_btn = QPushButton('Save mask to NIFTI')

        self.scope_btn = QPushButton('Scope')

        drawing_layout = QHBoxLayout()
        drawing_layout.addWidget(self.pen_btn)
        drawing_layout.addWidget(self.erase_btn)

        segmentation_layout = QHBoxLayout()
        segmentation_layout.addWidget(self.processing_btn)
        segmentation_layout.addWidget(self.nj_segment_btn)

        files_managment_layout = QHBoxLayout()
        files_managment_layout.addWidget(self.load_mask_btn)
        files_managment_layout.addWidget(self.save_mask_btn)

        layout = QVBoxLayout(self)
        layout.setAlignment(Qt.AlignTop)
        layout.addWidget(QLabel('Image slice: '))
        layout.addWidget(self.slider)
        layout.addWidget(QLabel('Mask color: '))
        layout.addWidget(self.color_btn)
        layout.addWidget(self.pen_size)
        layout.addLayout(drawing_layout)
        layout.addLayout(segmentation_layout)
        layout.addLayout(files_managment_layout)

    def open_color_dialog(self):
        self.mask_color = QColorDialog.getColor(self.color_btn.color)
        self.color_btn.color = self.mask_color
        self.color_btn.update()

    def get_color(self) -> QColor: return self.mask_color

    def get_size(self) -> int: return int(self.pen_size.value())

    def set_slider_maximum(self, max: int):
        self.slider.setMaximum(max)

    @property
    def tab_name(self):
        return self.__tab_name__

    def __init_slider__(self, max: int = 1) -> QSlider:
        slider = QSlider()
        slider.setOrientation(Qt.Horizontal)
        slider.setMinimum(0)
        slider.setMaximum(max)
        slider.setTickInterval(1)
        slider.setSliderPosition(1)

        return slider
Ejemplo n.º 8
0
 def testQRealSignal(self):
     foo1 = QDoubleSpinBox()
     effect = QGraphicsBlurEffect()
     effect.blurRadiusChanged['qreal'].connect(foo1.setValue) # check if qreal is a valid type
     effect.setBlurRadius(0.42)
     self.assertAlmostEqual(foo1.value(), effect.blurRadius())
class GeneralView(QWidget):
    """Config widget for general properties of an experiment.
    This "view" does not have a model. Instead, it is a part of a bigger view called ExperimentView, and gets updated
    with it.
    """

    inlet_type_export_values = {
        "LSL stream": "lsl",
        "LSL file stream": "lsl_from_file",
        "LSL generator": "lsl_generator",
        "Field trip buffer": "ftbuffer"
    }
    inlet_type_import_values = {
        v: k
        for k, v in inlet_type_export_values.items()
    }

    def __init__(self, parent=None):
        super().__init__(parent=parent)
        layout = QFormLayout()
        self.setLayout(layout)

        self.name = QLineEdit()

        # prefilter_lower_bound ---------------------------------------------------------------------------------------------
        self.prefilter_lower_bound_enable = QCheckBox()
        self.prefilter_lower_bound_enable.stateChanged.connect(self._adjust)

        self.prefilter_lower_bound = QDoubleSpinBox()
        self.prefilter_lower_bound.setEnabled(False)
        self.prefilter_lower_bound.valueChanged.connect(self._adjust)
        self.prefilter_lower_bound.setMinimum(0)
        self.prefilter_lower_bound.setMaximum(0)  # TODO: add proper value
        self.prefilter_lower_bound.setValue(0)  # TODO: add proper value

        prefilter_lower_bound_widget = QWidget()
        prefilter_lower_bound_widget.setContentsMargins(0, 0, 0, 0)
        prefilter_lower_bound_widget.setLayout(QHBoxLayout())
        prefilter_lower_bound_widget.layout().setContentsMargins(0, 0, 0, 0)
        prefilter_lower_bound_widget.layout().addWidget(
            self.prefilter_lower_bound_enable)
        prefilter_lower_bound_widget.layout().addWidget(
            self.prefilter_lower_bound)

        # prefilter_upper_bound --------------------------------------------------------------------------------------------
        self.prefilter_upper_bound_enable = QCheckBox()
        self.prefilter_upper_bound_enable.stateChanged.connect(self._adjust)

        self.prefilter_upper_bound = QDoubleSpinBox()
        self.prefilter_upper_bound.setEnabled(False)
        self.prefilter_upper_bound.valueChanged.connect(self._adjust)
        self.prefilter_upper_bound.setMinimum(
            self.prefilter_lower_bound.value())
        self.prefilter_upper_bound.setMaximum(10000)  # TODO: add proper value
        self.prefilter_upper_bound.setValue(0)  # TODO: add proper value

        prefilter_upper_bound_widget = QWidget()
        prefilter_upper_bound_widget.setContentsMargins(0, 0, 0, 0)
        prefilter_upper_bound_widget.setLayout(QHBoxLayout())
        prefilter_upper_bound_widget.layout().setContentsMargins(0, 0, 0, 0)
        prefilter_upper_bound_widget.layout().addWidget(
            self.prefilter_upper_bound_enable)
        prefilter_upper_bound_widget.layout().addWidget(
            self.prefilter_upper_bound)

        # Inlet selection ----------------------------------------------------------------------------------------------
        self.inlet_type = QComboBox()
        self.inlet_type.addItem("LSL stream")
        self.inlet_type.addItem("LSL file stream")
        self.inlet_type.addItem("LSL generator")
        self.inlet_type.addItem("Field trip buffer")

        self.lsl_stream_name = QComboBox()
        self.lsl_stream_name.addItem("NVX136_Data")
        self.lsl_stream_name.addItem("Mitsar")

        self.lsl_filename = PathEdit()
        dialog = QFileDialog(self, "Open")
        dialog.setFileMode(dialog.AnyFile)
        self.lsl_filename.setDialog(dialog)
        self.hostname_port = QLineEdit("localhost:1972")

        self.inlet_params = StackedDictWidget()
        self.inlet_params.setMaximumHeight(25)
        self.inlet_params.addWidget("LSL stream", self.lsl_stream_name)
        self.inlet_params.addWidget("LSL file stream", self.lsl_filename)
        self.inlet_params.addWidget("LSL generator", QWidget())
        self.inlet_params.addWidget("Field trip buffer", self.hostname_port)
        # TODO: LSL generator is not reflected in the exported file, even when selected.

        self.inlet_type.currentTextChanged.connect(
            self.inlet_params.setCurrentKey)

        self.inlet_config = QWidget()
        self.inlet_config.setContentsMargins(0, 0, 0, 0)
        inlet_layout = QHBoxLayout()
        inlet_layout.setContentsMargins(0, 0, 0, 0)
        inlet_layout.addWidget(self.inlet_type)
        inlet_layout.addWidget(self.inlet_params)
        self.inlet_config.setLayout(inlet_layout)

        # --------------------------------------------------------------------------------------------------------------
        self.name = QLineEdit("Experiment")
        self.dc = QCheckBox()

        self.plot_raw = QCheckBox()
        self.plot_raw.setChecked(True)
        self.plot_signals = QCheckBox()
        self.plot_signals.setChecked(True)

        self.discard_channels = QLineEdit()
        self.reference_sub = QLineEdit()
        self.show_photo_rectangle = QCheckBox()
        self.show_notch_filters = QCheckBox()

        self.reward_refractory_period = QDoubleSpinBox()
        self.reward_refractory_period.setRange(0.1, 10)
        self.reward_refractory_period.setValue(0.25)
        self.reward_refractory_period.setSuffix(" s")

        # Adding properties to the widget ------------------------------------------------------------------------------
        layout.addRow("Name", self.name)
        layout.addRow("Inlet", self.inlet_config)
        layout.addRow("Enable DC blocker", self.dc)
        layout.addRow("Prefilter band (lower bound)",
                      prefilter_lower_bound_widget)
        layout.addRow("Prefilter band (upper bound)",
                      prefilter_upper_bound_widget)
        layout.addRow("Plot raw", self.plot_raw)
        layout.addRow("Plot signals", self.plot_signals)
        layout.addRow("Discard channels", self.discard_channels)
        layout.addRow("Reference sub", self.reference_sub)
        layout.addRow("Show photo-sensor rectangle", self.show_photo_rectangle)
        layout.addRow("Show notch filters", self.show_notch_filters)
        layout.addRow("Reward refractory period",
                      self.reward_refractory_period)

    def updateModel(self, ex, /):
        ex.name = self.name.text()
        ex.inlet = self.inlet_type_export_values[self.inlet_type.currentText()]
        ex.lsl_stream_name = self.lsl_stream_name.currentText()
        ex.raw_data_path = self.lsl_filename.text()
        ex.hostname_port = self.hostname_port.text()
        ex.dc = self.dc.isChecked()

        if self.prefilter_lower_bound_enable.isChecked():
            prefilter_lower_bound = self.prefilter_lower_bound.value()
        else:
            prefilter_lower_bound = None

        if self.prefilter_upper_bound_enable.isChecked():
            prefilter_upper_bound = self.prefilter_upper_bound.value()
        else:
            prefilter_upper_bound = None

        ex.prefilter_band = (prefilter_lower_bound, prefilter_upper_bound)
        ex.plot_raw = self.plot_raw.isChecked()
        ex.plot_signals = self.plot_signals.isChecked()
        ex.discard_channels = self.discard_channels.text()
        ex.reference_sub = self.reference_sub.text()
        ex.show_photo_rectangle = self.show_photo_rectangle.isChecked()
        ex.show_notch_filters = self.show_notch_filters.isChecked()
        ex.reward_refractory_period = self.reward_refractory_period.value()

    def _adjust(self):
        if self.prefilter_lower_bound_enable.isChecked():
            self.prefilter_lower_bound.setEnabled(True)
            self.prefilter_upper_bound.setMinimum(
                self.prefilter_lower_bound.value())
        else:
            self.prefilter_lower_bound.setEnabled(False)
            self.prefilter_upper_bound.setMinimum(0)

        if self.prefilter_upper_bound_enable.isChecked():
            self.prefilter_upper_bound.setEnabled(True)
            self.prefilter_lower_bound.setMaximum(
                self.prefilter_upper_bound.value())
        else:
            self.prefilter_upper_bound.setEnabled(False)
            self.prefilter_lower_bound.setMaximum(
                10000)  # TODO: add proper value
Ejemplo n.º 10
0
class ToolBar(QToolBar):
    """Toolbar for VMS. Provides widget to setup frequency range and window
    width.
    """

    frequencyChanged = Signal(float, float)
    intervalChanged = Signal(float)

    def __init__(self):
        super().__init__()

        settings = QSettings("LSST.TS", "VMSGUI")

        self.setObjectName("VMSToolBar")

        self.addAction(self.style().standardIcon(QStyle.SP_MediaStop), "Stop")

        self.addWidget(QLabel("Frequency"))

        self.minFreq = QDoubleSpinBox()
        self.minFreq.setDecimals(1)
        self.minFreq.setRange(0, 10000)
        self.minFreq.setSingleStep(5)
        self.minFreq.setValue(float(settings.value("minFreq", 0)))
        self.minFreq.editingFinished.connect(self.minMaxChanged)
        self.addWidget(self.minFreq)

        self.addWidget(QLabel("-"))

        self.maxFreq = QDoubleSpinBox()
        self.maxFreq.setDecimals(1)
        self.maxFreq.setRange(0.1, 10000)
        self.maxFreq.setSingleStep(5)
        self.maxFreq.setValue(float(settings.value("maxFreq", 200)))
        self.maxFreq.editingFinished.connect(self.minMaxChanged)
        self.addWidget(self.maxFreq)

        self.addWidget(QLabel("Interval:"))

        self.interval = QDoubleSpinBox()
        self.interval.setDecimals(3)
        self.interval.setRange(0.01, 3600)
        self.interval.setSingleStep(0.1)
        self.interval.setValue(float(settings.value("interval", 50.0)))
        self.interval.editingFinished.connect(self.newInterval)
        self.addWidget(self.interval)

        self.frequencyChanged.emit(self.minFreq.value(), self.maxFreq.value())

    def storeSettings(self):
        """Store settings through QSettings."""
        settings = QSettings("LSST.TS", "VMSGUI")
        settings.setValue("minFreq", self.minFreq.value())
        settings.setValue("maxFreq", self.maxFreq.value())
        settings.setValue("interval", self.interval.value())

    @Slot()
    def minMaxChanged(self):
        self.frequencyChanged.emit(*self.getFrequencyRange())

    @Slot()
    def newInterval(self):
        self.intervalChanged.emit(self.interval.value())

    def getFrequencyRange(self):
        return (self.minFreq.value(), self.maxFreq.value())
Ejemplo n.º 11
0
class NifBatchTools(MainWindow):
    def __init__(self):
        super().__init__("HTools - NifBatchTools")
        log.info("Opening NifBatchTools window")

        self.source_folder = CONFIG.get("DEFAULT", "SourceFolder")
        self.keywords = list(
            map(lambda x: x.encode("ascii"),
                CONFIG.get("NIF", "keywords").replace(" ", "").split(",")))
        self.nif_files = set(
        )  # improve performance (better to check in a set rather than in a QListWidget
        self.ignored_nif_files = set(
        )  # improve performance (better to check in a set rather than in a QListWidget
        self.setSize(QSize(700, 600))
        self.processed_files = itertools.count()

        log.info("Source folder  : " + self.source_folder)
        log.info("Keywords       : " + str(self.keywords))

        self.init_ui()

    def init_ui(self):
        main_splitter = QSplitter(self, Qt.Horizontal)

        left_pane = QWidget(self)
        left_pane.setMaximumWidth(370)
        left_v_box = QVBoxLayout(self)
        left_pane.setLayout(left_v_box)

        right_pane = QWidget(self)
        right_v_box = QVBoxLayout(self)
        right_pane.setLayout(right_v_box)

        main_splitter.addWidget(left_pane)
        main_splitter.addWidget(right_pane)

        # ===== Details =====
        self.group_box_details = QuickyGui.create_group_box(self, "Details")

        nif_files_loaded = QuickyGui.create_label(self, ".nif files loaded")
        self.lcd_nif_files_loaded = QuickyGui.create_lcd(self)

        nif_files_ignored = QuickyGui.create_label(self, ".nif files ignored")
        self.lcd_nif_files_ignored = QuickyGui.create_lcd(self)

        self.nif_files_list_widget = NifList(self)
        self.ignored_nif_files_list_widget = NifList(self)
        self.update_nif_files()

        self.group_box_legends = QuickyGui.create_group_box(self, "Legends")
        instructions_4 = QuickyGui.create_label(
            self, "Green - File correctly processed\n")
        instructions_4.setStyleSheet(
            "QLabel { color : darkGreen; font-weight : bold }")
        instructions_5 = QuickyGui.create_label(self,
                                                "Blue - File is processing\n")
        instructions_5.setStyleSheet(
            "QLabel { color : darkBlue; font-weight : bold }")
        instructions_6 = QuickyGui.create_label(
            self, "Red - File ignored/with errors.")
        instructions_6.setStyleSheet(
            "QLabel { color : darkRed; font-weight : bold }")
        instructions_7 = QuickyGui.create_label(
            self, "Reasons : "
            "\n * Check log to see if there is an error concerning this file, or try to open it with NifSkope"
            "\n * Otherwise it couldn't find a NiTriShape block whose name is specified in provided keywords. It may be normal, if there is no body part. But if there is and you want this file to be processed by the tool, then you must add the corresponding NiTriShape block's name (use nikskope to find it) to the list of keywords, located in the .ini file, situated alongside the executable."
            " If you have Nikskope, you can open the file by double-clicking on in, in the list view, or from your explorer. Restart the tool to load the new .ini file."
        )
        instructions_7.setStyleSheet("QLabel { color : darkRed}")

        vbox = QVBoxLayout()
        vbox.setSpacing(5)
        vbox.addWidget(instructions_4)
        vbox.addWidget(instructions_5)
        vbox.addWidget(instructions_6)
        vbox.addWidget(instructions_7)

        self.group_box_legends.setLayout(vbox)

        vbox = QVBoxLayout(self)

        hbox = QHBoxLayout(self)
        hbox.addWidget(nif_files_loaded)
        hbox.addWidget(self.lcd_nif_files_loaded)

        vbox.addItem(hbox)
        vbox.addWidget(self.nif_files_list_widget)

        hbox = QHBoxLayout(self)
        hbox.addWidget(nif_files_ignored)
        hbox.addWidget(self.lcd_nif_files_ignored)
        vbox.addItem(hbox)

        vbox.addWidget(self.ignored_nif_files_list_widget)
        vbox.addWidget(self.group_box_legends)

        self.group_box_details.setLayout(vbox)
        right_v_box.addWidget(self.group_box_details)

        # ===== STEP 0 - Instructions =====
        self.group_box_instructions = QuickyGui.create_group_box(
            self, "Instructions")

        instructions_1 = QuickyGui.create_label(
            self,
            "I. By clicking on \"Scan Folder\", all .nif contained in this folder (subfolders and so on), will be added to the set of files to be processed. You can scan multiple folder, by clicking again. All files not already present will be added."
        )
        instructions_2 = QuickyGui.create_label(
            self,
            "II. Once your desired parameters are set, click on \"Apply\". Bewary, the process is quite slow (just opening the file is quite consuming somehow)"
        )

        vbox = QVBoxLayout()
        vbox.setSpacing(5)
        vbox.addWidget(instructions_1)
        vbox.addWidget(instructions_2)

        self.group_box_instructions.setLayout(vbox)
        left_v_box.addWidget(self.group_box_instructions)

        # ===== STEP I - Load Files =====
        self.group_box_load_files = QuickyGui.create_group_box(
            self, "STEP I - Load .nif files")

        button_load_files = QuickyGui.create_button(self, "Scan Folder",
                                                    self.action_load_files)
        button_clear_files = QuickyGui.create_button(self,
                                                     "Clear loaded files",
                                                     self.action_clear_files)

        hbox = QHBoxLayout()
        hbox.addWidget(button_load_files)
        hbox.addWidget(button_clear_files)

        self.group_box_load_files.setLayout(hbox)
        left_v_box.addWidget(self.group_box_load_files)

        # ===== STEP II - Set parameters =====
        self.group_box_parameters = QuickyGui.create_group_box(
            self, "STEP II - Set parameters")

        vbox = QVBoxLayout()

        # Glossiness
        label_glossiness = QuickyGui.create_label(self, "Glossiness")
        self.spin_box_glossiness = QDoubleSpinBox()
        self.spin_box_glossiness.setMinimum(0)
        self.spin_box_glossiness.setMaximum(1000)
        self.spin_box_glossiness.setValue(CONFIG.getfloat("NIF", "Glossiness"))
        log.info("Glossiness target : " +
                 str(self.spin_box_glossiness.value()))

        hbox = QHBoxLayout()
        hbox.addWidget(label_glossiness)
        hbox.addWidget(self.spin_box_glossiness)
        vbox.addItem(hbox)

        # Specular Strength
        label_specular_strength = QuickyGui.create_label(
            self, "Specular Strength")
        self.spin_box_specular_strength = QDoubleSpinBox()
        self.spin_box_specular_strength.setMinimum(0)
        self.spin_box_specular_strength.setMaximum(1000)
        self.spin_box_specular_strength.setValue(
            CONFIG.getfloat("NIF", "SpecularStrength"))
        log.info("Specular Strength target : " +
                 str(self.spin_box_specular_strength.value()))

        hbox = QHBoxLayout()
        hbox.addWidget(label_specular_strength)
        hbox.addWidget(self.spin_box_specular_strength)
        vbox.addItem(hbox)

        self.group_box_parameters.setLayout(vbox)
        left_v_box.addWidget(self.group_box_parameters)

        # ===== STEP III - Apply =====
        self.group_box_apply = QuickyGui.create_group_box(
            self, "STEP III - Apply")

        button_load_files = QuickyGui.create_button(self, "Apply",
                                                    self.action_apply)

        hbox = QHBoxLayout()
        hbox.addWidget(button_load_files)

        self.group_box_apply.setLayout(hbox)
        left_v_box.addWidget(self.group_box_apply)

        # ===== Finalizing =====
        self.progress_bar = QProgressBar(self)
        left_v_box.addWidget(self.progress_bar)

        left_v_box.setSpacing(10)
        self.mainLayout.addWidget(main_splitter)

    def toggle(self, value):
        self.group_box_parameters.setEnabled(value)
        self.group_box_load_files.setEnabled(value)
        self.group_box_apply.setEnabled(value)

    def update_nif_files(self, value=0):
        self.lcd_nif_files_loaded.display(self.nif_files_list_widget.count())
        self.lcd_nif_files_ignored.display(
            self.ignored_nif_files_list_widget.count())
        self.nif_files_list_widget.sortItems()
        self.ignored_nif_files_list_widget.sortItems()

    def finish_action(self):
        self.progress_bar.setMinimum(0)
        self.progress_bar.setMaximum(max(1,
                                         self.nif_files_list_widget.count()))
        self.progress_bar.setValue(self.nif_files_list_widget.count())
        self.toggle(True)
        log.info("Done !")

    def finish_load_action(self, result):
        self.finish_action()
        QMessageBox.information(
            self, "Results",
            "Done !\n\n" + str(self.nif_files_list_widget.count()) +
            " .nif file(s) loaded.\n" + str(result) + " .nif files ignored.")

    def start_apply_action(self, index):
        item = self.nif_files_list_widget.item(index)
        item.setForeground(Qt.blue)

    def result_apply_action(self, index, result):
        item = self.nif_files_list_widget.item(index)
        if result:
            item.setForeground(Qt.darkGreen)
        else:
            item.setForeground(Qt.darkRed)
        self.progress_bar.setValue(next(self.processed_files) + 1)

    def finish_apply_action(self):
        if self.progress_bar.value() == self.nif_files_list_widget.count():
            self.finish_action()
            QMessageBox.information(
                self, "Results", "Done !\n\n" +
                str(self.progress_bar.value()) + " .nif file(s) loaded.\n")

    def action_clear_files(self):
        log.info("Clearing loaded .nif files ...")
        self.nif_files_list_widget.clear()
        self.ignored_nif_files_list_widget.clear()
        self.nif_files.clear()
        self.ignored_nif_files.clear()
        self.update_nif_files()
        self.progress_bar.reset()

    def action_load_files(self):
        log.info("Loading .nif files ...")
        self.toggle(False)
        self.progress_bar.setMinimum(0)
        self.progress_bar.setMaximum(0)

        file_dialog = QFileDialog()
        file_dialog.setFileMode(QFileDialog.DirectoryOnly)
        file_dialog.setDirectory(self.source_folder)

        if file_dialog.exec_():
            scan_dirs = file_dialog.selectedFiles()
            if len(scan_dirs) >= 1:
                self.source_folder = scan_dirs[0]
            else:
                self.source_folder = file_dialog.directory()

        if self.source_folder:
            log.info("Scanning directory : " + self.source_folder)
            CONFIG.set("DEFAULT", "SourceFolder", self.source_folder),
            save_config()

        worker = Worker(self.load_files)
        worker.signals.progress.connect(self.update_nif_files)
        worker.signals.result.connect(self.finish_load_action)

        QThreadPool.globalInstance().start(worker)

    def load_files(self, progress_callback):
        """
        Traverse folder to find .nif files
        """
        ignored_files = 0
        for root, dirs, files in os.walk(self.source_folder):
            for file in files:
                path = root + "/" + file
                if file.endswith(
                        ".nif"
                ) and path not in self.nif_files and path not in self.ignored_nif_files:
                    stream = open(path, "rb")
                    data = NifFormat.Data()
                    success = False
                    add_to_ignored_list = False
                    try:
                        data.inspect(stream)
                        if "NiNode".encode(
                                'ascii') == data.header.block_types[0]:
                            if any(keyword in self.keywords
                                   for keyword in data.header.strings):
                                success = True
                            else:
                                add_to_ignored_list = True

                    except ValueError:
                        log.exception("[" + file +
                                      "] - Too Big to inspect - skipping")
                    except Exception:
                        log.exception("[" + file + "] - Error")
                    finally:
                        if success:
                            self.nif_files.add(path)
                            self.nif_files_list_widget.addItem(path)
                        elif add_to_ignored_list:
                            item = QListWidgetItem(
                                path, self.ignored_nif_files_list_widget)
                            item.setForeground(Qt.darkRed)
                            ignored_files += 1
                    progress_callback.emit(0)  # emit parameter is not used
        return ignored_files

    def action_apply(self):
        """
        Apply parameters to relevant .nif files
        """
        if self.nif_files_list_widget.count() == 0:
            QMessageBox.warning(self, "No .nif files loaded",
                                "Don't forget to load .nif files !")
            return

        if self.nif_files_list_widget.count() >= get_config().getint(
                "DEFAULT", "softLimit"):
            box = QMessageBox()
            box.setIcon(QMessageBox.Question)
            box.setWindowTitle('Are you sure ?')
            box.setText(
                "The tool may struggle with more than 100 .nif files at once. We advise you to process small batches.\n\nAre you sure you wish to continue ?"
            )
            box.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
            buttonY = box.button(QMessageBox.Yes)
            buttonY.setText('Yes')
            buttonN = box.button(QMessageBox.No)
            buttonN.setText('No')
            box.exec_()

            if box.clickedButton() == buttonN:
                return

        log.info("Applying parameters to " +
                 str(self.nif_files_list_widget.count()) + " files ...")
        self.toggle(False)
        self.progress_bar.setValue(0)
        self.processed_files = itertools.count()

        CONFIG.set("NIF", "Glossiness", str(self.spin_box_glossiness.value())),
        CONFIG.set("NIF", "SpecularStrength",
                   str(self.spin_box_specular_strength.value())),
        save_config()

        QMessageBox.warning(
            self, "Attention !",
            "The process is quite slow.\n\nThe gui will be mostly unresponsive to your input. Don't close the application, unless the completion pourcentage has not been updated in a long time (several minutes).\nIt took me 13 minutes to process 100 files for example."
        )

        #for indices in chunkify(range(self.nif_files_list_widget.count()), QThreadPool.globalInstance().maxThreadCount()-1):
        QThreadPool.globalInstance().setExpiryTimeout(-1)
        for index in range(self.nif_files_list_widget.count()):
            item = self.nif_files_list_widget.item(index)
            worker = NifProcessWorker(
                index=index,
                path=item.text(),
                keywords=self.keywords,
                glossiness=self.spin_box_glossiness.value(),
                specular_strength=self.spin_box_specular_strength.value())
            worker.signals.start.connect(self.start_apply_action)
            worker.signals.result.connect(self.result_apply_action)
            worker.signals.finished.connect(self.finish_apply_action)
            QThreadPool.globalInstance().start(worker)
Ejemplo n.º 12
0
# equation = input('Enter polynomial function:')
# equation = '3*x^2-2*x+10'
equation = equationinput.toPlainText()
print('equation is', equation)

# def getvalue(variablename, boxname):
# variablename = boxname.value()
# return (0)

# min = input ("Enter minimum value for x:")
# min = float(min)
# min = 0
# minbutton.clicked.connect(getvalue(min,mininput))
# minbutton.clicked.connect()
min = mininput.value()
print("minimum value is", min)

# max = input ("Enter maximum value for x:")
# max = float(max)
# max = 9
max = maxinput.value()
print("maximum value is", max)

# step = input ("Enter step for function:")
# step = float(step)
# step = 1
step = stepinput.value()
print("step value is", step)

Ejemplo n.º 13
0
class NNResolverSettingWidget(QDialog):
    def __init__(self, parent=None, filename=None, group=None):
        super().__init__(parent=parent, f=Qt.Window)
        self.setWindowTitle(self.tr("NN Resolver Setting"))
        if filename is not None:
            self.setting_file = QSettings(filename, QSettings.Format.IniFormat)
            if group is not None:
                self.setting_file.beginGroup(group)
        else:
            self.setting_file = None
        self.setAttribute(Qt.WA_StyledBackground, True)
        self.initialize_ui()

    def initialize_ui(self):
        self.main_layout = QGridLayout(self)
        self.device_label = QLabel(self.tr("Device"))
        self.device_label.setToolTip(
            self.
            tr("The neural netowrk framwork, pytorch, also can use the GPU of Nvidia to do calculations."
               ))
        self.device_combo_box = QComboBox()
        self.device_combo_box.addItem("cpu")
        if torch.cuda.is_available():
            self.device_combo_box.addItem("cuda")
        self.main_layout.addWidget(self.device_label, 0, 0)
        self.main_layout.addWidget(self.device_combo_box, 0, 1)

        self.distance_label = QLabel(self.tr("Distance (Loss) Function"))
        self.distance_label.setToolTip(
            self.
            tr("It's the function to calculate the difference (on the contrary, similarity) between two samples."
               ))
        self.distance_combo_box = QComboBox()
        self.distance_combo_box.addItems(built_in_distances)
        # self.distance_combo_box.setCurrentText("log10MSE")
        self.distance_combo_box.currentTextChanged.connect(
            self.on_distance_changed)
        self.main_layout.addWidget(self.distance_label, 1, 0)
        self.main_layout.addWidget(self.distance_combo_box, 1, 1)

        self.min_niter_label = QLabel(self.tr("Minimum N<sub>iteration</sub>"))
        self.min_niter_label.setToolTip(
            self.tr("Minimum number of iterations to perform"))
        self.min_niter_input = QSpinBox()
        self.min_niter_input.setRange(10, 10000)
        self.min_niter_input.setValue(2000)
        self.main_layout.addWidget(self.min_niter_label, 2, 0)
        self.main_layout.addWidget(self.min_niter_input, 2, 1)

        self.max_niter_label = QLabel(self.tr("Maximum N<sub>iteration</sub>"))
        self.max_niter_label.setToolTip(
            self.tr("Maximum number of iterations to perform"))
        self.max_niter_input = QSpinBox()
        self.max_niter_input.setRange(100, 100000)
        self.max_niter_input.setValue(5000)
        self.main_layout.addWidget(self.max_niter_label, 3, 0)
        self.main_layout.addWidget(self.max_niter_input, 3, 1)

        self.tol_label = QLabel(self.tr("-lg(loss<sub>tolerance</sub>)"))
        self.tol_label.setToolTip(
            self.
            tr("Controls the tolerance of the loss function for termination."))
        self.tol_input = QSpinBox()
        self.tol_input.setRange(1, 100)
        self.tol_input.setValue(10)
        self.main_layout.addWidget(self.tol_label, 4, 0)
        self.main_layout.addWidget(self.tol_input, 4, 1)

        self.ftol_label = QLabel(self.tr("-lg(δ<sub>loss</sub>)"))
        self.ftol_label.setToolTip(
            self.
            tr("Controls the precision goal for the value of loss function in the stopping criterion."
               ))
        self.ftol_input = QSpinBox()
        self.ftol_input.setRange(1, 100)
        self.ftol_input.setValue(10)
        self.main_layout.addWidget(self.ftol_label, 5, 0)
        self.main_layout.addWidget(self.ftol_input, 5, 1)

        self.lr_label = QLabel(self.tr("Learning Rate (x10<sup>-3</sup>)"))
        self.lr_label.setToolTip(
            self.
            tr("The learning rate of the neural network to update its weights from gradient."
               ))
        self.lr_input = QDoubleSpinBox()
        self.lr_input.setDecimals(3)
        self.lr_input.setRange(0.001, 1000)
        self.lr_input.setValue(15)
        self.main_layout.addWidget(self.lr_label, 6, 0)
        self.main_layout.addWidget(self.lr_input, 6, 1)

        self.eps_label = QLabel(self.tr("-lg(δ<sub>eps</sub>)"))
        self.eps_label.setToolTip(
            self.
            tr("Controls the step size used for numerical approximation of the jacobian"
               ))
        self.eps_input = QSpinBox()
        self.eps_input.setRange(1, 100)
        self.eps_input.setValue(8)
        self.main_layout.addWidget(self.eps_label, 7, 0)
        self.main_layout.addWidget(self.eps_input, 7, 1)

    def on_distance_changed(self, distance: str):
        if distance == "log10MSE":
            self.tol_label.setText(self.tr("-loss<sub>tolerance</sub>"))
        else:
            self.tol_label.setText(self.tr("-lg(loss<sub>tolerance</sub>)"))

    @property
    def setting(self):
        devices = ["cpu", "cuda"]
        device = devices[self.device_combo_box.currentIndex()]
        distance = self.distance_combo_box.currentText()
        min_niter = self.min_niter_input.value()
        max_niter = self.max_niter_input.value()
        # when using Lg(MSE) distance
        tol = -self.tol_input.value() if distance == "log10MSE" else 10**(
            -self.tol_input.value())
        ftol = 10**(-self.ftol_input.value())
        lr = self.lr_input.value() / 1000.0
        eps = 10**(-self.eps_input.value())

        setting = NNResolverSetting(device=device,
                                    distance=distance,
                                    min_niter=min_niter,
                                    max_niter=max_niter,
                                    tol=tol,
                                    ftol=ftol,
                                    lr=lr,
                                    eps=eps)
        return setting

    @setting.setter
    def setting(self, setting: NNResolverSetting):
        self.device_combo_box.setCurrentText(setting.device)
        self.distance_combo_box.setCurrentText(setting.distance)
        self.min_niter_input.setValue(setting.min_niter)
        self.max_niter_input.setValue(setting.max_niter)
        if setting.distance == "log10MSE":
            self.tol_input.setValue(-setting.tol)
        else:
            self.tol_input.setValue(-np.log10(setting.tol))
        self.ftol_input.setValue(-np.log10(setting.ftol))
        self.lr_input.setValue(setting.lr * 1000.0)
        self.eps_input.setValue(-np.log10(setting.eps))

    def save(self):
        if self.setting_file is not None:
            setting_bytes = pickle.dumps(self.setting)
            self.setting_file.setValue("nn_resolver_setting", setting_bytes)

    def restore(self):
        if self.setting_file is not None:
            setting_bytes = self.setting_file.value("nn_resolver_setting",
                                                    defaultValue=None)
            if setting_bytes is not None:
                setting = pickle.loads(setting_bytes)
                self.setting = setting
        else:
            self.setting = NNResolverSetting()
Ejemplo n.º 14
0
class SliderSpinBox(QWidget):

    valueChanged = Signal(float)

    def __init__(self, parent=None, *args, **kwargs):
        super(SliderSpinBox, self).__init__(parent=parent, *args, **kwargs)

        self._outerLayout = QHBoxLayout(self)
        self._outerLayout.setSpacing(0)
        self._outerLayout.setMargin(0)

        self._slider = Slider(self)
        self._slider.setOrientation(Qt.Horizontal)
        self._spinBox = QDoubleSpinBox(self)
        self._labelMinValue = QLabel(self)
        self._labelMaxValue = QLabel(self)
        self._labelTitle = QLabel(self)

        self._outerLayout.addWidget(self._labelMinValue)
        self._outerLayout.addWidget(self._slider)
        self._outerLayout.addWidget(self._labelMaxValue)
        self._outerLayout.addWidget(self._spinBox)
        self._outerLayout.addWidget(self._labelTitle)

        self.setMinimum(self._slider.minimum())
        self.setMaximum(self._slider.maximum())
        self._spinBox.setSingleStep(self._slider.getRange()/10.0)
        self._connect()

    def _connect(self):
        self._slider.signalValueChanged.connect(self._on_slider_value_changed)
        self._spinBox.valueChanged.connect(self._on_spin_box_value_changed)
        self._spinBox.valueChanged.connect(self.valueChanged)

    @Slot(float)
    def _on_slider_value_changed(self, value):
        if abs(self._spinBox.value() - value) > sys.float_info.epsilon:
            self._spinBox.setValue(value)

    @Slot(float)
    def _on_spin_box_value_changed(self, value):
        if abs(self._slider.value() - value) > sys.float_info.epsilon:
            self._slider.setValue(value)

    def setValue(self, value):
        self._on_spin_box_value_changed(value)

    def setMinimum(self, value):
        self._slider.setMinimum(value)
        self._spinBox.setMinimum(value)
        self._labelMinValue.setText(str(value))
        self._spinBox.setSingleStep(self._slider.getRange()/10.0)

    def setMaximum(self, value):
        self._slider.setMaximum(value)
        self._spinBox.setMaximum(value)
        self._labelMaxValue.setText(str(value))
        self._spinBox.setSingleStep(self._slider.getRange()/10.0)

    def setRange(self, values):
        self.setMinimum(values[0])
        self.setMaximum(values[1])

    def setTitle(self, value):
        self._labelTitle.setText(value)

    def setSliderFactor(self, value):
        self._slider.setFactor(value)
Ejemplo n.º 15
0
class GeoWidget(QWidget):
    coordinate_changed = Signal(name="coordinateChanged")

    def __init__(self, parent=None):
        super().__init__(parent)
        self._coordinate = QGeoCoordinate(0, 0)
        # The coordinate bounds below only bound England, they can be expanded if more countries are added
        self._lat_spinbox = QDoubleSpinBox(minimum=49.0, maximum=56.0)
        self._lng_spinbox = QDoubleSpinBox(minimum=-8, maximum=2)
        self.map_button = QToolButton(text="Map",
                                      clicked=self.handle_clicked_map)
        self.post_button = QToolButton(text='Postcode',
                                       clicked=self.handle_clicked_post)
        self.map_view = MapDialog(self)

        lay = QHBoxLayout(self)
        lay.addWidget(QLabel("Latitude:"))
        lay.addWidget(self._lat_spinbox)
        lay.addWidget(QLabel("Longitude:"))
        lay.addWidget(self._lng_spinbox)
        lay.addWidget(self.map_button)
        lay.addWidget(self.post_button)

    @Property(QGeoCoordinate, notify=coordinate_changed)
    def coordinate(self):
        return self._coordinate

    @coordinate.setter
    def coordinate(self, coordinate):
        if self.coordinate == coordinate:
            return
        self._coordinate = coordinate
        self.coordinate_changed.emit()

    def handle_value_changed(self):
        coordinate = QGeoCoordinate(self._lat_spinbox.value(),
                                    self._lng_spinbox.value())
        self.coordinate = coordinate

    @Slot(QGeoCoordinate)
    def update_from_map(self, coordinate):
        self.coordinate = coordinate
        self._lat_spinbox.setValue(self.coordinate.latitude())
        self._lng_spinbox.setValue(self.coordinate.longitude())

    def handle_clicked_map(self):
        self.map_view.exec_()

    def handle_clicked_post(self):

        api = pst.Api()
        valid = False
        retry = False
        while not valid:
            if retry:
                pcode, ok = QInputDialog.getText(
                    self, 'Postcode', 'Postcode Invalid, please try again')
            else:
                pcode, ok = QInputDialog.getText(self, 'Postcode', 'Postcode:')
                retry = True
            if not ok:
                return
            valid = api.is_postcode_valid(pcode)
        if valid:
            data = api.get_postcode(pcode)
            self.coordinate = QGeoCoordinate(data['result']['latitude'],
                                             data['result']['longitude'])
            self._lat_spinbox.setValue(self.coordinate.latitude())
            self._lng_spinbox.setValue(self.coordinate.longitude())
Ejemplo n.º 16
0
class App(QMainWindow):
    def __init__(self):
        super().__init__()
        self.init_ui()
        self.attach_event()
        self.setAcceptDrops(True)
        
    def init_ui(self):
        # Define & Configure Components
        normal_button_size = QSize(80, 24)
        icon_button_size = QSize(24, 24)
        icon_size = QSize(18, 18)
        
        self.central_widget = QWidget()
        self.central_layout = QGridLayout()
        self.central_widget.setLayout(self.central_layout)

        self.tab_group_widget = QTabWidget()
        self.tab_group_widget.setMinimumSize(400, 0)
        self.tab_group_widget.setFixedHeight(150)
        self.tab1_name = '스폰서 변환'
        self.tab2_name = '싱크 조절(초)'
        self.tab3_name = '싱크 조절(%)'

        self.tab_page_1 = QWidget()
        self.tab_grid_1 = QGridLayout()
        self.tab1_search_label = QLabel('검색 텍스트')
        self.tab1_search = QLineEdit()
        self.tab1_sponsor = QWidget()
        self.tab1_sponsor_layout = QHBoxLayout()
        self.tab1_sponsor_layout.setContentsMargins(0, 0, 0, 0)
        self.tab1_sponsor_label = QLabel('스폰서 영상 길이')
        self.tab1_sponsor_value = QDoubleSpinBox()
        self.tab1_sponsor_value.setFixedWidth(60)
        self.tab1_sponsor_value.setMinimum(-1000000000)
        self.tab1_sponsor_value.setValue(10)
        self.tab1_offset = QWidget()
        self.tab1_offset_layout = QHBoxLayout()
        self.tab1_offset_layout.setContentsMargins(0, 0, 0, 0)
        self.tab1_offset_label = QLabel('라인 오프셋')
        self.tab1_offset_value = QSpinBox()
        self.tab1_offset_value.setMinimum(-1000000000)
        self.tab1_offset_value.setValue(2)
        self.tab1_offset_value.setFixedWidth(50)
        self.tab1_ignore = QWidget()
        self.tab1_ignore_layout = QHBoxLayout()
        self.tab1_ignore_layout.setContentsMargins(0, 0, 0, 0)
        self.tab1_ignore_label1 = QLabel('시작부터')
        self.tab1_ignore_value = QSpinBox()
        self.tab1_ignore_value.setFixedWidth(50)
        self.tab1_ignore_value.setValue(5)
        self.tab1_ignore_label2 = QLabel('줄 ')
        self.tab1_ignore_sec = QSpinBox()
        self.tab1_ignore_sec.setFixedWidth(60)
        self.tab1_ignore_sec.setMaximum(1000)
        self.tab1_ignore_sec.setValue(90)
        self.tab1_ignore_label3 = QLabel('초 무시하기')
        self.tab1_add_button = QPushButton('추가하기')

        self.tab_page_2 = QWidget()
        self.tab_grid_2 = QGridLayout()
        self.tab2_shift = QWidget()
        self.tab2_shift_layout = QHBoxLayout()
        self.tab2_shift_layout.setContentsMargins(0, 0, 0, 0)
        self.tab2_shift_label1 = QLabel('자막 싱크')
        self.tab2_shift_value = QDoubleSpinBox()
        self.tab2_shift_value.setFixedWidth(60)
        self.tab2_shift_label2 = QLabel('초 ')
        self.tab2_slow_radio = QRadioButton('느리게')
        self.tab2_slow_radio.setChecked(True)
        self.tab2_fast_radio = QRadioButton('빠르게')
        self.tab2_add_button = QPushButton('추가하기')

        self.tab_page_3 = QWidget()
        self.tab_grid_3 = QGridLayout()
        self.tab3_speed_label1 = QLabel('자막 싱크')
        self.tab3_speed_value = QSpinBox()
        self.tab3_speed_value.setFixedWidth(70)
        self.tab3_speed_value.setRange(1, 1000)
        self.tab3_speed_value.setValue(100)
        self.tab3_speed_label2 = QLabel('%')
        self.tab3_add_button = QPushButton('추가하기')

        self.que_label = QLabel('작업 목록')
        self.que_label.setFixedHeight(24)
        self.que_widget = QWidget()
        self.que_widget.setFixedHeight(114)
        self.que_layout = QGridLayout()
        self.que_layout.setContentsMargins(0, 0, 0, 0)
        self.que_list = QTreeWidget()
        self.que_list.setHeaderLabels(['작업', '옵션'])
        self.que_delete_button = QPushButton(QIcon(':/remove.png'), '')
        self.que_delete_button.setFixedSize(icon_button_size)
        self.que_delete_button.setIconSize(icon_size)
        self.que_delete_button.setToolTip('목록 삭제')
        self.que_up_button = QPushButton(QIcon(':/up.png'), '')
        self.que_up_button.setIconSize(icon_size)
        self.que_up_button.setFixedSize(icon_button_size)
        self.que_up_button.setToolTip('위로')
        self.que_down_button = QPushButton(QIcon(':/down.png'), '')
        self.que_down_button.setIconSize(icon_size)
        self.que_down_button.setFixedSize(icon_button_size)
        self.que_down_button.setToolTip('아래로')
        self.que_clear_button = QPushButton(QIcon(':/clear.png'), '')
        self.que_clear_button.setIconSize(icon_size)
        self.que_clear_button.setFixedSize(icon_button_size)
        self.que_clear_button.setToolTip('비우기')

        self.file_label = QLabel('파일 목록')
        self.file_label.setFixedHeight(24)
        self.file_widget = QWidget()
        self.file_layout = QGridLayout()
        self.file_layout.setContentsMargins(0, 0, 0, 0)
        self.file_list = QTreeWidget()
        self.file_list.setAcceptDrops(True)
        self.file_list.setHeaderLabels(['이름', '경로'])
        self.file_file_open = QPushButton(QIcon(':/file.png'), '')
        self.file_file_open.setFixedSize(icon_button_size)
        self.file_file_open.setIconSize(icon_size)
        self.file_file_open.setToolTip('파일 열기')
        self.file_dir_open = QPushButton(QIcon(':/folder.png'), '')
        self.file_dir_open.setFixedSize(icon_button_size)
        self.file_dir_open.setIconSize(icon_size)
        self.file_dir_open.setToolTip('폴더 열기')
        self.file_delete = QPushButton(QIcon(':/remove.png'), '')
        self.file_delete.setFixedSize(icon_button_size)
        self.file_delete.setIconSize(icon_size)
        self.file_delete.setToolTip('목록 삭제')
        self.file_clear = QPushButton(QIcon(':/clear.png'), '')
        self.file_clear.setFixedSize(icon_button_size)
        self.file_clear.setIconSize(icon_size)
        self.file_clear.setToolTip('비우기')
        self.file_encode = QPushButton(QIcon(':/encode.png'), '')
        self.file_encode.setFixedSize(icon_button_size)
        self.file_encode.setIconSize(icon_size)
        self.file_encode.setToolTip('인코딩 설정')

        self.save_widget = QGroupBox('저장 옵션')
        self.save_widget.setMinimumSize(400, 0)
        self.save_widget.setFixedHeight(82)
        self.save_layout = QGridLayout()
        self.save_orig_radio = QRadioButton('원본 위치에 저장')
        self.save_orig_radio.setChecked(True)
        self.save_strip = QCheckBox('싱크 꼬임 무시')
        self.save_strip.setToolTip('싱크 꼬임을 무시하고 모든 자막을 보존합니다.')
        self.save_dir_radio = QRadioButton('다른 위치에 저장')
        self.save_dir_line = QLineEdit()
        self.save_dir_find = QPushButton('...')
        self.save_dir_find.setFixedWidth(40)

        self.ok_button = QPushButton('적용')
        self.ok_button.setFixedSize(normal_button_size)
        self.cancel_button = QPushButton('취소')
        self.cancel_button.setFixedSize(normal_button_size)

        # Display GUI Components
        self.central_layout.addWidget(self.tab_group_widget, 0, 0, 1, 3)
        self.central_layout.addWidget(self.que_label, 1, 0, 1, 3)
        self.central_layout.addWidget(self.que_widget, 2, 0, 1, 3)
        self.central_layout.addWidget(self.file_label, 3, 0, 1, 3)
        self.central_layout.addWidget(self.file_widget, 4, 0, 1, 3)
        self.central_layout.addWidget(self.save_widget, 5, 0, 1, 3)
        self.central_layout.addWidget(self.ok_button, 6, 1, 1, 1)
        self.central_layout.addWidget(self.cancel_button, 6, 2, 1, 1)

        self.tab_group_widget.addTab(self.tab_page_1, QIcon(), self.tab1_name)
        self.tab_group_widget.addTab(self.tab_page_2, QIcon(), self.tab2_name)
        self.tab_group_widget.addTab(self.tab_page_3, QIcon(), self.tab3_name)

        self.tab_page_1.setLayout(self.tab_grid_1)
        self.tab_grid_1.addWidget(self.tab1_search_label, 0, 0, 1, 1)
        self.tab_grid_1.addWidget(self.tab1_search, 0, 1, 1, 2)
        self.tab_grid_1.addWidget(self.tab1_sponsor, 1, 1, 1, 1)
        self.tab_grid_1.addWidget(self.tab1_offset, 1, 2, 1, 1)
        self.tab_grid_1.addWidget(self.tab1_ignore, 2, 1, 1, 2)
        self.tab_grid_1.addWidget(self.tab1_add_button, 3, 0, 1, 3)
        self.tab1_sponsor.setLayout(self.tab1_sponsor_layout)
        self.tab1_sponsor_layout.addWidget(self.tab1_sponsor_label)
        self.tab1_sponsor_layout.addWidget(self.tab1_sponsor_value)
        self.tab1_sponsor_layout.addStretch(1)
        self.tab1_offset.setLayout(self.tab1_offset_layout)
        self.tab1_offset_layout.addWidget(self.tab1_offset_label)
        self.tab1_offset_layout.addWidget(self.tab1_offset_value)
        self.tab1_offset_layout.addStretch(1)
        self.tab1_ignore.setLayout(self.tab1_ignore_layout)
        self.tab1_ignore_layout.addWidget(self.tab1_ignore_label1)
        self.tab1_ignore_layout.addWidget(self.tab1_ignore_value)
        self.tab1_ignore_layout.addWidget(self.tab1_ignore_label2)
        self.tab1_ignore_layout.addWidget(self.tab1_ignore_sec)
        self.tab1_ignore_layout.addWidget(self.tab1_ignore_label3)
        self.tab1_ignore_layout.addStretch(1)

        self.tab_page_2.setLayout(self.tab_grid_2)
        self.tab_grid_2.setRowStretch(0, 1)
        self.tab_grid_2.addWidget(self.tab2_shift, 1, 0, 2, 1)
        self.tab_grid_2.addWidget(self.tab2_slow_radio, 1, 1, 1, 1)
        self.tab_grid_2.addWidget(self.tab2_fast_radio, 2, 1, 1, 1)
        self.tab_grid_2.setColumnStretch(2, 1)
        self.tab_grid_2.setRowStretch(3, 1)
        self.tab_grid_2.addWidget(self.tab2_add_button, 4, 0, 1, 3)
        self.tab2_shift.setLayout(self.tab2_shift_layout)
        self.tab2_shift_layout.addWidget(self.tab2_shift_label1)
        self.tab2_shift_layout.addWidget(self.tab2_shift_value)
        self.tab2_shift_layout.addWidget(self.tab2_shift_label2)

        self.tab_page_3.setLayout(self.tab_grid_3)
        self.tab_grid_3.setRowStretch(0, 1)
        self.tab_grid_3.addWidget(self.tab3_speed_label1, 1, 0, 1, 1)
        self.tab_grid_3.addWidget(self.tab3_speed_value, 1, 1, 1, 1)
        self.tab_grid_3.addWidget(self.tab3_speed_label2, 1, 2, 1, 1)
        self.tab_grid_3.setColumnStretch(3, 1)
        self.tab_grid_3.setRowStretch(2, 1)
        self.tab_grid_3.addWidget(self.tab3_add_button, 3, 0, 1, 4)

        self.que_widget.setLayout(self.que_layout)
        self.que_layout.addWidget(self.que_list, 0, 0, 4, 1)
        self.que_layout.addWidget(self.que_delete_button, 0, 1, 1, 1)
        self.que_layout.addWidget(self.que_up_button, 1, 1, 1, 1)
        self.que_layout.addWidget(self.que_down_button, 2, 1, 1, 1)
        self.que_layout.addWidget(self.que_clear_button, 3, 1, 1, 1)

        self.file_widget.setLayout(self.file_layout)
        self.file_layout.addWidget(self.file_list, 0, 0, 6, 1)
        self.file_layout.addWidget(self.file_file_open, 0, 1, 1, 1)
        self.file_layout.addWidget(self.file_dir_open, 1, 1, 1, 1)
        self.file_layout.addWidget(self.file_delete, 2, 1, 1, 1)
        self.file_layout.addWidget(self.file_clear, 3, 1, 1, 1)
        self.file_layout.addWidget(self.file_encode, 5, 1, 1, 1)

        self.save_widget.setLayout(self.save_layout)
        self.save_layout.addWidget(self.save_orig_radio, 0, 0, 1, 1)
        self.save_layout.setColumnStretch(1, 1)
        self.save_layout.addWidget(self.save_strip, 0, 2, 1, 2)
        self.save_layout.addWidget(self.save_dir_radio, 1, 0, 1, 1)
        self.save_layout.addWidget(self.save_dir_line, 1, 1, 1, 2)
        self.save_layout.addWidget(self.save_dir_find, 1, 3, 1, 1)

        self.setWindowTitle('Batch SAMI Sync v0.2')
        self.setCentralWidget(self.central_widget)
        self.adjustSize()

    def attach_event(self):
        # Default encoding hack
        self.encoding = '자동'

        # Define and Connect event handlers
        def tab1_add():
            sponsor_text = self.tab1_search.text()
            sponsor_time = self.tab1_sponsor_value.value()
            line_offset = self.tab1_offset_value.value()
            line_ignore = self.tab1_ignore_value.value()
            time_ignore = self.tab1_ignore_sec.value()
            data = [1, sponsor_time, sponsor_text, line_offset, line_ignore, time_ignore]
            item = QTreeWidgetItem(self.que_list, [self.tab1_name, '스폰서 영상 시간 : ' + str(sponsor_time) + '초, 오프셋 : ' + str(line_offset) + '줄, 시작부터 ' + str(line_ignore) + '번째 줄, ' + str(time_ignore) + '초 무시 - 검색어 : ' + sponsor_text])
            item.setData(2, 2, data)

        def tab2_add():
            shift_time = self.tab2_shift_value.value()
            shift_direction = self.tab2_fast_radio.isChecked()
            direction_text = '빠르게' if shift_direction else '느리게'
            data = [2, shift_time, shift_direction]
            item = QTreeWidgetItem(self.que_list, [self.tab2_name, '자막 싱크 ' + str(shift_time) + '초 ' + direction_text])
            item.setData(2, 2, data)

        def tab3_add():
            speed_rate = self.tab3_speed_value.value()
            data = [3, speed_rate]
            item = QTreeWidgetItem(self.que_list, [self.tab3_name, '자막 속도 ' + str(speed_rate) + '%'])
            item.setData(2, 2, data)

        def file_open():
            selected = QFileDialog.getOpenFileNames(self, "자막 파일 선택", "", "SAMI Files (*.smi);;All Files (*)")
            for file in selected[0]:
                name = ntpath.basename(file)
                Utils.insert_list(self.file_list, name, file)

        def dir_open():
            selected = QFileDialog.getExistingDirectory(self, "자막 폴더 선택")
            for paths, subdirs, files in os.walk(selected):
                for file in files:
                    if fnmatch(file, '*.smi'):
                        name = ntpath.basename(file)
                        Utils.insert_list(self.file_list, name, file)

        def open_encode_dialog():
            self.dialog = QInputDialog(self)
            self.dialog.setWindowTitle('인코딩 설정')
            self.dialog.setLabelText('텍스트 인코딩 설정')
            self.dialog.setComboBoxItems(['자동', 'EUC-KR', 'UTF-8', 'UTF-16LE', 'UTF-16BE', '직접 입력'])
            self.dialog.show()

            self.dialog.textValueChanged.connect(type_encode)
            self.dialog.textValueSelected.connect(set_encode)

        def type_encode(text):
            if text == '직접 입력':
                self.dialog.setComboBoxItems([])
                self.dialog.setComboBoxEditable(True)

        def set_encode(text):
            self.encoding = text

        def save_dir():
            selected = QFileDialog.getExistingDirectory(self, "저장 위치 선택")
            self.save_dir_line.setText(selected)

        def apply():
            self.ok_button.setEnabled(False)
            ques = Utils.read_list(self.que_list, False)
            files = Utils.read_list(self.file_list, False)
            strip = False if self.save_strip.isChecked() else True
            log = []
            for file in files:
                try:
                    text = Utils.launch_que(file[1], ques, self.encoding, strip)
                    if len(text):
                        if self.save_orig_radio.isChecked():
                            savepath = file[1]
                        else:
                            savepath = self.save_dir_line.text() + '/' + file[0]
                        Utils.save_file(savepath, text)
                except Exception as e:
                    log.append(file[0] + ' 처리 오류 : ' + str(e))
            if log:
                ScrollMessageBox(QMessageBox.Warning, 'Batch SAMI Sync', "\n".join(log))

            else:
                QMessageBox.information(self, 'Batch SAMI Sync', '변환 완료!')
            self.ok_button.setEnabled(True)

        self.tab1_add_button.clicked.connect(tab1_add)
        self.tab2_add_button.clicked.connect(tab2_add)
        self.tab3_add_button.clicked.connect(tab3_add)
        self.que_delete_button.clicked.connect(lambda: Utils.delete_list(self.que_list))
        self.que_clear_button.clicked.connect(lambda: Utils.clear_list(self.que_list))
        self.que_up_button.clicked.connect(lambda: Utils.up_list(self.que_list))
        self.que_down_button.clicked.connect(lambda: Utils.down_list(self.que_list))
        self.file_file_open.clicked.connect(file_open)
        self.file_dir_open.clicked.connect(dir_open)
        self.file_delete.clicked.connect(lambda: Utils.delete_list(self.file_list))
        self.file_clear.clicked.connect(lambda: Utils.clear_list(self.file_list))
        self.file_encode.clicked.connect(open_encode_dialog)
        self.save_dir_find.clicked.connect(save_dir)
        self.ok_button.clicked.connect(apply)
        self.cancel_button.clicked.connect(sys.exit)

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls:
            event.accept()
        else:
            event.ignore()

    def dragMoveEvent(self, event):
        if event.mimeData().hasUrls():
            event.setDropAction(Qt.CopyAction)
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        if event.mimeData().hasUrls():
            event.setDropAction(Qt.CopyAction)
            event.accept()
            for url in event.mimeData().urls():
                if url.isLocalFile():
                    file = str(url.toLocalFile())
                    if fnmatch(file, '*.smi'):
                        name = ntpath.basename(file)
                        Utils.insert_list(self.file_list, name, file)
                    elif not fnmatch(file, '*.*'):
                        for paths, subdirs, files in os.walk(file):
                            for file in files:
                                if fnmatch(file, '*.smi'):
                                    name = ntpath.basename(file)
                                    Utils.insert_list(self.file_list, name, file)

        else:
            event.ignore()
Ejemplo n.º 17
0
class RandomDatasetGenerator(QDialog):
    logger = logging.getLogger("root.ui.RandomGeneratorWidget")
    gui_logger = logging.getLogger("GUI")

    def __init__(self, parent=None):
        super().__init__(parent=parent, f=Qt.Window)
        self.setWindowTitle(self.tr("Dataset Generator"))
        self.last_n_components = 0
        self.components = []  # typing.List[RandomGeneratorComponentWidget]
        self.component_series = []
        self.init_ui()
        self.target = LOESS
        self.minimum_size_input.setValue(0.02)
        self.maximum_size_input.setValue(2000.0)
        self.n_classes_input.setValue(101)
        self.precision_input.setValue(4)

        self.file_dialog = QFileDialog(parent=self)
        self.update_timer = QTimer()
        self.update_timer.timeout.connect(lambda: self.update_chart(True))
        self.cancel_flag = False

    def init_ui(self):
        self.setAttribute(Qt.WA_StyledBackground, True)
        self.main_layout = QGridLayout(self)
        # self.main_layout.setContentsMargins(0, 0, 0, 0)

        self.sampling_group = QGroupBox(self.tr("Sampling"))
        # self.control_group.setFixedSize(400, 160)
        self.control_layout = QGridLayout(self.sampling_group)
        self.minimum_size_label = QLabel(self.tr("Minimum Size [μm]"))
        self.minimum_size_input = QDoubleSpinBox()
        self.minimum_size_input.setDecimals(2)
        self.minimum_size_input.setRange(1e-4, 1e6)
        self.minimum_size_input.setValue(0.0200)
        self.maximum_size_label = QLabel(self.tr("Maximum Size [μm]"))
        self.maximum_size_input = QDoubleSpinBox()
        self.maximum_size_input.setDecimals(2)
        self.maximum_size_input.setRange(1e-4, 1e6)
        self.maximum_size_input.setValue(2000.0000)
        self.control_layout.addWidget(self.minimum_size_label, 0, 0)
        self.control_layout.addWidget(self.minimum_size_input, 0, 1)
        self.control_layout.addWidget(self.maximum_size_label, 0, 2)
        self.control_layout.addWidget(self.maximum_size_input, 0, 3)
        self.n_classes_label = QLabel(self.tr("N<sub>classes</sub>"))
        self.n_classes_input = QSpinBox()
        self.n_classes_input.setRange(10, 1e4)
        self.n_classes_input.setValue(101)
        self.precision_label = QLabel(self.tr("Data Precision"))
        self.precision_input = QSpinBox()
        self.precision_input.setRange(2, 8)
        self.precision_input.setValue(4)
        self.control_layout.addWidget(self.n_classes_label, 1, 0)
        self.control_layout.addWidget(self.n_classes_input, 1, 1)
        self.control_layout.addWidget(self.precision_label, 1, 2)
        self.control_layout.addWidget(self.precision_input, 1, 3)
        self.component_number_label = QLabel(self.tr("N<sub>components</sub>"))
        self.component_number_input = QSpinBox()
        self.component_number_input.setRange(1, 10)
        self.component_number_input.valueChanged.connect(
            self.on_n_components_changed)
        self.preview_button = QPushButton(qta.icon("mdi.animation-play"),
                                          self.tr("Preview"))
        self.preview_button.clicked.connect(self.on_preview_clicked)
        self.control_layout.addWidget(self.component_number_label, 2, 0)
        self.control_layout.addWidget(self.component_number_input, 2, 1)
        self.control_layout.addWidget(self.preview_button, 2, 2, 1, 2)
        self.main_layout.addWidget(self.sampling_group, 0, 0)

        self.save_group = QGroupBox(self.tr("Save"))
        # self.save_group.setFixedHeight(160)
        self.save_layout = QGridLayout(self.save_group)
        self.n_samples_label = QLabel(self.tr("N<sub>samples</sub>"))
        self.n_samples_input = QSpinBox()
        self.n_samples_input.setRange(100, 100000)
        self.save_layout.addWidget(self.n_samples_label, 0, 0)
        self.save_layout.addWidget(self.n_samples_input, 0, 1)

        self.cancel_button = QPushButton(qta.icon("mdi.cancel"),
                                         self.tr("Cancel"))
        self.cancel_button.setEnabled(False)
        self.cancel_button.clicked.connect(self.on_cancel_clicked)
        self.generate_button = QPushButton(qta.icon("mdi.cube-send"),
                                           self.tr("Generate"))
        self.generate_button.clicked.connect(self.on_generate_clicked)
        self.progress_bar = QProgressBar()
        self.progress_bar.setRange(0, 100)
        self.progress_bar.setOrientation(Qt.Horizontal)
        self.progress_bar.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        self.save_layout.addWidget(self.cancel_button, 1, 0)
        self.save_layout.addWidget(self.generate_button, 1, 1)
        self.save_layout.addWidget(self.progress_bar, 2, 0, 1, 2)
        self.main_layout.addWidget(self.save_group, 0, 1)

        self.param_group = QGroupBox("Random Parameter")
        # self.param_group.setFixedWidth(400)
        self.param_layout = QGridLayout(self.param_group)
        self.main_layout.addWidget(self.param_group, 1, 0)

        self.preview_group = QGroupBox(self.tr("Preview"))
        self.chart_layout = QGridLayout(self.preview_group)

        self.chart = MixedDistributionChart(parent=self, toolbar=False)
        self.chart_layout.addWidget(self.chart, 0, 0)
        self.chart.setSizePolicy(QSizePolicy.MinimumExpanding,
                                 QSizePolicy.MinimumExpanding)
        self.main_layout.addWidget(self.preview_group, 1, 1)

    @staticmethod
    def to_points(x, y):
        return [QPointF(x_value, y_value) for x_value, y_value in zip(x, y)]

    def on_n_components_changed(self, n_components: int):
        if self.last_n_components < n_components:
            for component_index in range(self.last_n_components, n_components):
                component = RandomGeneratorComponentWidget(
                    name=f"AC{component_index+1}")
                component.value_changed.connect(self.on_value_changed)
                self.param_layout.addWidget(component, component_index + 1, 0)
                self.components.append(component)

        if self.last_n_components > n_components:
            for i in range(n_components, self.last_n_components):
                before_component = self.components[i]
                before_component.value_changed.disconnect(
                    self.on_value_changed)
                self.param_layout.removeWidget(before_component)
                # if not hide, the widget will still display on screen
                before_component.hide()
                self.components.pop(n_components)

        self.last_n_components = n_components

    def on_preview_clicked(self):
        if self.update_timer.isActive():
            self.preview_button.setText(self.tr("Preview"))
            self.update_timer.stop()
            self.update_chart()
        else:
            self.preview_button.setText(self.tr("Stop"))
            self.update_timer.start(200)

    def on_cancel_clicked(self):
        self.cancel_flag = True

    def on_generate_clicked(self):
        if self.update_timer.isActive():
            self.preview_button.setText(self.tr("Preview"))
            self.update_timer.stop()
            self.update_chart()

        filename, _ = self.file_dialog.getSaveFileName(
            self, self.tr("Choose a filename to save the generated dataset"),
            None, "Microsoft Excel (*.xlsx)")
        if filename is None or filename == "":
            return
        n_samples = self.n_samples_input.value()
        dataset = self.get_random_dataset(n_samples)
        # generate samples
        self.cancel_button.setEnabled(True)
        self.generate_button.setEnabled(False)
        format_str = self.tr("Generating {0} samples: %p%").format(n_samples)
        self.progress_bar.setFormat(format_str)
        self.progress_bar.setValue(0)

        def cancel():
            self.progress_bar.setFormat(self.tr("Task canceled"))
            self.progress_bar.setValue(0)
            self.cancel_button.setEnabled(False)
            self.generate_button.setEnabled(True)
            self.cancel_flag = False

        samples = []
        for i in range(n_samples):
            if self.cancel_flag:
                cancel()
                return
            sample = dataset.get_sample(i)
            samples.append(sample)
            progress = (i + 1) / n_samples * 50
            self.progress_bar.setValue(progress)
            QCoreApplication.processEvents()

        # save file to excel file
        format_str = self.tr("Writing {0} samples to excel file: %p%").format(
            n_samples)
        self.progress_bar.setFormat(format_str)
        self.progress_bar.setValue(50)

        wb = openpyxl.Workbook()
        prepare_styles(wb)

        ws = wb.active
        ws.title = self.tr("README")
        description = \
            """
            This Excel file was generated by QGrain ({0}).

            Please cite:
            Liu, Y., Liu, X., Sun, Y., 2021. QGrain: An open-source and easy-to-use software for the comprehensive analysis of grain size distributions. Sedimentary Geology 423, 105980. https://doi.org/10.1016/j.sedgeo.2021.105980

            It contanins n_components + 3 sheets:
            1. The first sheet is the random settings which were used to generate random parameters.
            2. The second sheet is the generated dataset.
            3. The third sheet is random parameters which were used to calulate the component distributions and their mixture.
            4. The left sheets are the component distributions of all samples.

            Artificial dataset
                Using skew normal distribution as the base distribution of each component (i.e. end-member).
                Skew normal distribution has three parameters, shape, location and scale.
                Where shape controls the skewness, location and scale are simliar to that of the Normal distribution.
                When shape = 0, it becomes Normal distribution.
                The weight parameter controls the fraction of the component, where fraction_i = weight_i / sum(weight_i).
                By assigning the mean and std of each parameter, random parameters was generate by the `scipy.stats.truncnorm.rvs` function of Scipy.

            Sampling settings
                Minimum size [μm]: {1},
                Maximum size [μm]: {2},
                N_classes: {3},
                Precision: {4},
                Noise: {5},
                N_samples: {6}

            """.format(QGRAIN_VERSION,
                       self.minimum_size_input.value(),
                       self.maximum_size_input.value(),
                       self.n_classes_input.value(),
                       self.precision_input.value(),
                       self.precision_input.value()+1,
                       n_samples)

        def write(row, col, value, style="normal_light"):
            cell = ws.cell(row + 1, col + 1, value=value)
            cell.style = style

        lines_of_desc = description.split("\n")
        for row, line in enumerate(lines_of_desc):
            write(row, 0, line, style="description")
        ws.column_dimensions[column_to_char(0)].width = 200

        ws = wb.create_sheet(self.tr("Random Settings"))
        write(0, 0, self.tr("Parameter"), style="header")
        ws.merge_cells(start_row=1, start_column=1, end_row=2, end_column=1)
        write(0, 1, self.tr("Shape"), style="header")
        ws.merge_cells(start_row=1, start_column=2, end_row=1, end_column=3)
        write(0, 3, self.tr("Location"), style="header")
        ws.merge_cells(start_row=1, start_column=4, end_row=1, end_column=5)
        write(0, 5, self.tr("Scale"), style="header")
        ws.merge_cells(start_row=1, start_column=6, end_row=1, end_column=7)
        write(0, 7, self.tr("Weight"), style="header")
        ws.merge_cells(start_row=1, start_column=8, end_row=1, end_column=9)
        ws.column_dimensions[column_to_char(0)].width = 16
        for col in range(1, 9):
            ws.column_dimensions[column_to_char(col)].width = 16
            if col % 2 == 0:
                write(1, col, self.tr("Mean"), style="header")
            else:
                write(1, col, self.tr("STD"), style="header")
        for row, comp_params in enumerate(self.target, 2):
            if row % 2 == 1:
                style = "normal_dark"
            else:
                style = "normal_light"
            write(row, 0, self.tr("Component{0}").format(row - 1), style=style)
            for i, key in enumerate(["shape", "loc", "scale", "weight"]):
                mean, std = comp_params[key]
                write(row, i * 2 + 1, mean, style=style)
                write(row, i * 2 + 2, std, style=style)

        ws = wb.create_sheet(self.tr("Dataset"))
        write(0, 0, self.tr("Sample Name"), style="header")
        ws.column_dimensions[column_to_char(0)].width = 24
        for col, value in enumerate(dataset.classes_μm, 1):
            write(0, col, value, style="header")
            ws.column_dimensions[column_to_char(col)].width = 10
        for row, sample in enumerate(samples, 1):
            if row % 2 == 0:
                style = "normal_dark"
            else:
                style = "normal_light"
            write(row, 0, sample.name, style=style)
            for col, value in enumerate(sample.distribution, 1):
                write(row, col, value, style=style)

            if self.cancel_flag:
                cancel()
                return
            progress = 50 + (row / n_samples) * 10
            self.progress_bar.setValue(progress)
            QCoreApplication.processEvents()

        ws = wb.create_sheet(self.tr("Parameters"))
        write(0, 0, self.tr("Sample Name"), style="header")
        ws.merge_cells(start_row=1, start_column=1, end_row=2, end_column=1)
        ws.column_dimensions[column_to_char(0)].width = 24
        for i in range(dataset.n_components):
            write(0,
                  4 * i + 1,
                  self.tr("Component{0}").format(i + 1),
                  style="header")
            ws.merge_cells(start_row=1,
                           start_column=4 * i + 2,
                           end_row=1,
                           end_column=4 * i + 5)
            for j, header_name in enumerate([
                    self.tr("Shape"),
                    self.tr("Location"),
                    self.tr("Scale"),
                    self.tr("Weight")
            ]):
                write(1, 4 * i + 1 + j, header_name, style="header")
                ws.column_dimensions[column_to_char(4 * i + 1 + j)].width = 16
        for row, sample in enumerate(samples, 2):
            if row % 2 == 1:
                style = "normal_dark"
            else:
                style = "normal_light"
            write(row, 0, sample.name, style=style)
            for i, comp_param in enumerate(sample.parameter.components):
                write(row, 4 * i + 1, comp_param.shape, style=style)
                write(row, 4 * i + 2, comp_param.loc, style=style)
                write(row, 4 * i + 3, comp_param.scale, style=style)
                write(row, 4 * i + 4, comp_param.weight, style=style)
            if self.cancel_flag:
                cancel()
                return
            progress = 60 + (row / n_samples) * 10
            self.progress_bar.setValue(progress)
            QCoreApplication.processEvents()

        for i in range(dataset.n_components):
            ws = wb.create_sheet(self.tr("Component{0}").format(i + 1))
            write(0, 0, self.tr("Sample Name"), style="header")
            ws.column_dimensions[column_to_char(0)].width = 24
            for col, value in enumerate(dataset.classes_μm, 1):
                write(0, col, value, style="header")
                ws.column_dimensions[column_to_char(col)].width = 10
            for row, sample in enumerate(samples, 1):
                if row % 2 == 0:
                    style = "normal_dark"
                else:
                    style = "normal_light"
                write(row, 0, sample.name, style=style)
                for col, value in enumerate(sample.components[i].distribution,
                                            1):
                    write(row, col, value, style=style)
            if self.cancel_flag:
                cancel()
                return
            progress = 70 + (
                (i * n_samples + row) / n_samples * dataset.n_components) * 30
            self.progress_bar.setValue(progress)
            QCoreApplication.processEvents()
        wb.save(filename)
        wb.close()

        self.progress_bar.setValue(100)
        self.progress_bar.setFormat(self.tr("Task finished"))
        self.cancel_button.setEnabled(False)
        self.generate_button.setEnabled(True)

    @property
    def target(self):
        return [comp.target for comp in self.components]

    @target.setter
    def target(self, values):
        if len(values) != len(self.components):
            self.component_number_input.setValue(len(values))
        for comp, comp_target in zip(self.components, values):
            comp.blockSignals(True)
            comp.target = comp_target
            comp.blockSignals(False)
        self.update_chart()

    def get_random_sample(self):
        dataset = self.get_random_dataset(n_samples=1)
        sample = dataset.get_sample(0)
        sample.name = self.tr("Artificial Sample")
        return sample

    def get_random_mean(self):
        dataset = self.get_random_dataset(n_samples=1)
        random_setting = RandomSetting(self.target)
        sample = dataset.get_sample_by_params(self.tr("Artificial Sample"),
                                              random_setting.mean_param)
        return sample

    def get_random_dataset(self, n_samples):
        min_μm = self.minimum_size_input.value()
        max_μm = self.maximum_size_input.value()
        n_classes = self.n_classes_input.value()
        if min_μm == max_μm:
            return
        if min_μm > max_μm:
            min_μm, max_μm = max_μm, min_μm
        precision = self.precision_input.value()
        noise = precision + 1

        dataset = get_random_dataset(target=self.target,
                                     n_samples=n_samples,
                                     min_μm=min_μm,
                                     max_μm=max_μm,
                                     n_classes=n_classes,
                                     precision=precision,
                                     noise=noise)
        return dataset

    def on_value_changed(self):
        self.update_chart()

    def update_chart(self, random=False):
        if not random:
            sample = self.get_random_mean()
        else:
            sample = self.get_random_sample()
        self.chart.show_model(sample.view_model)

    def closeEvent(self, event):
        if self.cancel_button.isEnabled():
            self.on_cancel_clicked()
        event.accept()
Ejemplo n.º 18
0
class LissajousInterface(QWidget):
    def __init__(self, lissCurve):
        QWidget.__init__(self)
        self.lissCurve = lissCurve

        # set amplitudes
        self.aAmpLabel = QLabel("A:")
        self.aAmpLabel.setFixedWidth(20)
        self.aAmplitude_spinBox = QDoubleSpinBox()
        self.configureAmpSpinBox(self.aAmplitude_spinBox)
        self.aAmplitude_spinBox.valueChanged.connect(self.valueChanged)

        self.bAmpLabel = QLabel("B:")
        self.bAmpLabel.setFixedWidth(20)
        self.bAmplitude_spinBox = QDoubleSpinBox()
        self.configureAmpSpinBox(self.bAmplitude_spinBox)
        self.bAmplitude_spinBox.valueChanged.connect(self.valueChanged)

        # set omegas
        self.aOmegaLabel = QLabel("ɷA:")
        self.aOmegaLabel.setFixedWidth(30)
        self.aOmega_spinBox = QSpinBox()
        self.configureOmegaSpinBox(self.aOmega_spinBox)
        self.aOmega_spinBox.valueChanged.connect(self.valueChanged)

        self.bOmegaLabel = QLabel("ɷB:")
        self.bOmegaLabel.setFixedWidth(30)
        self.bOmega_spinBox = QSpinBox()
        self.configureOmegaSpinBox(self.bOmega_spinBox)
        self.bOmega_spinBox.valueChanged.connect(self.valueChanged)

        self.phiLabel = QLabel("φ")
        self.phiLabel.setFixedWidth(20)
        self.phi_spinBox = QDoubleSpinBox()
        self.configurePhaseSpinBox(self.phi_spinBox)
        self.phi_spinBox.valueChanged.connect(self.valueChanged)

        self.configureLayout()

    @Slot()
    def valueChanged(self):
        self.lissCurve.setVariables(self.aAmplitude_spinBox.value(),
                                    self.bAmplitude_spinBox.value(),
                                    self.aOmega_spinBox.value(),
                                    self.bOmega_spinBox.value(),
                                    self.phi_spinBox.value())

    def configureAmpSpinBox(self, amp):
        amp.setRange(0, 10)
        amp.setWrapping(False)
        amp.setValue(5)
        amp.setSingleStep(0.01)

    def configureOmegaSpinBox(self, ome):
        ome.setRange(-10, 10)
        ome.setWrapping(False)
        ome.setValue(5)

    def configurePhaseSpinBox(self, phi):
        phi.setRange(-10, 10)
        phi.setWrapping(False)
        phi.setValue(5)
        phi.setSingleStep(0.01)

    def configureLayout(self):
        self.interfaceLayout = QHBoxLayout()

        # set amplitude layout
        self.aAmpWithLayout = QHBoxLayout()
        self.aAmpWithLayout.addWidget(self.aAmpLabel)
        self.aAmpWithLayout.addWidget(self.aAmplitude_spinBox)

        self.bAmpWithLayout = QHBoxLayout()
        self.bAmpWithLayout.addWidget(self.bAmpLabel)
        self.bAmpWithLayout.addWidget(self.bAmplitude_spinBox)

        self.amplitudeLayout = QVBoxLayout()
        self.amplitudeLayout.addLayout(self.aAmpWithLayout)
        self.amplitudeLayout.addLayout(self.bAmpWithLayout)

        # set omega layout
        self.aOmegaWithLayout = QHBoxLayout()
        self.aOmegaWithLayout.addWidget(self.aOmegaLabel)
        self.aOmegaWithLayout.addWidget(self.aOmega_spinBox)

        self.bOmegaWithLayout = QHBoxLayout()
        self.bOmegaWithLayout.addWidget(self.bOmegaLabel)
        self.bOmegaWithLayout.addWidget(self.bOmega_spinBox)

        self.omegaLayout = QVBoxLayout()
        self.omegaLayout.addLayout(self.aOmegaWithLayout)
        self.omegaLayout.addLayout(self.bOmegaWithLayout)

        # set omega layout
        self.phiLayout = QHBoxLayout()
        self.phiLayout.addWidget(self.phiLabel)
        self.phiLayout.addWidget(self.phi_spinBox)

        # set general interface layout
        self.interfaceLayout.addLayout(self.amplitudeLayout)
        self.interfaceLayout.addLayout(self.omegaLayout)
        self.interfaceLayout.addLayout(self.phiLayout)

        self.setLayout(self.interfaceLayout)
Ejemplo n.º 19
0
class MedianWidget(ToolWidget):
    def __init__(self, image, parent=None):
        super(MedianWidget, self).__init__(parent)

        self.variance_spin = QSpinBox()
        self.variance_spin.setRange(0, 50)
        self.variance_spin.setValue(10)
        self.threshold_spin = QDoubleSpinBox()
        self.threshold_spin.setRange(0, 1)
        self.threshold_spin.setValue(0.45)
        self.threshold_spin.setSingleStep(0.01)
        self.showprob_check = QCheckBox(self.tr('Probability map'))
        self.filter_check = QCheckBox(self.tr('Speckle filter'))
        self.filter_check.setChecked(True)
        self.process_button = QPushButton(self.tr('Process'))
        self.avgprob_label = QLabel(self.tr('Press "Process" to start'))

        top_layout = QHBoxLayout()
        top_layout.addWidget(QLabel(self.tr('Min variance:')))
        top_layout.addWidget(self.variance_spin)
        top_layout.addWidget(QLabel(self.tr('Threshold:')))
        top_layout.addWidget(self.threshold_spin)
        top_layout.addWidget(self.showprob_check)
        top_layout.addWidget(self.filter_check)
        top_layout.addWidget(self.process_button)
        # top_layout.addWidget(self.avgprob_label)
        top_layout.addStretch()

        self.image = image
        self.viewer = ImageViewer(self.image, self.image)
        self.gray = cv.cvtColor(self.image, cv.COLOR_BGR2GRAY)
        self.prob = self.var = None
        self.block = 64
        self.canceled = False

        self.process_button.clicked.connect(self.prepare)
        self.variance_spin.valueChanged.connect(self.process)
        self.threshold_spin.valueChanged.connect(self.process)
        self.showprob_check.stateChanged.connect(self.process)
        self.filter_check.stateChanged.connect(self.process)

        main_layout = QVBoxLayout()
        main_layout.addLayout(top_layout)
        main_layout.addWidget(self.viewer)
        self.setLayout(main_layout)

    def prepare(self):
        modelfile = 'models/median_b{}.mdl'.format(self.block)
        try:
            model = load(modelfile)
        except FileNotFoundError:
            QMessageBox.critical(
                self, self.tr('Error'),
                self.tr('Model not found ("{}")!'.format(modelfile)))
            return
        limit = model.best_ntree_limit if hasattr(model,
                                                  'best_ntree_limit') else None
        columns = model._features_count
        if columns == 8:
            levels = 1
            windows = 1
        elif columns == 24:
            levels = 3
            windows = 1
        elif columns == 96:
            levels = 3
            windows = 4
        elif columns == 128:
            levels = 4
            windows = 4
        else:
            QMessageBox.critical(self, self.tr('Error'),
                                 self.tr('Unknown model format!'))
            return

        padded = pad_image(self.gray, self.block)
        rows, cols = padded.shape
        self.prob = np.zeros(
            ((rows // self.block) + 1, (cols // self.block) + 1))
        self.var = np.zeros_like(self.prob)
        progress = QProgressDialog(self.tr('Detecting median filter...'),
                                   self.tr('Cancel'), 0, self.prob.size, self)
        progress.canceled.connect(self.cancel)
        progress.setWindowModality(Qt.WindowModal)
        k = 0
        self.canceled = False
        for i in range(0, rows, self.block):
            for j in range(0, cols, self.block):
                roi = padded[i:i + self.block, j:j + self.block]
                x = np.reshape(get_features(roi, levels, windows),
                               (1, columns))
                y = model.predict_proba(x, ntree_limit=limit)[0, 1]
                ib = i // self.block
                jb = j // self.block
                self.var[ib, jb] = np.var(roi)
                self.prob[ib, jb] = y
                if self.canceled:
                    self.prob = self.var = None
                    progress.close()
                    return
                progress.setValue(k)
                k += 1
        progress.close()
        self.process()

    def cancel(self):
        self.canceled = True

    def process(self):
        if self.prob is None:
            return
        mask = self.var < self.variance_spin.value()
        if self.filter_check.isChecked():
            prob = cv.medianBlur(self.prob.astype(np.float32), 3)
        else:
            prob = self.prob.astype(np.float32)
        if self.showprob_check.isChecked():
            output = np.repeat(prob[:, :, np.newaxis], 3, axis=2)
            output[mask] = 0
        else:
            thr = self.threshold_spin.value()
            output = np.zeros((prob.shape[0], prob.shape[1], 3))
            blue, green, red = cv.split(output)
            blue[mask] = 1
            green[prob < thr] = 1
            green[mask] = 0
            red[prob >= thr] = 1
            red[mask] = 0
            output = cv.merge((blue, green, red))
        output = cv.convertScaleAbs(output, None, 255)
        output = cv.resize(output, None, None, self.block, self.block,
                           cv.INTER_LINEAR)
        self.viewer.update_processed(
            np.copy(output[:self.image.shape[0], :self.image.shape[1]]))
        avgprob = cv.mean(prob, 1 - mask.astype(np.uint8))[0] * 100
        self.avgprob_label.setText(self.tr(
            'Average = {:.2f}%'.format(avgprob)))
        modify_font(self.avgprob_label, italic=False, bold=True)
        self.process_button.setEnabled(False)
Ejemplo n.º 20
0
class PlotsWidget(ToolWidget):
    def __init__(self, image, parent=None):
        super(PlotsWidget, self).__init__(parent)

        choices = ["Red", "Green", "Blue", "Hue", "Saturation", "Value"]
        self.xaxis_combo = QComboBox()
        self.xaxis_combo.addItems(choices)
        self.xaxis_combo.setCurrentIndex(3)
        self.yaxis_combo = QComboBox()
        self.yaxis_combo.addItems(choices)
        self.yaxis_combo.setCurrentIndex(4)
        self.zaxis_combo = QComboBox()
        self.zaxis_combo.addItems(choices)
        self.zaxis_combo.setCurrentIndex(5)
        self.sampling_spin = QSpinBox()
        levels = int(np.log2(min(image.shape[:-1])))
        self.sampling_spin.setRange(0, levels)
        self.sampling_spin.setSpecialValueText(self.tr("Off"))
        # self.sampling_spin.setSuffix(self.tr(' level(s)'))
        self.sampling_spin.setValue(1)
        self.size_spin = QSpinBox()
        self.size_spin.setRange(1, 10)
        self.size_spin.setValue(1)
        self.size_spin.setSuffix(self.tr(" pt"))
        self.markers = [
            ",", ".", "o", "8", "s", "p", "P", "*", "h", "H", "X", "D"
        ]
        self.alpha_spin = QDoubleSpinBox()
        self.alpha_spin.setRange(0, 1)
        self.alpha_spin.setDecimals(2)
        self.alpha_spin.setSingleStep(0.05)
        self.alpha_spin.setValue(1)
        self.colors_check = QCheckBox(self.tr("Show colors"))
        self.grid_check = QCheckBox(self.tr("Show grid"))
        self.norm_check = QCheckBox(self.tr("Normalized"))
        self.total_label = QLabel()

        img = np.copy(image)
        self.colors = [None] * (levels + 1)
        for scale in range(levels + 1):
            rgb = cv.cvtColor(img.astype(np.float32) / 255, cv.COLOR_BGR2RGB)
            hsv = cv.cvtColor(rgb, cv.COLOR_RGB2HSV)
            hsv[:, :, 0] /= 360
            shape = (img.shape[0] * img.shape[1], img.shape[2])
            self.colors[scale] = np.concatenate(
                (np.reshape(rgb, shape), np.reshape(hsv, shape)), axis=1)
            img = cv.pyrDown(img)

        figure2 = Figure()
        plot2_canvas = FigureCanvas(figure2)
        self.axes2 = plot2_canvas.figure.subplots()
        toolbar2 = NavigationToolbar(plot2_canvas, self)
        plot2_layout = QVBoxLayout()
        plot2_layout.addWidget(plot2_canvas)
        plot2_layout.addWidget(toolbar2)
        plot2_widget = QWidget()
        plot2_widget.setLayout(plot2_layout)

        figure3 = Figure()
        plot3_canvas = FigureCanvas(figure3)
        self.axes3 = plot3_canvas.figure.add_subplot(111, projection="3d")
        toolbar3 = NavigationToolbar(plot3_canvas, self)
        plot3_layout = QVBoxLayout()
        plot3_layout.addWidget(plot3_canvas)
        plot3_layout.addWidget(toolbar3)
        plot3_widget = QWidget()
        plot3_widget.setLayout(plot3_layout)

        self.tab_widget = QTabWidget()
        self.tab_widget.addTab(plot2_widget, "2D Plot")
        self.tab_widget.addTab(plot3_widget, "3D Plot")
        self.redraw()
        figure2.set_tight_layout(True)
        figure3.set_tight_layout(True)

        self.xaxis_combo.currentIndexChanged.connect(self.redraw)
        self.yaxis_combo.currentIndexChanged.connect(self.redraw)
        self.zaxis_combo.currentIndexChanged.connect(self.redraw)
        self.sampling_spin.valueChanged.connect(self.redraw)
        self.size_spin.valueChanged.connect(self.redraw)
        self.alpha_spin.valueChanged.connect(self.redraw)
        self.colors_check.stateChanged.connect(self.redraw)
        self.grid_check.stateChanged.connect(self.redraw)
        self.norm_check.stateChanged.connect(self.redraw)
        self.tab_widget.currentChanged.connect(self.redraw)

        params_layout = QGridLayout()
        params_layout.addWidget(QLabel(self.tr("X axis:")), 0, 0)
        params_layout.addWidget(self.xaxis_combo, 0, 1)
        params_layout.addWidget(QLabel(self.tr("Y axis:")), 1, 0)
        params_layout.addWidget(self.yaxis_combo, 1, 1)
        params_layout.addWidget(QLabel(self.tr("Z axis:")), 2, 0)
        params_layout.addWidget(self.zaxis_combo, 2, 1)
        params_layout.addWidget(QLabel(self.tr("Subsampling:")), 0, 2)
        params_layout.addWidget(self.sampling_spin, 0, 3)
        params_layout.addWidget(QLabel(self.tr("Point size:")), 1, 2)
        params_layout.addWidget(self.size_spin, 1, 3)
        params_layout.addWidget(QLabel(self.tr("Point alpha:")), 2, 2)
        params_layout.addWidget(self.alpha_spin, 2, 3)
        params_layout.addWidget(self.colors_check, 0, 4)
        params_layout.addWidget(self.grid_check, 1, 4)
        params_layout.addWidget(self.total_label, 2, 4)
        bottom_layout = QHBoxLayout()
        bottom_layout.addLayout(params_layout)
        bottom_layout.addStretch()

        main_layout = QVBoxLayout()
        main_layout.addWidget(self.tab_widget)
        main_layout.addLayout(bottom_layout)
        self.setLayout(main_layout)

    def redraw(self):
        start = time()
        v = self.sampling_spin.value()
        x = self.colors[v][:, self.xaxis_combo.currentIndex()]
        y = self.colors[v][:, self.yaxis_combo.currentIndex()]
        s = self.size_spin.value()**2
        c = None if not self.colors_check.isChecked(
        ) else self.colors[v][:, :3]

        if self.tab_widget.currentIndex() == 0:
            self.zaxis_combo.setEnabled(False)
            self.grid_check.setEnabled(True)
            self.alpha_spin.setEnabled(True)
            a = self.alpha_spin.value()
            xlim = self.axes2.get_xlim()
            ylim = self.axes2.get_ylim()
            self.axes2.clear()
            self.axes2.set_facecolor([0.5] * 3 if c is not None else [1.0] * 3)
            self.axes2.scatter(x, y, s, c, ".", alpha=a)
            self.axes2.set_xlabel(self.xaxis_combo.currentText())
            self.axes2.set_ylabel(self.yaxis_combo.currentText())
            self.axes2.grid(self.grid_check.isChecked(), which="both")
            self.axes2.set_xlim(xlim)
            self.axes2.set_ylim(ylim)
            self.axes2.figure.canvas.draw()
        else:
            self.zaxis_combo.setEnabled(True)
            self.grid_check.setEnabled(False)
            self.alpha_spin.setEnabled(False)
            z = self.colors[v][:, self.zaxis_combo.currentIndex()]
            self.axes3.clear()
            self.axes3.set_facecolor([0.5] * 3 if c is not None else [1.0] * 3)
            self.axes3.scatter(x, y, z, s=s, c=c, marker=".", depthshade=True)
            self.axes3.set_xlabel(self.xaxis_combo.currentText())
            self.axes3.set_ylabel(self.yaxis_combo.currentText())
            self.axes3.set_zlabel(self.zaxis_combo.currentText())
            self.axes3.grid(self.grid_check.isChecked(), which="both")
            self.axes3.figure.canvas.draw()

        self.total_label.setText(self.tr(f"[{len(x)} points]"))
        self.info_message.emit(f"Plot redraw = {elapsed_time(start)}")