예제 #1
0
class ChangeDetectorApp(QWidget):
    
	image1 = ""
	image2 = ""
	result_path = ""
	AppSize = (600, 300)
	NUMBER_OF_SLICES = 9

	def __init__(self):
		super().__init__()
		self.AppTitle = "Satellite Images Change Detector"
		self.initUI()
		self.setFixedSize(*self.AppSize)
		self.setWindowTitle(self.AppTitle)
		self.show()
		self.output.insertPlainText(">>> Program Started\n")
		
	def initUI(self):

		#set background image of main window
		oImage = QImage("background.jpg")
		sImage = oImage.scaled(QSize(*self.AppSize))
		palette = QPalette()
		palette.setBrush(10, QBrush(sImage))
		self.setPalette(palette)

		#settings of image 1 button
		image1 = QPushButton('First Image', self)
		image1.setToolTip('Click to choose first photo')
		image1.resize(image1.sizeHint())
		image1.clicked.connect(self.openFile1NameDialog)

		#settings of image 2 button
		image2 = QPushButton('Second Image', self)
		image2.setToolTip('Click to choose second photo')
		image2.resize(image2.sizeHint())
		image2.clicked.connect(self.openFile2NameDialog)

		#settings of result button
		self.result = QPushButton('Result path', self)
		self.result.setToolTip('Click to choose where to save the result')
		self.result.resize(self.result.sizeHint())
		self.result.clicked.connect(self.saveFileDialog)
		self.result.setEnabled(False)

		#settings of save result check box
		self.save_res = QCheckBox('Save Result', self)
		self.save_res.setToolTip('Click this to save the output result on the disk')
		self.save_res.stateChanged.connect(self.saveResult)
		self.save_res.setAutoFillBackground(True)
		p = self.save_res.palette()
		p.setColor(self.save_res.backgroundRole(), Qt.white)
		self.save_res.setPalette(p)

		#settings of detect button
		detect = QPushButton('Detect', self)
		detect.setToolTip('Click to detect changes between inputs')
		detect.resize(detect.sizeHint())
		detect.clicked.connect(self.detectClicked)
		
		# creating a plainText box for output messages
		self.output = QPlainTextEdit(self)

		#settings of quit button
		quit = QPushButton('Quit', self)
		quit.setToolTip('Click to quit the app')
		quit.resize(quit.sizeHint())
		quit.clicked.connect(QApplication.instance().quit)

		# setting layout of main window
		resultBox = QHBoxLayout()
		resultBox.setSpacing(10)
		resultBox.addWidget(self.result)
		resultBox.addWidget(self.save_res)

		leftBox = QVBoxLayout()
		leftBox.addWidget(image1)
		leftBox.addWidget(image2)
		leftBox.addLayout(resultBox)
		leftBox.addStretch(1)
		leftBox.addWidget(detect)

		rightBox = QVBoxLayout()
		rightBox.addWidget(self.output)
		rightBox.addStretch(1)
		rightBox.addWidget(quit)
		
		layout = QHBoxLayout()
		layout.addLayout(leftBox)
		layout.addStretch(1)
		layout.addLayout(rightBox)

		self.setLayout(layout)

	def detectClicked(self):
		if self.image1 == "":
			self.output.insertPlainText("! Error: Enter first image\n")
		elif self.image2 == "":
			self.output.insertPlainText("! Error: Enter second image\n")
		else:
			self.output.insertPlainText(">>> Detection Started\n")
			run_detection(self.image1, self.image2, self.NUMBER_OF_SLICES)
            
	def openFile1NameDialog(self):
		options = QFileDialog.Options()
		options |= QFileDialog.DontUseNativeDialog
		fileName, _ = QFileDialog.getOpenFileName(self,"QFileDialog.getOpenFileName()", "","All Files (*);;PNG Files (*.png);;JPG Files (*.jpg);;JPEG Files (*.jpeg)", options=options)
		if fileName:
			self.image1 = fileName
			self.output.insertPlainText(">>> First image is {}\n".format(self.image1))

	def openFile2NameDialog(self):
		options = QFileDialog.Options()
		options |= QFileDialog.DontUseNativeDialog
		fileName, _ = QFileDialog.getOpenFileName(self,"QFileDialog.getOpenFileName()", "","All Files (*);;PNG Files (*.png);;JPG Files (*.jpg);;JPEG Files (*.jpeg)", options=options)
		if fileName:
			self.image2 = fileName
			self.output.insertPlainText(">>> Second image is {}\n".format(self.image2))

	def saveFileDialog(self):
		options = QFileDialog.Options()
		options |= QFileDialog.DontUseNativeDialog
		fileName, _ = QFileDialog.getSaveFileName(self,"QFileDialog.getSaveFileName()","","All Files (*);;PNG Files (*.png)", options=options)
		if fileName:
			self.result_path = fileName
			self.output.insertPlainText(">>> Result save to {}\n".format(self.result_path))

	def saveResult(self, state):
		if state == Qt.Checked:
			self.result.setEnabled(True)
			self.result_path = ""
		else:
			self.result.setEnabled(False)
			self.result_path = ""
예제 #2
0
class _SingleRoiCtrlWidget(QWidget):
    """_SingleRoiCtrlWidget class.

    Widget which controls a single ROI.
    """
    # TODO: locked currently is always 0
    # (idx, activated, locked, x, y, w, h) where idx starts from 1
    roi_geometry_change_sgn = pyqtSignal(object)

    _pos_validator = QIntValidator(-10000, 10000)
    _size_validator = QIntValidator(1, 10000)

    def __init__(self,
                 roi: RectROI,
                 *,
                 mediator=None,
                 with_lock=True,
                 parent=None):
        super().__init__(parent=parent)

        self._roi = roi
        # Here is mediator is a general mediator object which has a slot
        # 'onRoiGeometryChange'.
        self._mediator = mediator

        idx = self._roi.index
        self._activate_cb = QCheckBox(f"ROI{idx}")
        palette = self._activate_cb.palette()
        palette.setColor(palette.WindowText,
                         FColor.mkColor(config['GUI_ROI_COLORS'][idx - 1]))
        self._activate_cb.setPalette(palette)

        self._with_lock = with_lock
        self._lock_cb = QCheckBox("Lock")

        self._width_le = SmartLineEdit()
        self._width_le.setValidator(self._size_validator)
        self._height_le = SmartLineEdit()
        self._height_le.setValidator(self._size_validator)
        self._px_le = SmartLineEdit()
        self._px_le.setValidator(self._pos_validator)
        self._py_le = SmartLineEdit()
        self._py_le.setValidator(self._pos_validator)

        self._line_edits = (self._width_le, self._height_le, self._px_le,
                            self._py_le)

        self.initUI()
        self.initConnections()

        self.disableAllEdit()

    def initUI(self):
        layout = QHBoxLayout()

        layout.addWidget(self._activate_cb)
        if self._with_lock:
            layout.addWidget(self._lock_cb)
        layout.addWidget(QLabel("w: "))
        layout.addWidget(self._width_le)
        layout.addWidget(QLabel("h: "))
        layout.addWidget(self._height_le)
        layout.addWidget(QLabel("x: "))
        layout.addWidget(self._px_le)
        layout.addWidget(QLabel("y: "))
        layout.addWidget(self._py_le)

        self.setLayout(layout)

    def initConnections(self):
        self._width_le.value_changed_sgn.connect(self.onRoiSizeEdited)
        self._height_le.value_changed_sgn.connect(self.onRoiSizeEdited)
        self._px_le.value_changed_sgn.connect(self.onRoiPositionEdited)
        self._py_le.value_changed_sgn.connect(self.onRoiPositionEdited)

        self._roi.sigRegionChangeFinished.connect(
            self.onRoiGeometryChangeFinished)

        self._activate_cb.stateChanged.connect(self.onToggleRoiActivation)
        self._activate_cb.stateChanged.emit(self._activate_cb.checkState())
        self._lock_cb.stateChanged.connect(self.onLock)

    def setLabel(self, text):
        self._activate_cb.setText(text)

    @pyqtSlot(int)
    def onToggleRoiActivation(self, state):
        if state == Qt.Checked:
            self._roi.show()
            self.enableAllEdit()
        else:
            self._roi.hide()
            self.disableAllEdit()

        x, y = [int(v) for v in self._roi.pos()]
        w, h = [int(v) for v in self._roi.size()]
        self.roi_geometry_change_sgn.emit(
            (self._roi.index, state == Qt.Checked, 0, x, y, w, h))

    @pyqtSlot(object)
    def onRoiPositionEdited(self, value):
        x, y = [int(v) for v in self._roi.pos()]
        w, h = [int(v) for v in self._roi.size()]

        if self.sender() == self._px_le:
            x = int(self._px_le.text())
        elif self.sender() == self._py_le:
            y = int(self._py_le.text())

        # If 'update' == False, the state change will be remembered
        # but not processed and no signals will be emitted.
        self._roi.setPos((x, y), update=False)
        # trigger sigRegionChanged which moves the handler(s)
        # finish=False -> sigRegionChangeFinished will not emit, which
        # otherwise triggers infinite recursion
        self._roi.stateChanged(finish=False)

        state = self._activate_cb.isChecked()
        self.roi_geometry_change_sgn.emit(
            (self._roi.index, state, 0, x, y, w, h))

    @pyqtSlot(object)
    def onRoiSizeEdited(self, value):
        x, y = [int(v) for v in self._roi.pos()]
        w, h = [int(v) for v in self._roi.size()]
        if self.sender() == self._width_le:
            w = int(self._width_le.text())
        elif self.sender() == self._height_le:
            h = int(self._height_le.text())

        # If 'update' == False, the state change will be remembered
        # but not processed and no signals will be emitted.
        self._roi.setSize((w, h), update=False)
        # trigger sigRegionChanged which moves the handler(s)
        # finish=False -> sigRegionChangeFinished will not emit, which
        # otherwise triggers infinite recursion
        self._roi.stateChanged(finish=False)

        self.roi_geometry_change_sgn.emit(
            (self._roi.index, self._activate_cb.isChecked(), 0, x, y, w, h))

    @pyqtSlot(object)
    def onRoiGeometryChangeFinished(self, roi):
        """Connect to the signal from an ROI object."""
        x, y = [int(v) for v in roi.pos()]
        w, h = [int(v) for v in roi.size()]
        self.updateParameters(x, y, w, h)
        # inform widgets outside this window
        self.roi_geometry_change_sgn.emit(
            (roi.index, self._activate_cb.isChecked(), 0, x, y, w, h))

    def notifyRoiParams(self):
        # fill the QLineEdit(s) and Redis
        self._roi.sigRegionChangeFinished.emit(self._roi)

    def reloadRoiParams(self, cfg):
        state, _, x, y, w, h = [v.strip() for v in cfg.split(',')]

        self.roi_geometry_change_sgn.disconnect()
        self._px_le.setText(x)
        self._py_le.setText(y)
        self._width_le.setText(w)
        self._height_le.setText(h)
        self.roi_geometry_change_sgn.connect(
            self._mediator.onRoiGeometryChange)
        self._activate_cb.setChecked(bool(int(state)))

    def updateParameters(self, x, y, w, h):
        self.roi_geometry_change_sgn.disconnect()
        self._px_le.setText(str(x))
        self._py_le.setText(str(y))
        self._width_le.setText(str(w))
        self._height_le.setText(str(h))
        self.roi_geometry_change_sgn.connect(
            self._mediator.onRoiGeometryChange)

    def setEditable(self, editable):
        for w in self._line_edits:
            w.setDisabled(not editable)

    @pyqtSlot(int)
    def onLock(self, state):
        self._roi.setLocked(state == Qt.Checked)
        self.setEditable(not state == Qt.Checked)

    def disableAllEdit(self):
        self.setEditable(False)
        self._lock_cb.setDisabled(True)

    def enableAllEdit(self):
        self._lock_cb.setDisabled(False)
        self.setEditable(True)