Пример #1
0
class AddUserFace(QDialog):
    def __init__(self, image):
        super(AddUserFace, self).__init__()
        self.setFixedSize(300, 275)
        self.setWindowIcon(QIcon('icons/add.png'))
        self.setWindowTitle('添加')

        self.rb_select = QRadioButton("选择", self)
        self.rb_select.setGeometry(70, 20, 50, 26)
        self.rb_select.toggled.connect(self.toggle)

        self.rb_new = QRadioButton('新建', self)
        self.rb_new.setGeometry(120, 20, 50, 26)
        self.rb_new.toggled.connect(self.toggle)

        lbl_name = QLabel('名称', self)
        lbl_name.setGeometry(10, 70, 50, 26)
        lbl_name.setAlignment(Qt.AlignCenter)

        users = DbHelper.query_users()

        self.cb_user = QComboBox(self)
        self.cb_user.setGeometry(70, 70, 200, 26)
        self.le_user = QLineEdit(self)
        self.le_user.setGeometry(70, 70, 200, 26)

        if users is not None and len(users) > 0:
            self.rb_select.setChecked(True)
            for user in users:
                self.cb_user.addItem(user[1], userData=user)
        else:
            self.rb_select.setDisabled(True)
            self.rb_new.setChecked(True)

        lbl_face = QLabel('人脸', self)
        lbl_face.setGeometry(10, 140, 50, 26)
        lbl_face.setAlignment(Qt.AlignCenter)

        self.btn_save = QPushButton(self)
        self.btn_save.setText('保存')
        self.btn_save.setGeometry(10, 234, 280, 30)
        self.btn_save.clicked.connect(self.save)

        self.cache_faces = {}
        self.face = None

        faces = HaarcascadeDetective.get_faces(image)
        index = 0
        for face in faces:
            viewer_face = QPushButton(self)
            viewer_face.setGeometry(70 * (index + 1), 120, 60, 60)
            viewer_face.setIconSize(QSize(56, 56))
            img = cv2.cvtColor(face, cv2.COLOR_BGR2RGB)
            image = QImage(img, img.shape[1], img.shape[0], img.shape[1] * 3,
                           QImage.Format_RGB888)
            pix_map = QPixmap.fromImage(image)
            viewer_face.setIcon(QIcon(pix_map))
            viewer_face.clicked.connect(self.select_face)
            self.cache_faces[viewer_face] = face
            if index == 0:
                self.face = face
                viewer_face.setStyleSheet(
                    'border-color: rgb(255, 0, 0);border-style: outset;border-width: 2px;'
                )
            index += 1
            if index > 3:
                break

        if index == 0:
            Tool.show_msg_box("未检测到人脸信息")

    def select_face(self):
        sender = self.sender()
        for btn in self.cache_faces:
            btn.setStyleSheet('border-style: none')
        sender.setStyleSheet(
            "border-color: rgb(255, 0, 0);border-style: outset;border-width: 2px;"
        )
        self.face = self.cache_faces[btn]

    def toggle(self):
        if self.rb_new.isChecked():
            self.cb_user.hide()
            self.le_user.show()
        elif self.rb_select.isChecked():
            self.le_user.hide()
            self.cb_user.show()

    def save(self):
        if self.face is None:
            return
        self.btn_save.setDisabled(True)
        if self.rb_new.isChecked():
            user_name = self.le_user.text().strip(' ')
            if not user_name.replace(' ', '').encode("utf-8").isalpha():
                Tool.show_msg_box('只支持英文字母和空格~')
                self.le_name.setFocus()
                return
            user_id = DbHelper.insert_user(user_name)
        else:
            user_id = self.cb_user.currentData()[0]
        if not os.path.exists("faces"):
            os.mkdir("faces")
        if not os.path.exists('faces/{}'.format(user_id)):
            os.mkdir('faces/{}'.format(user_id))
        face = 'faces/{}/{}.png'.format(user_id, time.time())
        cv2.imwrite(face, self.face)
        self.close()
Пример #2
0
class DownloadComponent(QGroupBox):
    reportFormatChanged = Signal(ReportWriter)
    saveCompleted = Signal(bool)

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

        self._report_writer = None
        self._report_writer_thread = ReportWriterThread()
        self._report_writer_thread.completed.connect(self._saveCompleted)
        
        self._progress_message = ProgressMessageBox(self.parentWidget(), "Export des données en cours...", "Export des données en cours...", 0, 0)

        self._report_types = {
            "summary": {"name": "Résumé", "description": "Le résumé inclu les statistiques générales sur les images analysées"},
            "full": {"name": "Complet", "description": "Le rapport complet inclu les statistiques détaillées sur les images analysées"},
            "annotations": {"name": "Annotations", "description": "Converti les résultats de l'analyse en annotation utilisable pour l'entrainement"}
        }
        self._report_formats = {
            "summary": {
                "PDF": {"type": "Document PDF", "extension": "*.pdf"},
                "Texte": {"type": "Fichier texte", "extension": "*.txt"}
            },
            "full": {
                "CSV": {"type": "Fichier CSV", "extension": "*.csv"},
                "JSON": {"type": "Fichier JSON", "extension": "*.json"},
                "XML": {"type": "Fichier XML", "extension": "*.xml"},
            },
            "annotations": {
                "Annotations YOLOv4": {"type": "Fichier zip", "extension": "*.zip"}
            }
        }
        self._default_report_type = "summary"

        self.setTitle("Paramètres")
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)

        self._form_layout = QFormLayout()
        self._form_layout.setHorizontalSpacing(20)
        self._form_layout.setVerticalSpacing(14)

        self._report_type_cbox = QComboBox()
        for report_type, v in self._report_types.items():
            self._report_type_cbox.addItem(v["name"], report_type)

        self._form_layout.addRow("Type de rapport :", self._report_type_cbox)

        self._info_text = QLabel(self._report_types[self._default_report_type]["description"])
        self._info_text.setObjectName("info")
        self._form_layout.addRow(self._info_text)

        self._report_format_cbox = QComboBox()
        for format, data in self._report_formats[self._default_report_type].items():
            self._report_format_cbox.addItem(format, data)

        self._form_layout.addRow("Format du rapport :", self._report_format_cbox)

        self._detection_shape_cbox = QComboBox()
        self._detection_shape_cbox.addItem("Rectangle", "rectangle")
        self._detection_shape_cbox.addItem("Cercle", "circle")
        self._detection_shape_cbox.hide()

        self._separator_cbox = QComboBox()
        self._separator_cbox.addItem("Point virgule", ";")
        self._separator_cbox.addItem("Virgule", ",")
        self._separator_cbox.hide()

        self._nb_keeped_spinbox = QSpinBox(self)
        self._nb_keeped_spinbox.setRange(1, 1)
        self._nb_keeped_spinbox.hide()

        download_button = StylizedButton("Télécharger", "blue")
        download_button.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)

        button_layout = QHBoxLayout()
        button_layout.setAlignment(Qt.AlignRight)
        button_layout.addWidget(download_button)

        main_layout = QVBoxLayout(self)
        main_layout.addLayout(self._form_layout)
        main_layout.addStretch(1)
        main_layout.addLayout(button_layout)

        # Signals
        download_button.clicked.connect(self._exportReport)
        self._report_type_cbox.currentIndexChanged.connect(self._reportTypeChanged)
        self._report_format_cbox.currentTextChanged.connect(self._reportFormatChanged)
        self._detection_shape_cbox.currentIndexChanged.connect(self._reportParamsChanged)
        self._separator_cbox.currentIndexChanged.connect(self._reportParamsChanged)

    def reset(self, analysis: Analysis):
        self._analysis = analysis

        self._report_type_cbox.setCurrentIndex(0)
        self._report_format_cbox.setCurrentIndex(0)
        self._nb_keeped_spinbox.setMaximum(analysis.imagesWithDetections())
        self._nb_keeped_spinbox.setValue(min(100, analysis.imagesWithDetections()))
        self._loadWriter()

    def _loadWriter(self):
        format_text = self._report_format_cbox.currentText()
        if format_text == "PDF":
            self._report_writer = PDFReportWriter(self._analysis)
        
        elif format_text == "Texte":
            self._report_writer = TextReportWriter(self._analysis)

        elif format_text == "CSV":
            self._report_writer = CSVReportWriter(self._analysis, self._separator_cbox.currentData(), self._detection_shape_cbox.currentData())

        elif format_text == "JSON":
            self._report_writer = JSONReportWriter(self._analysis, shape=self._detection_shape_cbox.currentData())
        
        elif format_text == "XML":
            self._report_writer = XMLReportWriter(self._analysis, shape=self._detection_shape_cbox.currentData())

        elif format_text == "Annotations YOLOv4":
            self._report_writer = Yolov4AnnotationsWriter(self._analysis)

        self.reportFormatChanged.emit(self._report_writer)

    @Slot(int)
    def _reportTypeChanged(self, index: int):
        report_type = self._report_type_cbox.currentData()
        self._info_text.setText(self._report_types[report_type]["description"])

        self._report_format_cbox.clear()
        for format, data in self._report_formats[report_type].items():
            self._report_format_cbox.addItem(format, data)

        if report_type == "summary":
            self._showDetectionShape(False)
            self._showSeparator(False)
            self._showKeepedNumber(False)
        elif report_type == "full":
            self._showDetectionShape(True)
            self._showKeepedNumber(False)
        elif report_type == "annotations":
            self._showDetectionShape(False)
            self._showSeparator(False)
            self._showKeepedNumber(True)
    
    @Slot(str)
    def _reportFormatChanged(self, format: str):
        if format == "CSV":
            self._showSeparator(True)
        else: # JSON & XSML
            self._showSeparator(False)

        self._loadWriter()

    def _showDetectionShape(self, show: bool):
        self._showRow("Détection :", self._detection_shape_cbox, show)

    def _showSeparator(self, show: bool):
        self._showRow("Séparateur :", self._separator_cbox, show)

    def _showKeepedNumber(self, show: bool):
        self._showRow("Images à exporter :", self._nb_keeped_spinbox, show)

    def _showRow(self, label: str, widget: QWidget, show: bool):
        if show and not widget.isVisible():
            widget.show()
            self._form_layout.addRow(label, widget)
        elif not show and widget.isVisible():
            label = self._form_layout.labelForField(widget)
            widget.hide()
            label.hide()
            self._form_layout.removeWidget(widget)
            self._form_layout.removeWidget(label)
            del label

    @Slot(int)
    def _reportParamsChanged(self, index: int):
        self._loadWriter()

    @Slot()
    def _exportReport(self):
        report_type = self._report_type_cbox.currentData()
        if report_type == "annotations":
            self._report_writer.setKeep(self._nb_keeped_spinbox.value())

        error = self._report_writer.checkErrors()
        if error:
            QMessageBox.warning(self.parentWidget(), "Impossible de générer le rapport", error)
            return

        filename = self._analysis.parameters().name()
        report_format = self._report_format_cbox.currentData()

        path = QStandardPaths.writableLocation(QStandardPaths.DocumentsLocation) + "/" + filename
        filter = "Fichier %s (%s)" % (report_format["type"], report_format["extension"])

        result = QFileDialog.getSaveFileName(self, "Enregistrer le fichier", path, filter)
        
        filepath = result[0]
        if filepath == '':
            return

        self._report_writer_thread.start(self._report_writer, filepath)
        self._progress_message.exec_()

    @Slot()
    def _saveCompleted(self, success: bool):
        if self._progress_message:
            self._progress_message.close()
        
        self.saveCompleted.emit(success)