Skip to content

Arquivo app.py

O app.py é uma aplicação gráfica baseada na biblioteca PyQt5 que permite selecionar um arquivo de imagem ou vídeo e executar a detecção de objetos nele. O algoritmo de detecção de objetos utilizado é o YOLOv5, que é executado por meio da chamada do arquivo detect.py na pasta yolov5.

A aplicação gráfica apresenta uma barra de progresso e duas labels que são atualizadas durante a execução do processo. A primeira label informa o nome do arquivo selecionado e a segunda informa quando a imagem é detectada com sucesso. O código também inclui funções que realizam a cópia do arquivo selecionado para a pasta de entrada do algoritmo de detecção de objetos, a junção dos arquivos de saída do YOLOv5 (caso o processamento tenha gerado arquivos divididos), bem como a função de iniciar o processo de detecção.

Bibliotecas necessárias
  • sys para acessar variáveis e funções específicas do sistema;
  • os para interagir com o sistema operacional;
  • shutil para integrar com o sistema operacional (por exemplo, criar e manipular arquivos e pastas);
  • PyQt5 para criar janelas e widgets. QApplication é a classe principal para gerenciar a aplicação; QWidget é a classe base para todos os widgets em PyQt5; QFileDialog é usada para abrir caixas de diálogo para selecionar arquivos e pastas; QPushButton é um botão que pode ser clicado para executar uma ação; QProgressBar é uma barra de progresso que mostra o progresso de uma tarefa; QLabel é um rótulo que pode exibir texto e imagens;
  • PyQt5.QtGui importa a classe QPixmap do PyQt5, que é usada para carregar imagens.

App

Bases: QWidget

A classe App é uma subclasse da classe QWidget e é responsável por construir a interface gráfica do usuário para o programa FireVision 0.1.0.

Source code in firevision/app.py
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
class App(QWidget):
    """
        A classe `App` é uma subclasse da classe `QWidget` e é responsável por construir a interface gráfica do usuário para o programa FireVision 0.1.0.
    """

    def __init__(self):
        """
            O método `__init__()` é um método especial que é executado quando um objeto da classe `App` é criado. Neste caso, ele define as dimensões da janela e chama o método `LoadWindow()` para criar a interface gráfica.
        """
        super().__init__()
        self.title = "FireVision 0.1.0"
        self.left = 220
        self.top = 220
        self.width = 640
        self.height = 480
        self.LoadWindow()

    def LoadWindow(self):
        """
            O método `LoadWindow()` define a janela, incluindo o título, dimensões e widgets. Ele cria um botão "Selecionar Arquivo" e uma barra de progresso que serão usados posteriormente.
        """
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.step = 0
        self.progress = QProgressBar(self)
        self.progress.setGeometry(200, 250, 250, 20)

        button = QPushButton("Selecionar Arquivo", self)

        button.setToolTip("Clique para selecionar um arquivo")
        button.move(200, 150)
        button.clicked.connect(self.OpenFileDialog)

        self.pixmap = QPixmap('fogo.jpeg')
        self.label2 = QLabel('', self)
        self.label2.setStyleSheet('color: blue; font-size: 12px')
        self.label2.move(200, 180)

        self.label = QLabel('', self)
        self.label.setStyleSheet('color: green; font-size: 16px')
        self.label.move(200, 300)

        self.show()

    def join_files(self, input_filename, output_filename):
        """
            O método `join_files()` recebe dois parâmetros: `input_filename` e `output_filename`. Ele é responsável por juntar os arquivos de saída gerados pelo modelo de detecção de objeto YOLOv5 em um único arquivo. Esse método é chamado pelo método `OpenFileDialog()`.
        """
        with open(output_filename, 'wb') as f:
            i = 0
            while True:
                chunk_filename = f'{input_filename}.{i}'
                if os.path.exists(chunk_filename):
                    with open(chunk_filename, 'rb') as chunk_file:
                        chunk = chunk_file.read()
                        f.write(chunk)
                    i += 1
                else:
                    break

        print(
            f'Os arquivos {input_filename}.* foram juntados em {output_filename}')

    def start_process(self):
        """
            O método `start_process()` é responsável por definir a barra de progresso com um valor máximo de 100 e atualizar o valor da barra de progresso enquanto o programa está executando.
        """
        self.progress.setMaximum(100)

        while self.progress_value < 100:
            self.progress_value += 1
            self.progress.setValue(self.progress_value)
            QApplication.processEvents()

    def progressLoad(self):
        """
            O método `progressLoad()` é responsável por atualizar o valor da barra de progresso.
        """
        self.step += 20
        self.progress.setValue(self.step)

    def setLabel(self):
        """
            O método `setLabel()` define o texto de uma label da interface gráfica como "Imagem detectada com sucesso".
        """
        self.label.setText("Imagem detectada com sucesso")

    # def setSelectText(self):
    #     # self.pixmap = QPixmap("caminho_da_imagem.png")
    #     self.label2.setText("../teste/fogo.jpg")

    def OpenFileDialog(self):
        """
            O método `OpenFileDialog()` é chamado quando o botão "Selecionar Arquivo" é clicado. Ele usa o método `join_files()` para juntar os arquivos de saída gerados pelo modelo YOLOv5. Em seguida, ele abre um diálogo de seleção de arquivo para que o usuário possa escolher um arquivo de imagem. Ele atualiza a barra de progresso usando o método `progressLoad()` e copia o arquivo selecionado para uma pasta específica. Ele, então, executa o modelo YOLOv5 no arquivo de imagem selecionado usando o método `os.system()`. Finalmente, ele atualiza a barra de progresso novamente e define o texto de uma label para indicar que a imagem foi detectada com sucesso.
        """
        self.join_files("../yolov5/best.pt", "../yolov5/best.pt")

        filename, _ = QFileDialog.getOpenFileName(
            self, "Selecionar Arquivo", "", "Arquivos de Imagem (*.jpg *jpeg);;Arquivos de Vídeo (.mp4)")

        if filename:
            ex.progressLoad()
            data_folder = os.path.join("..", "yolov5", "data")
            images_folder = os.path.join(data_folder, "images")

            if not os.path.exists(images_folder):
                os.makedirs(images_folder)
            new_filename = os.path.join(
                images_folder, os.path.basename(filename))

            string = str(new_filename)
            self.label2.setText(string)

            shutil.copy2(filename, new_filename)
            ex.progressLoad()
            print(f"Cópia do arquivo salvo em {new_filename}")

        try:
            # Muda de diretório
            os.chdir("../yolov5")
            ex.progressLoad()
            ex.progressLoad()
            # Executa um comando no terminal
            os.system("python detect.py --source data/images --weights best.pt")
            ex.progressLoad()
            # Executa o script "detect.py" indicando o caminho runs/train/exp2/weights/best.pt:
            # os.system("python detect.py --source data/images --weights runs/train/exp2/weights/best.pt")
            # ex.start_process()
            ex.setLabel()

        except Exception as e:
            #print(f"Erro ao salvar arquivo: {e}")
            print(f"O arquivo foi criado na pasta images do yolov, porém no windows pode apresentar o erro: {e}")

LoadWindow()

O método LoadWindow() define a janela, incluindo o título, dimensões e widgets. Ele cria um botão "Selecionar Arquivo" e uma barra de progresso que serão usados posteriormente.

Source code in firevision/app.py
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
def LoadWindow(self):
    """
        O método `LoadWindow()` define a janela, incluindo o título, dimensões e widgets. Ele cria um botão "Selecionar Arquivo" e uma barra de progresso que serão usados posteriormente.
    """
    self.setWindowTitle(self.title)
    self.setGeometry(self.left, self.top, self.width, self.height)

    self.step = 0
    self.progress = QProgressBar(self)
    self.progress.setGeometry(200, 250, 250, 20)

    button = QPushButton("Selecionar Arquivo", self)

    button.setToolTip("Clique para selecionar um arquivo")
    button.move(200, 150)
    button.clicked.connect(self.OpenFileDialog)

    self.pixmap = QPixmap('fogo.jpeg')
    self.label2 = QLabel('', self)
    self.label2.setStyleSheet('color: blue; font-size: 12px')
    self.label2.move(200, 180)

    self.label = QLabel('', self)
    self.label.setStyleSheet('color: green; font-size: 16px')
    self.label.move(200, 300)

    self.show()

OpenFileDialog()

O método OpenFileDialog() é chamado quando o botão "Selecionar Arquivo" é clicado. Ele usa o método join_files() para juntar os arquivos de saída gerados pelo modelo YOLOv5. Em seguida, ele abre um diálogo de seleção de arquivo para que o usuário possa escolher um arquivo de imagem. Ele atualiza a barra de progresso usando o método progressLoad() e copia o arquivo selecionado para uma pasta específica. Ele, então, executa o modelo YOLOv5 no arquivo de imagem selecionado usando o método os.system(). Finalmente, ele atualiza a barra de progresso novamente e define o texto de uma label para indicar que a imagem foi detectada com sucesso.

Source code in firevision/app.py
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
def OpenFileDialog(self):
    """
        O método `OpenFileDialog()` é chamado quando o botão "Selecionar Arquivo" é clicado. Ele usa o método `join_files()` para juntar os arquivos de saída gerados pelo modelo YOLOv5. Em seguida, ele abre um diálogo de seleção de arquivo para que o usuário possa escolher um arquivo de imagem. Ele atualiza a barra de progresso usando o método `progressLoad()` e copia o arquivo selecionado para uma pasta específica. Ele, então, executa o modelo YOLOv5 no arquivo de imagem selecionado usando o método `os.system()`. Finalmente, ele atualiza a barra de progresso novamente e define o texto de uma label para indicar que a imagem foi detectada com sucesso.
    """
    self.join_files("../yolov5/best.pt", "../yolov5/best.pt")

    filename, _ = QFileDialog.getOpenFileName(
        self, "Selecionar Arquivo", "", "Arquivos de Imagem (*.jpg *jpeg);;Arquivos de Vídeo (.mp4)")

    if filename:
        ex.progressLoad()
        data_folder = os.path.join("..", "yolov5", "data")
        images_folder = os.path.join(data_folder, "images")

        if not os.path.exists(images_folder):
            os.makedirs(images_folder)
        new_filename = os.path.join(
            images_folder, os.path.basename(filename))

        string = str(new_filename)
        self.label2.setText(string)

        shutil.copy2(filename, new_filename)
        ex.progressLoad()
        print(f"Cópia do arquivo salvo em {new_filename}")

    try:
        # Muda de diretório
        os.chdir("../yolov5")
        ex.progressLoad()
        ex.progressLoad()
        # Executa um comando no terminal
        os.system("python detect.py --source data/images --weights best.pt")
        ex.progressLoad()
        # Executa o script "detect.py" indicando o caminho runs/train/exp2/weights/best.pt:
        # os.system("python detect.py --source data/images --weights runs/train/exp2/weights/best.pt")
        # ex.start_process()
        ex.setLabel()

    except Exception as e:
        #print(f"Erro ao salvar arquivo: {e}")
        print(f"O arquivo foi criado na pasta images do yolov, porém no windows pode apresentar o erro: {e}")

__init__()

O método __init__() é um método especial que é executado quando um objeto da classe App é criado. Neste caso, ele define as dimensões da janela e chama o método LoadWindow() para criar a interface gráfica.

Source code in firevision/app.py
22
23
24
25
26
27
28
29
30
31
32
def __init__(self):
    """
        O método `__init__()` é um método especial que é executado quando um objeto da classe `App` é criado. Neste caso, ele define as dimensões da janela e chama o método `LoadWindow()` para criar a interface gráfica.
    """
    super().__init__()
    self.title = "FireVision 0.1.0"
    self.left = 220
    self.top = 220
    self.width = 640
    self.height = 480
    self.LoadWindow()

join_files(input_filename, output_filename)

O método join_files() recebe dois parâmetros: input_filename e output_filename. Ele é responsável por juntar os arquivos de saída gerados pelo modelo de detecção de objeto YOLOv5 em um único arquivo. Esse método é chamado pelo método OpenFileDialog().

Source code in firevision/app.py
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
def join_files(self, input_filename, output_filename):
    """
        O método `join_files()` recebe dois parâmetros: `input_filename` e `output_filename`. Ele é responsável por juntar os arquivos de saída gerados pelo modelo de detecção de objeto YOLOv5 em um único arquivo. Esse método é chamado pelo método `OpenFileDialog()`.
    """
    with open(output_filename, 'wb') as f:
        i = 0
        while True:
            chunk_filename = f'{input_filename}.{i}'
            if os.path.exists(chunk_filename):
                with open(chunk_filename, 'rb') as chunk_file:
                    chunk = chunk_file.read()
                    f.write(chunk)
                i += 1
            else:
                break

    print(
        f'Os arquivos {input_filename}.* foram juntados em {output_filename}')

progressLoad()

O método progressLoad() é responsável por atualizar o valor da barra de progresso.

Source code in firevision/app.py
92
93
94
95
96
97
def progressLoad(self):
    """
        O método `progressLoad()` é responsável por atualizar o valor da barra de progresso.
    """
    self.step += 20
    self.progress.setValue(self.step)

setLabel()

O método setLabel() define o texto de uma label da interface gráfica como "Imagem detectada com sucesso".

Source code in firevision/app.py
 99
100
101
102
103
def setLabel(self):
    """
        O método `setLabel()` define o texto de uma label da interface gráfica como "Imagem detectada com sucesso".
    """
    self.label.setText("Imagem detectada com sucesso")

start_process()

O método start_process() é responsável por definir a barra de progresso com um valor máximo de 100 e atualizar o valor da barra de progresso enquanto o programa está executando.

Source code in firevision/app.py
81
82
83
84
85
86
87
88
89
90
def start_process(self):
    """
        O método `start_process()` é responsável por definir a barra de progresso com um valor máximo de 100 e atualizar o valor da barra de progresso enquanto o programa está executando.
    """
    self.progress.setMaximum(100)

    while self.progress_value < 100:
        self.progress_value += 1
        self.progress.setValue(self.progress_value)
        QApplication.processEvents()