import os os.environ['TF_ENABLE_ONEDNN_OPTS'] = '0' import tkinter as tk from tkinter import filedialog import customtkinter import cv2 from cv2 import dnn from pydub import AudioSegment from PIL import Image, ImageTk,ImageOps import threading from glob import glob import sounddevice as sd import wavio import re import pygame from tkinter import ttk, Canvas import whisper import webbrowser import pyaudio import wave from moviepy.editor import * import librosa from librosa import load import librosa.display from librosa.feature import mfcc from transformers import pipeline import IPython.display as ipd from collections import defaultdict from tkcalendar import DateEntry import speech_recognition as sr import numpy as np import sys import shutil import geocoder import logging import time from tensorflow.keras.models import load_model from tensorflow.image import resize from math import ceil import subprocess import matplotlib.pyplot as plt from pyannote.audio import Pipeline import matplotlib matplotlib.use("Agg") from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from reportlab.lib.pagesizes import letter, A4, landscape from moviepy.video.fx.all import speedx from reportlab.pdfgen import canvas from reportlab.lib.colors import red, black, Color from PyPDF2 import PdfMerger from reportlab.platypus import SimpleDocTemplate, Table, TableStyle,Spacer, PageBreak, Image as ReportImage from reportlab.platypus.flowables import PageBreak from reportlab.lib import colors import pandas as pd import tabula import PyPDF2 import torch import string from pdf2docx import Converter import urllib.parse from fpdf import FPDF import pdfplumber from datetime import datetime import fitz import warnings from reportlab.lib.units import inch from docx import Document from moviepy.config import change_settings import joblib import spacy change_settings({"IMAGEMAGICK_BINARY": "C:\\Program Files\\ImageMagick-7.1.1-Q16-HDRI\\magick.exe"}) image_mean = np.array([127, 127, 127]) image_std = 128.0 iou_threshold = 0.3 center_variance = 0.1 size_variance = 0.2 min_boxes = [[10.0, 16.0, 24.0], [32.0, 48.0], [64.0, 96.0], [128.0, 192.0, 256.0]] strides = [8.0, 16.0, 32.0, 64.0] threshold = 0.5 customtkinter.set_appearance_mode("Dark") pdf_path ="" g = geocoder.ip('me') Local="PJM Lisboa" City=g.city agora = datetime.now() Datainterrogatorio = agora Datainterrogatorio = agora.strftime("%d/%m/%Y") Hour=agora.strftime("%H") Minutes=agora.strftime("%M") hora = agora.strftime("%H:%M") resultados={} Nome, nim, posto, DTnasc, cc, ccval, nif, pai, mae, morada, imagem,Interrogador, vetoremocoes,vetoremocoesFER,a, codigo_postal, freguesia, concelho, Nacionalidade, data_atual =[None]*20 def preprocess_frase_pt(frase): nlp = spacy.load("pt_core_news_sm") portuguesstopwords = set(nlp.Defaults.stop_words) if not isinstance(frase, str): raise ValueError("A entrada deve ser uma string.") frase = frase.lower() frase = frase.translate(str.maketrans('', '', string.punctuation)) frase = ''.join([char for char in frase if not char.isdigit()]) frase = ' '.join(frase.split()) frase = ' '.join([word for word in frase.split() if word not in portuguesstopwords]) frase_lemmatizada = ' '.join([token.lemma_ for token in nlp(frase)]) return frase_lemmatizada def preencheraintestemunha(caminho_docx, dados, caminho_saida): doc = Document(caminho_docx) for paragrafo in doc.paragraphs: for marcador, valor in dados.items(): if marcador in paragrafo.text: for run in paragrafo.runs: if marcador in run.text: run.text = run.text.replace(marcador, valor) for tabela in doc.tables: for linha in tabela.rows: for celula in linha.cells: for marcador, valor in dados.items(): if marcador in celula.text: for paragrafo in celula.paragraphs: for run in paragrafo.runs: if marcador in run.text: run.text = run.text.replace(marcador, valor) for section in doc.sections: header = section.header footer = section.footer for paragrafo in header.paragraphs: for marcador, valor in dados.items(): if marcador in paragrafo.text: for run in paragrafo.runs: if marcador in run.text: run.text = run.text.replace(marcador, valor) for paragrafo in footer.paragraphs: for marcador, valor in dados.items(): if marcador in paragrafo.text: for run in paragrafo.runs: if marcador in run.text: run.text = run.text.replace(marcador, valor) doc.save(caminho_saida) print(f"Documento preenchido salvo em: {caminho_saida}") def juntapdfs2(): pdf1="C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\transcricao_audio.pdf" pdf2="C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\Anexo_A.pdf" pdf3 = "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\ANEXO_B_C.pdf" outputpdf="C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\TranscriptWithAER&FER.pdf" try: merger = PdfMerger() merger.append(pdf1) merger.append(pdf2) merger.append(pdf3) with open(outputpdf, 'wb') as output_file: merger.write(output_file) merger.close() print(f"PDFs combinados com sucesso em {outputpdf}") except Exception as e: print(f"Erro ao juntar os PDFs: {e}") def define_img_size(image_size): shrinkage_list = [] feature_map_w_h_list = [] for size in image_size: feature_map = [int(ceil(size / stride)) for stride in strides] feature_map_w_h_list.append(feature_map) for i in range(0, len(image_size)): shrinkage_list.append(strides) priors = generate_priors( feature_map_w_h_list, shrinkage_list, image_size, min_boxes ) return priors def generate_priors(feature_map_list, shrinkage_list, image_size, min_boxes): priors = [] for index in range(0, len(feature_map_list[0])): scale_w = image_size[0] / shrinkage_list[0][index] scale_h = image_size[1] / shrinkage_list[1][index] for j in range(0, feature_map_list[1][index]): for i in range(0, feature_map_list[0][index]): x_center = (i + 0.5) / scale_w y_center = (j + 0.5) / scale_h for min_box in min_boxes[index]: w = min_box / image_size[0] h = min_box / image_size[1] priors.append([x_center,y_center,w,h]) print("priors nums:{}".format(len(priors))) return np.clip(priors, 0.0, 1.0) def hard_nms(box_scores, iou_threshold, top_k=-1, candidate_size=200): scores = box_scores[:, -1] boxes = box_scores[:, :-1] picked = [] indexes = np.argsort(scores) indexes = indexes[-candidate_size:] while len(indexes) > 0: current = indexes[-1] picked.append(current) if 0 < top_k == len(picked) or len(indexes) == 1: break current_box = boxes[current, :] indexes = indexes[:-1] rest_boxes = boxes[indexes, :] iou = iou_of(rest_boxes,np.expand_dims(current_box, axis=0),) indexes = indexes[iou <= iou_threshold] return box_scores[picked, :] def area_of(left_top, right_bottom): hw = np.clip(right_bottom - left_top, 0.0, None) return hw[..., 0] * hw[..., 1] def iou_of(boxes0, boxes1, eps=1e-5): overlap_left_top = np.maximum(boxes0[..., :2], boxes1[..., :2]) overlap_right_bottom = np.minimum(boxes0[..., 2:], boxes1[..., 2:]) overlap_area = area_of(overlap_left_top, overlap_right_bottom) area0 = area_of(boxes0[..., :2], boxes0[..., 2:]) area1 = area_of(boxes1[..., :2], boxes1[..., 2:]) return overlap_area / (area0 + area1 - overlap_area + eps) def predict(width,height,confidences,boxes, prob_threshold,iou_threshold=0.3,top_k=-1): boxes = boxes[0] confidences = confidences[0] picked_box_probs = [] picked_labels = [] for class_index in range(1, confidences.shape[1]): probs = confidences[:, class_index] mask = probs > prob_threshold probs = probs[mask] if probs.shape[0] == 0: continue subset_boxes = boxes[mask, :] box_probs = np.concatenate( [subset_boxes, probs.reshape(-1, 1)], axis=1) box_probs = hard_nms(box_probs,iou_threshold=iou_threshold, top_k=top_k,) picked_box_probs.append(box_probs) picked_labels.extend([class_index] * box_probs.shape[0]) if not picked_box_probs: return np.array([]), np.array([]), np.array([]) picked_box_probs = np.concatenate(picked_box_probs) picked_box_probs[:, 0] *= width picked_box_probs[:, 1] *= height picked_box_probs[:, 2] *= width picked_box_probs[:, 3] *= height return ( picked_box_probs[:, :4].astype(np.int32), np.array(picked_labels), picked_box_probs[:, 4] ) def convert_locations_to_boxes(locations, priors, center_variance, size_variance): if len(priors.shape) + 1 == len(locations.shape): priors = np.expand_dims(priors, 0) return np.concatenate([ locations[..., :2] * center_variance * priors[..., 2:] + priors[..., :2], np.exp(locations[..., 2:] * size_variance) * priors[..., 2:] ], axis=len(locations.shape) - 1) def center_form_to_corner_form(locations): return np.concatenate( [locations[..., :2] - locations[..., 2:] / 2, locations[..., :2] + locations[..., 2:] / 2], len(locations.shape) - 1 ) def FER_live_cam(): emotion_dict = {0: 'neutral', 1: 'happiness', 2: 'surprise', 3: 'sadness',4: 'anger', 5: 'disgust', 6: 'fear'} def modelemotionface(parent_frame,parent_frame2): cap = cv2.VideoCapture(1) frame_width = int(cap.get(3)) frame_height = int(cap.get(4)) size = (frame_width, frame_height) result = cv2.VideoWriter('C:/Users/garci/OneDrive/Área de Trabalho/Programa PJM/Programa final/FERVideo.mp4', cv2.VideoWriter_fourcc(*'MJPG'), 10, size) emotion_dict = {0: 'neutral', 1: 'happiness', 2: 'surprise', 3: 'sadness', 4: 'anger', 5: 'disgust', 6: 'fear'} emotion_colors = {'neutral': (255, 255, 255), 'happiness': (0, 255, 0), 'surprise': (255, 255, 0), 'sadness': (0, 0, 255), 'anger': (0, 0, 128), 'disgust': (128, 0, 128), 'fear': (255, 0, 0)} model = cv2.dnn.readNetFromONNX('C:/Users/garci/Downloads/emotion-ferplus-8.onnx') proto_path = 'C:/Users/garci/Downloads/RFB-320.prototxt' model_path = 'C:/Users/garci/Downloads/RFB-320.caffemodel' net = cv2.dnn.readNetFromCaffe(proto_path, model_path) emotion_counter = {emotion: 0 for emotion in emotion_dict.values()} current_emotion = None audio = pyaudio.PyAudio() stream = audio.open(input=True, format=pyaudio.paInt16, channels=2, rate=16000, frames_per_buffer=1024) frames_audio = [] input_size = [320, 240] width, height = input_size priors = define_img_size(input_size) while cap.isOpened(): ret, frame = cap.read() if ret: img_ori = frame rect = cv2.resize(img_ori, (width, height)) rect = cv2.cvtColor(rect, cv2.COLOR_BGR2RGB) net.setInput(cv2.dnn.blobFromImage(rect, 1 / 127.5, (width, height), 127)) boxes, scores = net.forward(["boxes", "scores"]) boxes = np.expand_dims(np.reshape(boxes, (-1, 4)), axis=0) scores = np.expand_dims(np.reshape(scores, (-1, 2)), axis=0) boxes = convert_locations_to_boxes(boxes, priors, 0.1, 0.2) boxes = center_form_to_corner_form(boxes) boxes, labels, probs = predict(img_ori.shape[1], img_ori.shape[0], scores, boxes, 0.5) gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) for (x1, y1, x2, y2) in boxes: w, h = x2 - x1, y2 - y1 cv2.rectangle(frame, (x1, y1), (x2, y2), (255, 0, 0), 2) face = cv2.resize(gray[y1:y1 + h, x1:x1 + w], (64, 64)).reshape(1, 1, 64, 64) model.setInput(face) output = model.forward() pred_index = np.argmax(output[0]) pred_emotion = emotion_dict[pred_index] color = emotion_colors[pred_emotion] if pred_emotion != current_emotion: current_emotion = pred_emotion emotion_counter[pred_emotion] += 1 cv2.rectangle(img_ori, (x1, y1), (x2, y2), color, 2, lineType=cv2.LINE_AA) cv2.putText(frame, pred_emotion, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, color, 2, lineType=cv2.LINE_AA) result.write(frame) cv2.imshow('Camera', frame) audio_data = stream.read(1024) frames_audio.append(audio_data) if cv2.waitKey(1) & 0xFF == ord('q'): break else: break cap.release() result.release() stream.stop_stream() stream.close() audio.terminate() audiopath = "C:/Users/garci/OneDrive/Área de Trabalho/Programa PJM/Programa final/audio.mp3" with wave.open(audiopath, 'wb') as wf: wf.setnchannels(2) wf.setsampwidth(audio.get_sample_size(pyaudio.paInt16)) wf.setframerate(16000) wf.writeframes(b''.join(frames_audio)) atualizar_grafico_emocoes(emotion_counter, parent_frame) print("Emotions detected during the video:") for emotion, count in emotion_counter.items(): print(f"{emotion}: {count}") video_path='C:/Users/garci/OneDrive/Área de Trabalho/Programa PJM/Programa final/FERVideo.mp4' anexoA(audiopath) dividirvideoclips(video_path) clipes = dividiraudioclips(audiopath) classificar_clipes(clipes,parent_frame2) classificar_videoclipes() sincronizarvideoaudio() criarvetoremocoesFER() juntapdfs2() copiarficheiro() def modelemotionface_video(video_path,parent_frame): cap = cv2.VideoCapture(video_path) frame_width = int(cap.get(3)) frame_height = int(cap.get(4)) size = (frame_width, frame_height) result = cv2.VideoWriter('C:/Users/garci/OneDrive/Área de Trabalho/Programa PJM/Programa final/Video.avi', cv2.VideoWriter_fourcc(*'MJPG'), 10, size) emotion_dict = {0: 'neutral', 1: 'happiness', 2: 'surprise', 3: 'sadness', 4: 'anger', 5: 'disgust', 6: 'fear'} emotion_colors = {'neutral': (255, 255, 255), 'happiness': (0, 255, 0), 'surprise': (255, 255, 0),'sadness': (0, 0, 255), 'anger': (0, 0, 128), 'disgust': (128, 0, 128), 'fear': (255, 0, 0)} emotion_model = cv2.dnn.readNetFromONNX('C:/Users/garci/Downloads/emotion-ferplus-8.onnx') model_path = 'C:/Users/garci/Downloads/RFB-320.caffemodel' proto_path = 'C:/Users/garci/Downloads/RFB-320.prototxt' net = cv2.dnn.readNetFromCaffe(proto_path, model_path) input_size = [320, 240] width, height = input_size priors = define_img_size(input_size) emotion_counter = {emotion: 0 for emotion in emotion_dict.values()} current_emotion = None while cap.isOpened(): ret, frame = cap.read() if not ret: break rect = cv2.resize(frame, (width, height)) rect_rgb = cv2.cvtColor(rect, cv2.COLOR_BGR2RGB) net.setInput(cv2.dnn.blobFromImage(rect_rgb, 1 / 127.5, (width, height), 127)) boxes, scores = net.forward(["boxes", "scores"]) boxes = np.expand_dims(np.reshape(boxes, (-1, 4)), axis=0) scores = np.expand_dims(np.reshape(scores, (-1, 2)), axis=0) boxes = convert_locations_to_boxes(boxes, priors, 0.1, 0.2) boxes = center_form_to_corner_form(boxes) boxes, labels, probs = predict(frame.shape[1], frame.shape[0], scores, boxes, 0.5) gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) for (x1, y1, x2, y2) in boxes: w, h = x2 - x1, y2 - y1 cv2.rectangle(frame, (x1, y1), (x2, y2), (255, 0, 0), 2) face_region = cv2.resize(gray[y1:y1 + h, x1:x1 + w], (64, 64)).reshape(1, 1, 64, 64) emotion_model.setInput(face_region) output = emotion_model.forward() pred_index = np.argmax(output[0]) pred_emotion = emotion_dict[pred_index] color = emotion_colors[pred_emotion] if pred_emotion != current_emotion: current_emotion = pred_emotion emotion_counter[pred_emotion] += 1 cv2.rectangle(frame, (x1, y1), (x2, y2), color, 2, lineType=cv2.LINE_AA) cv2.putText(frame, pred_emotion, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, color, 2, lineType=cv2.LINE_AA) result.write(frame) cv2.imshow('Video FER', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() result.release() atualizar_grafico_emocoes(emotion_counter, parent_frame) video_clip = VideoFileClip('C:/Users/garci/OneDrive/Área de Trabalho/Programa PJM/Programa final/Video.avi') video_clip.write_videofile("C:/Users/garci/OneDrive/Área de Trabalho/Programa PJM/Programa final/FERVideo.mp4", codec="libx264", audio_codec="aac") print("Contagem de emoções detectadas durante o vídeo:") for emotion, count in emotion_counter.items(): print(f"{emotion}: {count}") if __name__ == "__main__": FER_live_cam() def wrap_text(text, max_length=400): words = text.split() lines = [] current_line = [] for word in words: if len(" ".join(current_line + [word])) <= max_length: current_line.append(word) else: lines.append(" ".join(current_line)) current_line = [word] if current_line: lines.append(" ".join(current_line)) return "\n".join(lines) def mostrar_dados(parent_frame): dados = Nome, nim, posto, DTnasc, cc, ccval, nif, pai, mae, morada, imagem, codigo_postal, freguesia, concelho, Morada, Nacionalidade dados_para_preencher = { "NUIPC1": "1234", "Equipa1": "Equipe A", "NomeIC": "João Silva", "DTD": str(Datainterrogatorio), "Hora1": str(hora), "LOCAL1": str(Local), "Name1": f"{Nome.title()}", "Posto1": str(posto), "NIM1": str(nim), "Filiacao1": f"{pai.title()} e de {mae.title()}", "Morada1": str(morada), "CP1": str(codigo_postal), "Freguesia1": str(freguesia), "Conc1": f"{concelho.title()}", "DN": str(DTnasc), "NCC": str(cc), "CCVal": str(ccval), "NIF1": str(nif), "Nacionalidade1":str(Nacionalidade) } caminho_saida = "C:/Users/garci/OneDrive/Área de Trabalho/Programa PJM/Programa final/Dataset/6_ainqtestemunha_Final.docx" preencheraintestemunha("C:/Users/garci/OneDrive/Área de Trabalho/Programa PJM/Programa final/Dataset/6_ainqtestemunha.docx", dados_para_preencher,caminho_saida) caminho_saida2 = "C:/Users/garci/OneDrive/Área de Trabalho/Programa PJM/Programa final/Dataset/3_aintarg_Final.docx" preencheraintestemunha("C:/Users/garci/OneDrive/Área de Trabalho/Programa PJM/Programa final/Dataset/3_aintarg.docx", dados_para_preencher, caminho_saida2) caminho_saida3 = "C:/Users/garci/OneDrive/Área de Trabalho/Programa PJM/Programa final/Dataset/2_auto_de_denuncia_Final.docx" preencheraintestemunha("C:/Users/garci/OneDrive/Área de Trabalho/Programa PJM/Programa final/Dataset/2_auto_de_denuncia.docx", dados_para_preencher, caminho_saida3) for widget in parent_frame.winfo_children(): widget.destroy() canvas = Canvas(parent_frame, width=600, height=400, bg="#2B2B2B", highlightthickness=0) canvas.grid(row=0, column=0, sticky="nsew") Postonimnome=posto+" "+nim+ " " +Nome cceval=cc+" válido até "+ccval labels = [("Nome", Postonimnome),("Data de Nascimento", DTnasc),("Cartão de Cidadão", cceval),("NIF", nif),("Pai", pai),("Mãe", mae),("Morada", Morada)] y_position=10 for label_text, value in labels: label = f"{label_text}: {value}" wrapped_label = wrap_text(label, max_length=80) canvas.create_text(10, y_position, anchor="nw", text=wrapped_label, font=("Arial", 10), fill="white") y_position += 40 try: if imagem: img = Image.open(imagem) img = img.resize((150, 150)) img_tk = ImageTk.PhotoImage(img) canvas.create_image(550, 10, anchor="ne", image=img_tk) canvas.image = img_tk except Exception as e: print(f"Erro ao carregar a imagem: {e}") def graficos(emotion_counter, parent_frame): emotions=list(emotion_counter.keys()) counts=list(emotion_counter.values()) fig, ax = plt.subplots(figsize=(5, 3)) fig.patch.set_facecolor('#2B2B2B') ax.set_facecolor('#2B2B2B') bars= ax.bar(emotions, counts, color=['White', 'green', 'yellow', 'blue', 'darkred', 'purple', 'red']) for bar in bars: yval = bar.get_height() ax.text(bar.get_x() + bar.get_width() / 2, yval, int(yval), ha='center', va='bottom', color='white') ax.set_xlabel('Emoções', color='white') ax.set_ylabel('Contagem', color='white') ax.set_title('FER', color='white') ax.tick_params(colors='white') ax.spines['top'].set_visible(False) ax.spines['right'].set_visible(False) ax.spines['left'].set_color('white') ax.spines['bottom'].set_color('white') plt.xticks(rotation=45, color='white') plt.xticks(color='white') plt.tight_layout() parent_frame.grid_rowconfigure(0, weight=1) parent_frame.grid_columnconfigure(0, weight=1) canvas = FigureCanvasTkAgg(fig, master=parent_frame) canvas.draw() canvas.get_tk_widget().grid(row=0, column=0, padx=10, pady=10) def graficosAER(emotion_counter, parent_frame): emotions=list(emotion_counter.keys()) counts=list(emotion_counter.values()) fig, ax = plt.subplots(figsize=(5, 3)) fig.patch.set_facecolor('#2B2B2B') ax.set_facecolor('#2B2B2B') bars= ax.bar(emotions, counts, color=['White', 'green', 'yellow', 'blue', 'darkred', 'purple', 'red']) for bar in bars: yval = bar.get_height() ax.text(bar.get_x() + bar.get_width() / 2, yval, int(yval), ha='center', va='bottom', color='white') ax.set_xlabel('Emoções', color='white') ax.set_ylabel('Contagem', color='white') ax.set_title('AER', color='white') ax.tick_params(colors='white') ax.spines['top'].set_visible(False) ax.spines['right'].set_visible(False) ax.spines['left'].set_color('white') ax.spines['bottom'].set_color('white') plt.xticks(rotation=45, color='white') plt.xticks(color='white') plt.tight_layout() parent_frame.grid_rowconfigure(0, weight=1) parent_frame.grid_columnconfigure(0, weight=1) canvas = FigureCanvasTkAgg(fig, master=parent_frame) canvas.draw() canvas.get_tk_widget().grid(row=0, column=0, padx=10, pady=10) def atualizar_grafico_emocoes(emotion_counter, parent_frame): for widget in parent_frame.winfo_children(): widget.destroy() graficos(emotion_counter, parent_frame) def atualizar_graficosAER(emotion_counter, parent_frame): for widget in parent_frame.winfo_children(): widget.destroy() graficosAER(emotion_counter, parent_frame) def extrairinfo(pdf_path, keyword): with pdfplumber.open(pdf_path) as pdf: for page in pdf.pages: text = page.extract_text() for line in text.split('\n'): if keyword in line: extracted_text = line.split(keyword, 1)[1].strip() if "AUTENTICAÇÃO" in extracted_text: extracted_text = extracted_text.split("AUTENTICAÇÃO", 1)[0].strip() return extracted_text return None def extrairinfomaisdificil(pdf_path, keyword): resultados = [] with pdfplumber.open(pdf_path) as pdf: for page in pdf.pages: text = page.extract_text() for line in text.split('\n'): if keyword in line: extracted_text = line.split(keyword, 1)[1].strip() if "AUTENTICAÇÃO" in extracted_text: extracted_text = extracted_text.split("AUTENTICAÇÃO", 1)[0].strip() resultados.append(extracted_text) return resultados def extrairinfoabaixo(pdf_path, keyword): resultados = [] with pdfplumber.open(pdf_path) as pdf: for page in pdf.pages: text = page.extract_text() lines = text.split('\n') for i, line in enumerate(lines): if keyword in line: if i + 1 < len(lines): extracted_text = lines[i + 1].strip() resultados.append(extracted_text) return resultados def extrairinfoabaixo3(pdf_path, keyword): resultados = [] with pdfplumber.open(pdf_path) as pdf: for page in pdf.pages: text = page.extract_text() lines = text.split('\n') for i, line in enumerate(lines): if keyword in line: for j in range(1, 4): if i + j < len(lines): extracted_text = lines[i + j].strip() resultados.append(extracted_text) return resultados def Login(): janela = customtkinter.CTk() janela.title("Login") janela.geometry("400x250") janela.resizable(False, False) texto = customtkinter.CTkLabel(janela, text="Login") texto.pack(padx=10, pady=10) user = customtkinter.CTkEntry(janela, placeholder_text="User") user.pack (padx=10, pady=10) password = customtkinter.CTkEntry(janela, placeholder_text="Password", show='*') password.pack (padx=10, pady=10) checkbox = customtkinter.CTkCheckBox(janela, text="1ª Utilização") checkbox.pack (padx=10, pady=10) botao = customtkinter.CTkButton(janela, text="Login", command=lambda: validar_login(user, password, janela)) botao.pack(padx=10, pady=10) janela.mainloop() def validar_login(user, password, janela): userverifica = user.get() passwordverifica = password.get() if userverifica == "kl3z" and passwordverifica == "12345": janela.destroy() janelaprincipal() else: show_messagebox("Erro", "User ou password incorretos!") def extrairimagemdopdfFM(pdf_path, page_number=0): pdf_path = os.path.normpath(pdf_path) doc = fitz.open(pdf_path) pagina = doc[page_number] imagem_extraida = False print("Extrair imagens do PDF") for img_index, img in enumerate(pagina.get_images(full=True)): try: xref = img[0] base_image = doc.extract_image(xref) image_bytes = base_image["image"] image_ext = base_image["ext"] image_filename = f"imagem_extraida_{img_index}.{image_ext}" with open(image_filename, "wb") as img_file: img_file.write(image_bytes) imagem = Image.open(image_filename) imagem.save(f"C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\Imagens\\imagem_corrigida_{img_index}.jpeg") imagem_extraida = True print(f"Imagem {img_index} extraída e corrigida: {image_filename}") except Exception as e: print(f"Erro ao extrair a imagem {img_index}: {e}") continue if not imagem_extraida: print("Nenhuma imagem foi extraída.") doc.close() def extrair_imagem_do_pdf(pdf_path): doc = fitz.open(pdf_path) for page_num in range(len(doc)): pagina = doc[page_num] for img_index, img in enumerate(pagina.get_images(full=True)): xref = img[0] base_image = doc.extract_image(xref) image_bytes = base_image["image"] image_ext = base_image["ext"] image_filename = f"C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\Imagens\\imagem_extraida_{page_num + 1}_{img_index + 1}.{image_ext}" with open(image_filename, "wb") as img_file: img_file.write(image_bytes) print(f"Imagem extraída e salva como: {image_filename}") imagem=image_filename doc.close() return imagem def carregar_ficheiro(user,parent_frame): pdf_path = filedialog.askopenfilename(filetypes=[("PDF files", "*.pdf")]) if pdf_path: user.configure(fg_color="green", text="File Loaded") retirarinfodafolha(pdf_path) mostrar_dados(parent_frame) def retirarinfodafolha(pdf_path): global Nome, nim, posto, DTnasc, cc, ccval, nif, pai, mae, morada, imagem, a, codigo_postal, freguesia, concelho, Morada valor100=extrairinfo(pdf_path, "MINISTÉRIO DA DEFESA NACIONAL") if valor100 is not None: pai = extrairinfo(pdf_path, "Pai:") or "" mae = extrairinfo(pdf_path, "Mãe:") or "" posto = extrairinfo(pdf_path, "Posto:") or "" nim = extrairinfo(pdf_path, "NIM:") or "" Nome = extrairinfo(pdf_path, "Nome:") or "" valor5 = extrairinfo(pdf_path, "Data de Nascimento:") or "" DTnasc = re.search(r"\d{2}-\d{2}-\d{4}", valor5).group() if valor5 else "" Freg = extrairinfo(pdf_path, "Freguesia:") or "" valor7 = extrairinfo(pdf_path, "Concelho:") or "" valor7= re.split(r"\s+Distrito", valor7)[0].strip() if valor7 else "" valor8 = extrairinfo(pdf_path, "Distrito:") or "" valor9 = extrairinfo(pdf_path, "País:")or "" valor9= re.split(r"\s+Posto", valor9)[0].strip() if valor9 else "" valor10 = extrairinfo(pdf_path, "Endereço:") or "" valor11 = extrairinfo(pdf_path, "Código Postal:") or "" valor12 = re.split(r"\s+Localidade:", valor11)[1].strip() if "Localidade:" in valor11 else "" valor11 = re.split(r"\s+Localidade:", valor11)[0].strip() if "Localidade:" in valor11 else "" valor13 = extrairinfo(pdf_path, "Cartão do Cidadão") or "" ccval = re.search(r"\d{2}-\d{2}-\d{4}", valor13).group() if valor13 else "" cc = valor13.replace(ccval, "").strip() if valor13 else "" nif = extrairinfo(pdf_path, "Número de Identificação Fiscal") or "" valor16 = extrairinfo(pdf_path, "Cartão da Segurança Social") or "" valor17 = extrairinfo(pdf_path, "Telemóvel:") or "" valor17 = re.split(r"\s+email:", valor17)[0].strip() if "email:" in valor17 else "" valor18 = extrairinfo(pdf_path, "email:") or "" valor19 = extrairinfomaisdificil(pdf_path, "Freguesia:")[1] if extrairinfomaisdificil(pdf_path, "Freguesia:") else "" valor20 = extrairinfomaisdificil(pdf_path, "Concelho:")[1] if extrairinfomaisdificil(pdf_path, "Concelho:") else "" valor21 = extrairinfomaisdificil(pdf_path, "Distrito:")[1] if extrairinfomaisdificil(pdf_path, "Distrito:") else "" valor22 = extrairinfomaisdificil(pdf_path, "País:")[1] if extrairinfomaisdificil(pdf_path, "País:") else "" valor22 = re.split(r"\s+Posto", valor22)[0].strip() if valor22 else "" Morada = valor10 +","+ " "+ valor11 +","+ " "+ valor12+","+ " "+ valor19 +","+ " "+ valor20 extrairimagemdopdfFM(pdf_path, page_number=0) imagem= "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\Imagens\\imagem_corrigida_1.jpeg" a = pdf_path partes = Morada.split(",") morada = partes[0].strip().title() if len(partes) > 0 else "" codigo_postal = f"{partes[1].strip()}, {partes[2].strip()}" if len(partes) > 2 else "" freguesia = partes[3].strip().title() if len(partes) > 3 else "" concelho = partes[4].strip().title() if len(partes) > 4 else "" Nacionalidade = extrairinfo(pdf_path, "País:") or "" Nacionalidade = re.sub(r"Posto Consular:\S*.+", "", Nacionalidade).strip() Nacionalidade = " ".join(Nacionalidade.split()[:-2]) if Nacionalidade else "" else: valor1 = extrairinfoabaixo(pdf_path, "Apelido(s)") or "" valor2 = extrairinfoabaixo(pdf_path, "Nome(s)") or "" valor3 = valor2+valor1 valor3 = " ".join(valor3) Nome=valor3 nim = "" posto = "" valor4 = extrairinfoabaixo(pdf_path, "Nascimento") or "" valor4 = re.search(r"\d{2}-\d{2}-\d{4}", "".join(valor4)).group() if valor4 else "" DTnasc = valor4 valor5 = extrairinfoabaixo(pdf_path, "Nº cartão") or "" valor5 = "".join(valor5) or "" valor6 = re.search(r"\d{2}-\d{2}-\d{4}", valor5).group() if valor5 else "" valor7 = valor5.replace(valor6, "").strip() if valor5 else "" valor8 = extrairinfoabaixo3(pdf_path, "Morada")[:2] if extrairinfoabaixo3(pdf_path, "Morada") else ["", ""] Morada = " ".join(valor8).strip() valor10 = extrairinfoabaixo3(pdf_path, "Filiação")[2] if len(extrairinfoabaixo3(pdf_path, "Filiação")) > 2 else "" mae = valor10 valor11 = extrairinfoabaixo3(pdf_path, "Filiação")[1] if len(extrairinfoabaixo3(pdf_path, "Filiação")) > 1 else "" valor12 = re.findall(r"\d+", valor11) if valor11 else [] valor13 = valor12[0] if len(valor12) > 0 else "" cc = valor7 ccval = valor6 nif = valor13 valor14 = valor12[1] if len(valor12) > 1 else "" valor15 = valor12[2] if len(valor12) > 2 else "" valor11 = re.findall(r"[A-Za-zçÇáÁéÉíÍóÓúÚâÂêÊîÎôÔûÛãÃõÕàÀèÈìÌòÒùÙäÄëËïÏöÖüÜñÑ]+", valor11) if valor11 else [] valor11 = " ".join(valor11) pai = valor11 extrair_imagem_do_pdf(pdf_path) imagem = "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\Imagens\\imagem_extraida_1_2.jpeg" a = pdf_path codigo_postal = re.search(r'\b\d{4}-\d{3}\b', Morada).group() if Morada else "" freguesia = re.search(r'\b([A-Za-zçãáéíóúâêô]*)\b(?=\s\d{4}-\d{3})', Morada).group() if Morada else "" concelho = re.search(r'\b[A-Z]{2,}\b$', Morada).group() if Morada else "" morada = re.search(r'^(.*?)(?=\s\d{4}-\d{3})', Morada).group() if Morada else "" Nacionalidade = extrairinfoabaixo(pdf_path, "Nascimento") Nacionalidade = "".join(Nacionalidade) Nacionalidade = Nacionalidade.split()[2] return Nome, nim, posto, DTnasc, cc, ccval, nif, pai, mae, morada, imagem, a, codigo_postal, freguesia, concelho, Morada, Nacionalidade def resumir_texto_2(texto, max_length=160, min_length=30): tamanhodotexto = len(texto.split()) max_length=min(max_length, tamanhodotexto) max_length=int(max_length) min_length=min(min_length, tamanhodotexto/4) min_length=int(min_length) summarizer = pipeline("summarization", model="facebook/bart-large-cnn", device=0) resumo = summarizer(texto, max_length=max_length, min_length=min_length, do_sample=False) return resumo[0]['summary_text'] def resumir_texto(texto, max_length=320, min_length=30): tamanhodotexto = len(texto.split()) max_length=min(max_length, tamanhodotexto) max_length=int(max_length) min_length=min(min_length, tamanhodotexto/4) min_length=int(min_length) summarizer = pipeline("summarization", model="t5-small", device=0) resumo = summarizer(texto, max_length=max_length, min_length=min_length, do_sample=False) return resumo[0]['summary_text'] def anexoA(audio_path): model=whisper.load_model("large") result = model.transcribe(audio_path, language='pt') textoarranjado = result['text'] textoformatado='' for char in textoarranjado: if char.isupper() and textoformatado: textoformatado += '\n' textoformatado += char texto_resumido = resumir_texto(textoarranjado) dados_para_preencher = {"ATT": textoarranjado} caminho_saida = "C:/Users/garci/OneDrive/Área de Trabalho/Programa PJM/Programa final/Dataset/6_ainqtestemunha_Final.docx" preencheraintestemunha("C:/Users/garci/OneDrive/Área de Trabalho/Programa PJM/Programa final/Dataset/6_ainqtestemunha_Final.docx", dados_para_preencher,caminho_saida) caminho_saida2 = "C:/Users/garci/OneDrive/Área de Trabalho/Programa PJM/Programa final/Dataset/3_aintarg_Final.docx" preencheraintestemunha("C:/Users/garci/OneDrive/Área de Trabalho/Programa PJM/Programa final/Dataset/3_aintarg_Final.docx", dados_para_preencher, caminho_saida2) caminho_saida3 = "C:/Users/garci/OneDrive/Área de Trabalho/Programa PJM/Programa final/Dataset/2_auto_de_denuncia_Final.docx" preencheraintestemunha("C:/Users/garci/OneDrive/Área de Trabalho/Programa PJM/Programa final/Dataset/2_auto_de_denuncia_Final.docx", dados_para_preencher, caminho_saida3) transcrever_audio(audio_path,texto_resumido) caminho_pdf = 'C:/Users/garci/OneDrive/Área de Trabalho/Programa PJM/Programa final/Anexo_A.pdf' c = canvas.Canvas(caminho_pdf, pagesize=letter) largura, altura = letter caminho_imagem = 'C:/Users/garci/OneDrive/Área de Trabalho/Programa PJM/Programa final/Icons/logo_presidencia_republica.jpg' cabecalho = [("RESERVADO",red),('MINISTÉRIO DA DEFESA NACIONAL', black),('EXÉRCITO PORTUGUÊS',black),('ESTADO-MAIOR GENERAL DAS FORÇAS ARMADAS',black), ('RELATÓRIO DE ENTERVISTA - PJM',black), ('ANEXO A - TRANSCRIÇÃO DO INTERREGOTÓRIO', black)] y_position = altura - 72 def check_y_position(): nonlocal y_position if y_position < 40: c.showPage() y_position = altura - 72 adicionar_cabecalho() def adicionar_cabecalho(): nonlocal y_position c.setFont("Helvetica-Bold", 12) c.setFillColor(black) y_position = altura - 72 c.setFillColor(cabecalho[0][1]) c.setFont("Helvetica-Bold", 14) text_width = c.stringWidth(cabecalho[0][0], "Helvetica", 12) c.drawString((largura - text_width) / 2, y_position, cabecalho[0][0]) y_position -= 30 c.drawImage(caminho_imagem, (largura - 50) / 2, y_position - 20, width=40, height=40) y_position -= 50 for line, color in cabecalho[1:]: check_y_position() c.setFillColor(color) text_width = c.stringWidth(line, "Helvetica-Bold", 14) c.drawString((largura - text_width) / 2, y_position, line) y_position -= 20 adicionar_cabecalho() for line in textoarranjado.strip().split('\n'): y_position -= 40 words = line.split(' ') current_line = "" for word in words: test_line = current_line + word + " " test_line_width = c.stringWidth(test_line, "Helvetica", 12) if test_line_width <= largura - 160: current_line = test_line else: check_y_position() c.drawString(36, y_position, current_line.strip()) y_position -= 15 current_line = word + " " if current_line.strip(): check_y_position() c.drawString(36, y_position, current_line.strip()) y_position -= 15 c.save() print("anexo criado") def transcrever_audio(audio_path,texto_resumido): caminho_pdf = 'C:/Users/garci/OneDrive/Área de Trabalho/Programa PJM/Programa final/transcricao_audio.pdf' c = canvas.Canvas(caminho_pdf, pagesize=letter) largura, altura = letter caminho_imagem = 'C:/Users/garci/OneDrive/Área de Trabalho/Programa PJM/Programa final/Icons/logo_presidencia_republica.jpg' cabecalho = [("RESERVADO",red),('MINISTÉRIO DA DEFESA NACIONAL', black),('FORÇAS ARMADAS',black),('ESTADO-MAIOR DAS FORÇAS ARMADAS',black), ('RELATÓRIO DE ENTERVISTA - PJM',black)] y_position = altura - 72 def check_y_position(): nonlocal y_position if y_position < 40: c.showPage() y_position = altura - 72 adicionar_cabecalho() def adicionar_cabecalho(): nonlocal y_position c.setFont("Helvetica-Bold", 12) c.setFillColor(black) y_position = altura - 72 c.setFillColor(cabecalho[0][1]) c.setFont("Helvetica-Bold", 14) text_width = c.stringWidth(cabecalho[0][0], "Helvetica", 12) c.drawString((largura - text_width) / 2, y_position, cabecalho[0][0]) y_position -= 30 c.drawImage(caminho_imagem, (largura - 50) / 2, y_position - 20, width=40, height=40) y_position -= 50 for line, color in cabecalho[1:]: check_y_position() c.setFillColor(color) text_width = c.stringWidth(line, "Helvetica-Bold", 14) c.drawString((largura - text_width) / 2, y_position, line) y_position -= 20 adicionar_cabecalho() c.setFillColor(black) c.setFont("Helvetica-Bold", 12) horamins = (Hour if Hour else "00") + ":" + (Minutes if Minutes else "00") informacoes_texto = f""" DADOS DO INTERROGADO Posto: {posto} NIM: {nim} Nome: {Nome} Data de Nascimento: {DTnasc} Cartão de Cidadão: {cc} Validade: {ccval} NIF: {nif} DADOS DO INTERROGADOR Interrogador: {Interrogador} Data do Interrogatório: {Datainterrogatorio}, Horas: {horamins} Local: {Local} , Cidade: {City} """ for linha in informacoes_texto.strip().split('\n'): y_position -= 20 c.drawString(36, y_position, linha.strip()) paibem=pai.title() maebem=mae.title() Moradabem=Morada.title() idade = datetime.strptime(DTnasc, "%d-%m-%Y") dataatual = datetime.now() idadeanos = dataatual.year - idade.year - ((dataatual.month, dataatual.day) < (idade.month, idade.day)) introducao= f""" Aos {Datainterrogatorio}, no {Local} em {City} compareceu perante mim, {Interrogador}, o {posto} {nim} {Nome} portador do Cartão de Cidadão n.º {cc}, válido até {ccval}. Declarou ser filho de {paibem} e de {maebem}, ter {idadeanos} anos de idade, residir na {Moradabem}.--/ RESUMO DA ENTREVISTA {texto_resumido} """ for line in introducao.strip().split('\n'): y_position -= 40 words = line.split(' ') current_line = "" for word in words: test_line = current_line + word + " " test_line_width = c.stringWidth(test_line, "Helvetica", 12) if test_line_width <= largura - 140: current_line = test_line else: check_y_position() c.drawString(36, y_position, current_line.strip()) y_position -= 15 current_line = word + " " if current_line.strip(): check_y_position() c.drawString(36, y_position, current_line.strip()) y_position -= 15 c.save() print("PDF criado com sucesso!") def show_messagebox(title, message, box_type="Erro"): Janela_erro = customtkinter.CTkToplevel() Janela_erro.title(title) Janela_erro.geometry("300x150+500+300") label_title = customtkinter.CTkLabel(Janela_erro, text=title, font=('Arial', 16, 'bold')) label_title.pack(pady=10) label_message = customtkinter.CTkLabel(Janela_erro, text=message) label_message.pack(pady=10) close_button = customtkinter.CTkButton(Janela_erro, text="OK", command=Janela_erro.destroy) close_button.pack(pady=10) def update_frame(video_clip): for frame in video_clip.iter_frames(fps=24, dtype='uint8'): frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) img = Image.fromarray(frame) img = img.resize((600, 400)) imgTk = ImageTk.PhotoImage(image=img) if cv2.waitKey(1) & 0xFF == ord('q'): break cv2.destroyAllWindows() def play_video(video_path,parent_frame,parent_frame2): audiopath='C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\audio.mp3' video_clip = VideoFileClip(video_path) video_clip.audio.write_audiofile(audiopath) print('audio gravado') update_frame(video_clip) modelemotionface_video(video_path,parent_frame) anexoA(audiopath) dividirvideoclips(video_path) clipes = dividiraudioclips(audiopath) classificar_clipes(clipes,parent_frame2) classificar_videoclipes() sincronizarvideoaudio() criarvetoremocoesFER() juntapdfs2() copiarficheiro() def carregarovideoparaver(): video_path = filedialog.askopenfilename(filetypes=[("Carregar Vídeo", "*.mp4;*.avi;*.mov")]) vlc_path = "C:\\Program Files (x86)\\VideoLAN\\VLC\\vlc.exe" subprocess.Popen([vlc_path, video_path,'--play-and-exit']) def carregarosomparaouvir(): audio_path = filedialog.askopenfilename(filetypes=[("Carregar Vídeo", "*.mp3;*.wav;*.ogg")]) vlc_path = "C:\\Program Files (x86)\\VideoLAN\\VLC\\vlc.exe" subprocess.Popen([vlc_path, audio_path,'--play-and-exit']) def criarvetoremocoesFER(): video_clips = "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\video_clips" audio_clips = "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\clips" vetoremocoesFER = [] vetoremocoesAER = [] vetor_sentimentos = [] try: video_clips = sorted([f for f in os.listdir(video_clips) if f.endswith('.mp4')]) audio_clips = sorted([f for f in os.listdir(audio_clips) if f.endswith('.mp3')]) for video_clip in video_clips: parts = os.path.basename(video_clip).replace('.mp4', '').split('_') if len(parts) >= 4: intervalo = f"{parts[1]}-{parts[2]}" emocao = parts[3] vetoremocoesFER.append([f"({intervalo})", emocao]) print("Vetor de emoções (FER):", vetoremocoesFER) for audio_clip in audio_clips: parts = os.path.basename(audio_clip).replace('.mp3', '').split('_') if len(parts) >= 5: intervalo = f"{parts[1]}-{parts[2]}" emocao = parts[3] sentimento = parts[4] vetoremocoesAER.append([f"({intervalo})", emocao, sentimento]) vetor_sentimentos.append(sentimento) print("Vetor de emoções e sentimentos (AER):", vetoremocoesAER) print("Vetor de sentimentos:", vetor_sentimentos) except Exception as e: print(f"Erro ao criar os vetores de emoções: {e}") criarpdfemocoes(vetoremocoesAER, vetoremocoesFER, vetor_sentimentos) return vetoremocoesFER, vetoremocoesAER, vetor_sentimentos def criarvetoremocoesFER2(): video_clips = "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\video_clips" audio_clips = "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\clips" vetoremocoesFER = [] vetoremocoes = [] try: video_clips = sorted([f for f in os.listdir(video_clips) if f.endswith('.mp4')]) audio_clips = sorted([f for f in os.listdir(audio_clips) if f.endswith('.mp3')]) for video_clip in video_clips: parts = os.path.basename(video_clip).replace('.mp4', '').split('_') if len(parts) >= 4: intervalo = f"{parts[1]}-{parts[2]}" emocao = parts[3] vetoremocoesFER.append([f"({intervalo})", emocao]) print("Vetor de emoções (FER):", vetoremocoesFER) for audio_clip in audio_clips: parts = os.path.basename(audio_clip).replace('.mp3', '').split('_') if len(parts) >= 4: intervalo = f"{parts[1]}-{parts[2]}" emocao = parts[3] vetoremocoes.append([f"({intervalo})", emocao]) print("Vetor de emoções (AER):", vetoremocoes) except Exception as e: print(f"Erro ao criar o vetor de emoções: {e}") criarpdfemocoes(vetoremocoes, vetoremocoesFER) return vetoremocoesFER, vetoremocoes def sincronizarvideoaudio(): video_path = "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\FERVideo.mp4" audio_path = "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\audio.mp3" outputpath = "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\VideoFINAL.mp4" audio_clips = sorted([ os.path.join("C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\clips", f) for f in os.listdir("C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\clips") if f.endswith('.mp3') ]) video_clips = sorted([ os.path.join("C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\video_clips", f) for f in os.listdir("C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\video_clips") if f.endswith('.mp4') ]) emotion_colors = { 'neutral': 'white', 'happiness': 'green', 'surprise': 'yellow', 'sadness': 'lightblue', 'anger': 'red', 'disgust': 'purple', 'fear': 'red' } try: video_clip = VideoFileClip(video_path) audio_clip = AudioFileClip(audio_path) video_duration = video_clip.duration audio_duration = audio_clip.duration speed_factor = video_duration / audio_duration video_clip = speedx(video_clip, factor=speed_factor).set_audio(audio_clip) annotated_clips = [] clip_duration = 10 for i, (audio_clip_path, video_clip_path) in enumerate(zip(audio_clips, video_clips)): aer_label_match = re.search(r'_([^_]+)_([^_]+)\.mp3$', audio_clip_path) fer_label_match = re.search(r'_([^_]+)\.mp4$', video_clip_path) aer_label = aer_label_match.group(1) if aer_label_match else 'neutral' sentiment_label = aer_label_match.group(2) if aer_label_match else 'neutral' fer_label = fer_label_match.group(1) if fer_label_match else 'neutral' aer_color = emotion_colors.get(aer_label, 'white') fer_color = emotion_colors.get(fer_label, 'white') sentiment_color = 'orange' aer_text = TextClip(f"AER: {aer_label}", fontsize=24, color=aer_color, bg_color="black") fer_text = TextClip(f"FER: {fer_label}", fontsize=24, color=fer_color, bg_color="black") sentiment_text = TextClip(f"Sentiment: {sentiment_label}", fontsize=24, color=sentiment_color, bg_color="black") video_height = video_clip.h aer_text = aer_text.set_position(("left", video_height - 90)).set_duration(clip_duration) fer_text = fer_text.set_position(("left", video_height - 60)).set_duration(clip_duration) sentiment_text = sentiment_text.set_position(("left", video_height - 30)).set_duration(clip_duration) start_time = i * clip_duration end_time = min((i + 1) * clip_duration, video_clip.duration) video_segment = video_clip.subclip(start_time, end_time) annotated_segment = CompositeVideoClip([video_segment, aer_text, fer_text, sentiment_text]) annotated_clips.append(annotated_segment) final_video = concatenate_videoclips(annotated_clips, method="compose") final_video.write_videofile(outputpath, codec="libx264", audio_codec="aac") print(f"Vídeo com áudio sincronizado salvo em: {outputpath}") except Exception as e: print(f"Erro ao sincronizar vídeo e áudio: {e}") def sincronizarvideoaudio2(): video_path = "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\FERVideo.mp4" audio_path = "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\audio.mp3" outputpath = "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\VideoFINAL.mp4" audio_clips = sorted([os.path.join("C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\clips", f)for f in os.listdir("C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\clips")if f.endswith('.mp3')]) video_clips = sorted([os.path.join("C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\video_clips", f)for f in os.listdir("C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\video_clips")if f.endswith('.mp4')]) emotion_colors = {'neutral': 'white', 'happiness': 'green', 'surprise': 'yellow','sadness': 'lightblue', 'anger': 'red', 'disgust': 'purple', 'fear': 'red'} try: video_clip = VideoFileClip(video_path) audio_clip = AudioFileClip(audio_path) video_duration = video_clip.duration audio_duration = audio_clip.duration speed_factor = video_duration / audio_duration video_clip = speedx(video_clip, factor=speed_factor).set_audio(audio_clip) annotated_clips = [] clip_duration = 10 for i, (audio_clip_path, video_clip_path) in enumerate(zip(audio_clips, video_clips)): aer_label_match = re.search(r'_([^_]+)\.mp3$', audio_clip_path) fer_label_match = re.search(r'_([^_]+)\.mp4$', video_clip_path) aer_label = aer_label_match.group(1) if aer_label_match else 'neutral' fer_label = fer_label_match.group(1) if fer_label_match else 'neutral' aer_color = emotion_colors.get(aer_label, 'white') fer_color = emotion_colors.get(fer_label, 'white') aer_text = TextClip(f"AER: {aer_label}", fontsize=24, color=aer_color, bg_color="black") fer_text = TextClip(f"FER: {fer_label}", fontsize=24, color=fer_color, bg_color="black") video_height = video_clip.h aer_text = aer_text.set_position(("left", "bottom")).set_duration(clip_duration) fer_text = fer_text.set_position(("left", (video_height - 60))).set_duration(clip_duration) start_time = i * clip_duration end_time = min((i + 1) * clip_duration, video_clip.duration) video_segment = video_clip.subclip(start_time, end_time) annotated_segment = CompositeVideoClip([video_segment, aer_text, fer_text]) annotated_clips.append(annotated_segment) final_video = concatenate_videoclips(annotated_clips, method="compose") final_video.write_videofile(outputpath, codec="libx264", audio_codec="aac") print(f"Vídeo com áudio sincronizado salvo em: {outputpath}") except Exception as e: print(f"Erro ao sincronizar vídeo e áudio: {e}") def vervideocompiladocomaerfer(): outputpath = "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\VideoFINAL.mp4" vlc_path = "C:\\Program Files (x86)\\VideoLAN\\VLC\\vlc.exe" subprocess.Popen([vlc_path, outputpath, '--play-and-exit']) def carregar_video(parent_frame,parent_frame2): video_path = filedialog.askopenfilename(filetypes=[("Carregar Vídeo", "*.mp4;*.avi;*.mov")]) if video_path: video_path = os.path.normpath(video_path) threading.Thread(target=play_video, args=(video_path,parent_frame,parent_frame2)).start() def criarpdfemocoes(vetoremocoesAER, vetoremocoesFER, vetor_sentimentos): output_pdf_path = "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\ANEXO_B_C.pdf" try: def cabecalho(canvas, doc): canvas.saveState() largura, altura = A4 caminho_imagem = 'C:/Users/garci/OneDrive/Área de Trabalho/Programa PJM/Programa final/Icons/logo_presidencia_republica.jpg' canvas.setFillColor(colors.red) canvas.setFont("Helvetica-Bold", 16) text_width = canvas.stringWidth("RESERVADO", "Helvetica-Bold", 16) canvas.drawString((largura - text_width) / 2, altura - 40, "RESERVADO") canvas.drawImage(caminho_imagem, largura / 2 - 20, altura - 100, width=40, height=40) cabecalho_texto = [ "MINISTÉRIO DA DEFESA NACIONAL", "EXÉRCITO PORTUGUÊS", "ESTADO-MAIOR GENERAL DAS FORÇAS ARMADAS", "RELATÓRIO DE ENTREVISTA - PJM", "ANEXOS B, C e D - SUMMARY AER, FER e Sentiment Analysis", ] y_position = altura - 120 for linha in cabecalho_texto: canvas.setFillColor(colors.black) canvas.setFont("Helvetica-Bold", 12) text_width = canvas.stringWidth(linha, "Helvetica-Bold", 12) canvas.drawString((largura - text_width) / 2, y_position, linha) y_position -= 15 canvas.restoreState() tabela_cabecalho = ['Tempo (SER)', 'SER', 'FER', 'Sentiment Analysis'] dados_combinados = [ [aer[0], aer[1], fer[1], sentimento] for aer, fer, sentimento in zip(vetoremocoesAER, vetoremocoesFER, vetor_sentimentos) ] dados_tabela = [tabela_cabecalho] + dados_combinados largura_tabela = A4[0] - inch col_widths = [largura_tabela / 4] * 4 tabela_combinada = Table(dados_tabela, colWidths=col_widths) tabela_combinada.setStyle(TableStyle([ ('BACKGROUND', (0, 0), (-1, 0), colors.grey), ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke), ('ALIGN', (0, 0), (-1, -1), 'CENTER'), ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'), ('FONTSIZE', (0, 0), (-1, -1), 10), ('BOTTOMPADDING', (0, 0), (-1, 0), 12), ('GRID', (0, 0), (-1, -1), 0.5, colors.black), ])) doc = SimpleDocTemplate(output_pdf_path, pagesize=A4) elementos = [Spacer(1, 120)] elementos.append(tabela_combinada) doc.build( elementos, onFirstPage=cabecalho, onLaterPages=cabecalho ) print(f"PDF gerado com sucesso em: {output_pdf_path}") except Exception as e: print(f"Erro ao criar o PDF: {e}") def criarpdfemocoes2(vetoremocoesAER, vetoremocoesFER): output_pdf_path = "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\ANEXO_B_C.pdf" try: def cabecalho(canvas, doc): canvas.saveState() largura, altura = A4 caminho_imagem = 'C:/Users/garci/OneDrive/Área de Trabalho/Programa PJM/Programa final/Icons/logo_presidencia_republica.jpg' canvas.setFillColor(colors.red) canvas.setFont("Helvetica-Bold", 16) text_width = canvas.stringWidth("RESERVADO", "Helvetica-Bold", 16) canvas.drawString((largura - text_width) / 2, altura - 40, "RESERVADO") canvas.drawImage(caminho_imagem, largura / 2 - 20, altura - 100, width=40, height=40) cabecalho_texto = [ "MINISTÉRIO DA DEFESA NACIONAL", "EXÉRCITO PORTUGUÊS", "ESTADO-MAIOR GENERAL DAS FORÇAS ARMADAS", "RELATÓRIO DE ENTREVISTA - PJM", "ANEXOS B e C - SUMMARY AER E FER", ] y_position = altura - 120 for linha in cabecalho_texto: canvas.setFillColor(colors.black) canvas.setFont("Helvetica-Bold", 12) text_width = canvas.stringWidth(linha, "Helvetica-Bold", 12) canvas.drawString((largura - text_width) / 2, y_position, linha) y_position -= 15 canvas.restoreState() tabela_cabecalho = ['Tempo (SER)', 'SER', 'FER'] dados_combinados = [ [aer[0], aer[1], fer[1]] for aer, fer in zip(vetoremocoesAER, vetoremocoesFER) ] dados_tabela = [tabela_cabecalho] + dados_combinados largura_tabela = A4[0] - inch col_widths = [largura_tabela / 4] * 4 tabela_combinada = Table(dados_tabela, colWidths=col_widths) tabela_combinada.setStyle(TableStyle([ ('BACKGROUND', (0, 0), (-1, 0), colors.grey), ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke), ('ALIGN', (0, 0), (-1, -1), 'CENTER'), ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'), ('FONTSIZE', (0, 0), (-1, -1), 10), ('BOTTOMPADDING', (0, 0), (-1, 0), 12), ('GRID', (0, 0), (-1, -1), 0.5, colors.black), ])) doc = SimpleDocTemplate(output_pdf_path, pagesize=A4) elementos = [Spacer(1, 120)] elementos.append(tabela_combinada) doc.build( elementos, onFirstPage=cabecalho, onLaterPages=cabecalho ) print(f"PDF gerado com sucesso em: {output_pdf_path}") except Exception as e: print(f"Erro ao criar o PDF: {e}") def carregar_audio(parent_frame): audio_path1 = filedialog.askopenfilename(filetypes=[("Carregar Áudio", "*.mp3;*.wav;*.ogg")]) if audio_path1: audio_path = os.path.normpath(audio_path1) anexoA(audio_path1) clipes = dividiraudioclips(audio_path) classificar_clipes(clipes,parent_frame) criarvetoremocoesFER() juntapdfs2() copiarficheiro() def dividiraudioclips(audio_path, duracaoclipe=10, outputdir="C://Users//garci//OneDrive//Área de Trabalho//Programa PJM//Programa final//clips"): audio = AudioSegment.from_file(audio_path) duracao_total = len(audio) clipescriados = [] os.makedirs(outputdir, exist_ok=True) for i in range(0, duracao_total, duracaoclipe * 1000): clipe = audio[i:i + duracaoclipe * 1000] clipe_path = os.path.join(outputdir, f"clipe_{i // 1000}s_{(i + duracaoclipe * 1000) // 1000}s.mp3") clipe.export(clipe_path, format="mp3") clipescriados.append(clipe_path) return clipescriados def dividirvideoclips(video_path, duracaoclipe=10, outputdir="C://Users//garci//OneDrive//Área de Trabalho//Programa PJM//Programa final//video_clips"): video = VideoFileClip(video_path) duracao_total = video.duration clipes_criados = [] os.makedirs(outputdir, exist_ok=True) for i in range(0, int(duracao_total), duracaoclipe): start_time = i end_time = min(i + duracaoclipe, duracao_total) clipe = video.subclip(start_time, end_time) clipe_path = os.path.join(outputdir, f"clipe_{start_time}s_{end_time}s.mp4") clipe.write_videofile(clipe_path, codec="libx264", audio_codec="aac") clipes_criados.append(clipe_path) video.close() return clipes_criados def preprocessar_video(video_path, frame_size=(64, 64)): cap = cv2.VideoCapture(video_path) frames = [] while cap.isOpened(): ret, frame = cap.read() if not ret: break resized_frame = cv2.resize(frame, frame_size) gray_frame = cv2.cvtColor(resized_frame, cv2.COLOR_BGR2GRAY) gray_frame = gray_frame.astype(np.uint8) frames.append(gray_frame) cap.release() return frames def classificar_videoclipes(): modelo = cv2.dnn.readNetFromONNX('C:/Users/garci/Downloads/emotion-ferplus-8.onnx') clipes = sorted([os.path.join("C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\video_clips", f) for f in os.listdir("C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\video_clips") if f.endswith('.mp4')]) emotion_labels= {0: 'neutral', 1: 'happiness', 2: 'surprise', 3: 'sadness', 4: 'anger', 5: 'disgust', 6: 'fear'} resultados = {} emotion_counter = {label: 0 for label in emotion_labels.values()} for clipe in clipes: try: frames = preprocessar_video(clipe, frame_size=(64, 64)) predicoes = [] for frame in frames: var= cv2.dnn.blobFromImage(frame, scalefactor=1.0, size=(64, 64), mean=(0, 0, 0), swapRB=False, crop=False) modelo.setInput(var) output = modelo.forward() predicoes.append(output) predicao_media = np.mean(predicoes, axis=0) classe = np.argmax(predicao_media) rotulo = emotion_labels.get(classe, "Unknown") resultados[clipe] = rotulo if rotulo in emotion_counter: emotion_counter[rotulo] += 1 pasta, nome_original = os.path.split(clipe) nome, extensao = os.path.splitext(nome_original) novo_nome = f"{nome}_{rotulo}{extensao}" novo_caminho = os.path.join(pasta, novo_nome) os.rename(clipe, novo_caminho) print(f"Clipe {clipe} classificado como: {rotulo} e renomeado para {novo_caminho}") except Exception as e: print(f"Erro ao classificar o clipe {clipe}: {e}") resultados[clipe] = None return resultados, emotion_counter def preprocessar_audio(caminho_audio, target_shape=(400, 480)): y, sr = librosa.load(caminho_audio, sr=16000) mfcc_features = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=40) resized_features = resize(np.expand_dims(mfcc_features, axis=-1),target_shape).numpy() return np.expand_dims(resized_features, axis=0) def classificar_clipes(clipes, parent_frame): modelocaminho = "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\Scripts\\Modelos\\model.h5" modelo_emocao = load_model(modelocaminho) vectorizer_path = "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\Scripts\\Modelos\\vectorizer2.joblib" modelo_sentiment_path = "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\Scripts\\Modelos\\logistic_regression_model2.joblib" vectorizer = joblib.load(vectorizer_path) modelo_sentiment = joblib.load(modelo_sentiment_path) emotion_labels = {1: 'Neutral',2: 'Neutral',3: 'happiness',4: 'sadness',5: 'anger',6: 'fear',7: 'Disgust',8: 'surprise'} sentiment_labels = {0: "Sadness", 1: "Happiness", 2: "Disgust", 3: "Anger", 4: "Fear", 5: "Surprise"} resultados = {} emotion_counter = {label: 0 for label in emotion_labels.values()} sentiment_counter = {label: 0 for label in sentiment_labels.values()} for clipe in clipes: try: features = preprocessar_audio(clipe) predicao_emocao = modelo_emocao.predict(features) classe_emocao = np.argmax(predicao_emocao) + 1 if classe_emocao in emotion_labels: rotulo_emocao = emotion_labels[classe_emocao] else: rotulo_emocao = "Unknown" if rotulo_emocao in emotion_counter: emotion_counter[rotulo_emocao] += 1 texto_audio = transcrever_audio_para_texto(clipe) texto_processado = preprocess_frase_pt(texto_audio) texto_vetorizado = vectorizer.transform([texto_processado]) predicao_sentiment = modelo_sentiment.predict(texto_vetorizado) classe_sentiment = predicao_sentiment[0] rotulo_sentiment = sentiment_labels.get(classe_sentiment, "Unknown") if rotulo_sentiment in sentiment_counter: sentiment_counter[rotulo_sentiment] += 1 pasta, nome_original = os.path.split(clipe) nome, extensao = os.path.splitext(nome_original) novo_nome = f"{nome}_{rotulo_emocao}_{rotulo_sentiment}{extensao}" novo_caminho = os.path.join(pasta, novo_nome) os.rename(clipe, novo_caminho) resultados[clipe] = {"Emotion": rotulo_emocao, "Sentiment": rotulo_sentiment} print(f"Clique {clipe} classificado como: {rotulo_emocao} (Emoção) e {rotulo_sentiment} (Sentimento)") print(f"Arquivo renomeado para: {novo_caminho}") except Exception as e: print(f"Erro ao classificar o clipe {clipe}: {e}") resultados[clipe] = None atualizar_graficosAER(emotion_counter, parent_frame) return resultados, emotion_counter, sentiment_counter def transcrever_audio_para_texto(audio_path): model = whisper.load_model("large") result = model.transcribe(audio_path, language='pt') return result['text'] def classificar_clipes2(clipes,parent_frame): modelocaminho = "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\Scripts\\Modelos\\model.h5" modelo = load_model(modelocaminho) emotion_labels = {1: 'Neutral',2: 'Neutral',3: 'happiness',4: 'sadness',5: 'anger',6: 'fear',7: 'Disgust',8: 'surprise'} resultados = {} emotion_counter = {label: 0 for label in emotion_labels.values()} for clipe in clipes: try: features = preprocessar_audio(clipe) predicao = modelo.predict(features) classe = np.argmax(predicao)+1 rotulo = emotion_labels.get(classe, "Unknown") resultados[clipe] = rotulo if rotulo in emotion_counter: emotion_counter[rotulo] += 1 print(f"Clique {clipe} classificado como: {rotulo}") pasta, nome_original = os.path.split(clipe) nome, extensao = os.path.splitext(nome_original) novo_nome = f"{nome}_{rotulo}{extensao}" novo_caminho = os.path.join(pasta, novo_nome) os.rename(clipe, novo_caminho) print(f"Arquivo renomeado para: {novo_caminho}") except Exception as e: print(f"Erro ao classificar o clipe {clipe}: {e}") resultados[clipe] = None atualizar_graficosAER(emotion_counter, parent_frame) return resultados, emotion_counter def atribuivalores(user2, local, city, data_entry, horas, minutos): global Datainterrogatorio, Hour, Minutes, Local, City, Interrogador Datainterrogatorio = data_entry.get_date() if data_entry.get_date() else None Hour = horas.get() Minutes = minutos.get() Local = local.get() City = city.get() Interrogador = user2.get() return Datainterrogatorio, Hour, Minutes, Local, City, Interrogador def abrir_email_com_anexos(): global data_atual, cc assunto = "Relatório PJM" corpo = f"Segue em anexo o relatório gerado pelo programa PJM em {data_atual}. Por favor, anexe o arquivo localizado no caminho abaixo:\n\n" nome_pasta = f"{cc}_{data_atual}" destino_base = "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\Corpus" ficheiro1 = "TranscriptWithAER&FER.pdf" caminho_destino = os.path.join(destino_base, nome_pasta, ficheiro1) corpo += f"{caminho_destino}\n\nAtenciosamente," mailto_link = f"mailto:?subject={urllib.parse.quote(assunto)}&body={urllib.parse.quote(corpo)}" webbrowser.open(mailto_link) def abrir_site_PJM(): url = "https://www.defesa.gov.pt/pt/defesa/organizacao/sc/pjm" webbrowser.open(url) def abrir_pdf_final(): pdf_path = "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\TranscriptWithAER&FER.pdf" try: os.startfile(pdf_path) except Exception as e: print(f"Erro ao abrir o PDF: {e}") def abrir_CR(): word_path = "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\Dataset\\2_auto_de_denuncia_Final.docx" try: os.startfile(word_path) except Exception as e: print(f"Erro ao abrir o PDF: {e}") def abrir_WER(): word_path = "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\Dataset\\6_ainqtestemunha_Final.docx" try: os.startfile(word_path) except Exception as e: print(f"Erro ao abrir o PDF: {e}") def abrir_IRD(): word_path = "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\Dataset\\3_aintarg_Final.docx" try: os.startfile(word_path) except Exception as e: print(f"Erro ao abrir o PDF: {e}") def copiarficheiro(): global data_atual, cc ficheiros_origem = [ "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\VideoFINAL.mp4", "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\TranscriptWithAER&FER.pdf", "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\Dataset\\6_ainqtestemunha_Final.docx", "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\Dataset\\3_aintarg_Final.docx", "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\Dataset\\2_auto_de_denuncia_Final.docx" ] destino_base = "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\Corpus" data_atual = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") nome_pasta = f"{cc}_{data_atual}" caminho_destino = os.path.join(destino_base, nome_pasta) if not os.path.exists(caminho_destino): os.makedirs(caminho_destino) for ficheiro_origem in ficheiros_origem: try: nome_original = os.path.basename(ficheiro_origem) nome, extensao = os.path.splitext(nome_original) novo_nome = f"{nome}_{cc}{extensao}" caminho_novo = os.path.join(caminho_destino, novo_nome) shutil.copy(ficheiro_origem, caminho_novo) print(f"Arquivo {nome_original} copiado e renomeado para {novo_nome}.") except Exception as e: print(f"Erro ao copiar e renomear {ficheiro_origem}: {e}") print(f"Arquivos copiados com sucesso para {caminho_destino}") def excluir_arquivos(pasta): for nome_arquivo in os.listdir(pasta): caminho_arquivo = os.path.join(pasta, nome_arquivo) try: if os.path.isfile(caminho_arquivo): os.remove(caminho_arquivo) print(f"Arquivo {caminho_arquivo} apagado com sucesso.") except Exception as e: print(f"Erro ao tentar deletar {caminho_arquivo}: {e}") pastaclips = "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\clips" pastavideo = "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\video_clips" pastaImagens = "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\Imagens" excluir_arquivos(pastaclips) excluir_arquivos(pastavideo) excluir_arquivos(pastaImagens) arquivos_para_apagar = [ "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\audio.mp3", "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\ANEXO_B_C.pdf", "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\Anexo_A.pdf", "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\transcricao_audio.pdf", "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\VideoFINAL.mp4", "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\Video.avi", "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\imagem_extraida_0.jpeg", "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\imagem_extraida_1.jpeg", "C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\FERVideo.mp4" ] for arquivo in arquivos_para_apagar: try: if os.path.exists(arquivo): os.remove(arquivo) print(f"Arquivo {arquivo} apagado com sucesso.") else: print(f"Arquivo {arquivo} não encontrado.") except Exception as e: print(f"Erro ao tentar deletar o arquivo {arquivo}: {e}") return data_atual def janelaprincipal(): janela_principal = customtkinter.CTk() janela_principal.geometry("1200x800") janela_principal.title("PJM IA") janela_principal.resizable(False, False) janela_principal.grid_columnconfigure(0, weight=0) janela_principal.grid_columnconfigure(1, weight=0) janela_principal.grid_rowconfigure(0, weight=0) janela_principal.grid_rowconfigure(1, weight=0) customtkinter.set_appearance_mode("Dark") lado_esquerdo1 = customtkinter.CTkFrame(janela_principal, width=600, height=400) lado_esquerdo1.grid(row=0, column=0, padx=10, pady=10, sticky="nsew") lado_direito1 = customtkinter.CTkFrame(janela_principal, width=600, height=400) lado_direito1.grid(row=0, column=1, padx=10, pady=10, sticky="nsew") lado_esquerdo2 = customtkinter.CTkFrame(janela_principal, width=600, height=400) lado_esquerdo2.grid(row=1, column=1, padx=10, pady=10, sticky="nsew") lado_direito2 = customtkinter.CTkFrame(janela_principal, width=600, height=400) lado_direito2.grid(row=1, column=0, padx=10, pady=10, sticky="nsew") janela_principal.grid_columnconfigure((0,1), weight=1) janela_principal.grid_rowconfigure((0,1), weight=1) barradetarefas=tk.Menu(janela_principal) Carregar=tk.Menu(barradetarefas, tearoff=0) Carregar.add_command(label='Carregar Video', command=lambda:carregar_video(lado_direito2,lado_esquerdo2)) Carregar.add_command(label='Carregar gravação som',command=lambda:carregar_audio(lado_esquerdo2)) Carregar.add_command(label='Usar a Camera', command=lambda:modelemotionface(lado_direito2,lado_esquerdo2)) Carregar.add_separator() Carregar.add_command(label="Sair", command=janela_principal.destroy) barradetarefas.add_cascade(label="Ficheiros", menu=Carregar) janela_principal.config(menu=barradetarefas) pdfimage = Image.open("C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\Icons\\pdf.png").resize((50,50), Image.Resampling.LANCZOS) pdficon=ImageTk.PhotoImage(pdfimage) pdfspeachFER = tk.Button(lado_direito1, image=pdficon, borderwidth=0, highlightthickness=0, bg="#2B2B2B",command=abrir_pdf_final) pdfspeachFER.grid(row=0, column=3, padx=6) labelpdfspeachFER = tk.Label(lado_direito1, text="Emotions\n Analysis", fg="white", bg="#2B2B2B") labelpdfspeachFER.grid(row=1, column=3, pady=(0, 5)) wordimage = Image.open("C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\Icons\\word.png").resize((50,50), Image.Resampling.LANCZOS) wordicon=ImageTk.PhotoImage(wordimage) aintargaicon = tk.Button(lado_direito1, image=wordicon, borderwidth=0, highlightthickness=0, bg="#2B2B2B", command=abrir_CR) aintargaicon.grid(row=0, column=0, padx=10) aintarg = tk.Label(lado_direito1, text="Complaint\nReport", fg="white", bg="#2B2B2B") aintarg.grid(row=1, column=0, pady=(5, 10)) PJMimage = Image.open("C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\Icons\\PJM.png").resize((60,80), Image.Resampling.LANCZOS) PJMicon=ImageTk.PhotoImage(PJMimage) PJMiconb = tk.Button(lado_direito1, image=PJMicon, borderwidth=0, highlightthickness=0, bg="#2B2B2B",command=abrir_site_PJM) PJMiconb.grid(row=8, column=0, padx=10) mailimage = Image.open("C:\\Users\\garci\\OneDrive\\Área de Trabalho\\Programa PJM\\Programa final\\Icons\\mail.png").resize((50,50), Image.Resampling.LANCZOS) mailicon=ImageTk.PhotoImage(mailimage) mailiconb = tk.Button(lado_direito1, image=mailicon, borderwidth=0, highlightthickness=0, bg="#2B2B2B",command=abrir_email_com_anexos) mailiconb.grid(row=8, column=1, padx=10) ainttesticon = tk.Button(lado_direito1, image=wordicon, borderwidth=0, highlightthickness=0, bg="#2B2B2B", command=abrir_WER) ainttesticon.grid(row=0, column=1, padx=10) ainttest = tk.Label(lado_direito1, text="Witness examination\nreport", fg="white", bg="#2B2B2B") ainttest.grid(row=1, column=1, pady=(5, 10)) adenicon = tk.Button(lado_direito1, image=wordicon, borderwidth=0, highlightthickness=0, bg="#2B2B2B", command=abrir_IRD) adenicon.grid(row=0, column=2, padx=10) aden = tk.Label(lado_direito1, text="Interrogation report\nof defendant", fg="white", bg="#2B2B2B") aden.grid(row=1, column=2, pady=(5, 10)) user = customtkinter.CTkButton(lado_direito1,text="Carregar Ficheiro PDF",command=lambda:carregar_ficheiro(user,lado_esquerdo1),fg_color="gray") user.grid(row=4, column=0, padx=10) userlabel = tk.Label(lado_direito1, text="FM/CC", fg="white", bg="#2B2B2B") userlabel.grid(row=5, column=0, pady=(5, 10)) opcoes = ["OF3 12345678 Tomás", "OF2 17645234 Doe", "OF4 12827412 Smith", "OF3 13235467 Johnson", "OF2 12314558 Wilson"] user2 = customtkinter.CTkOptionMenu(lado_direito1, values=opcoes,fg_color="#2B2B2B") user2.grid(row=4, column=1, padx=10) userlabel2 = tk.Label(lado_direito1, text="NIM/NIF", fg="white", bg="#2B2B2B") userlabel2.grid(row=5, column=1, pady=(5, 10)) data_entry = DateEntry(lado_direito1, width=15, background="#2B2B2B", foreground="white", borderwidth=2, date_pattern='dd/mm/yyyy') data_entry.grid(row=4, column=2, padx=(0, 10), pady=(5, 10)) datalabel = tk.Label(lado_direito1, text="Date\n(dd/mm/yyyy)", fg="white", bg="#2B2B2B") datalabel.grid(row=5, column=2, pady=(5, 10)) horas= ttk.Combobox(lado_direito1, width=3, values=[f"{i:02d}" for i in range(24)]) horas.grid(row=4, column=3, sticky="w", padx=(10)) horas.set("HH") minutos = ttk.Combobox(lado_direito1, width=3, values=[f"{i:02d}" for i in range(60)]) minutos.grid(row=4, column=3, padx=(55)) minutos.set("MM") timelabel = tk.Label(lado_direito1, text="Hour", fg="white", bg="#2B2B2B") timelabel.grid(row=5, column=3, sticky="w", padx=35) local = customtkinter.CTkEntry(lado_direito1, placeholder_text="Local") local.grid(row=6, column=0, padx=10) locallabel = tk.Label(lado_direito1, text="Local", fg="white", bg="#2B2B2B") locallabel.grid(row=7, column=0, pady=(5, 10)) city = customtkinter.CTkEntry(lado_direito1, placeholder_text="City") city.grid(row=6, column=1, padx=10) citylabel = tk.Label(lado_direito1, text="City", fg="white", bg="#2B2B2B") citylabel.grid(row=7, column=1, pady=(5, 10)) validar = customtkinter.CTkButton(lado_direito1, text="Need Validation", fg_color="gray") validar.grid(row=6, column=2) def verificarcampospreenchidos(): fm_cc_valor = user2.get() local_valor = local.get() city_valor = city.get() data_valor = data_entry.get_date() if data_entry.get_date() else None hora_valor = horas.get() minuto_valor = minutos.get() if all([fm_cc_valor, local_valor, city_valor, data_valor, hora_valor, minuto_valor]): validar.configure(fg_color="green", text="Validated", command=lambda: atribuivalores(user2, local, city, data_entry, horas, minutos)) else: validar.configure(fg_color="gray", text="Need Validation") for campo in [user2,data_entry,horas,minutos,local,city]: campo.bind("", lambda event: verificarcampospreenchidos()) janela_principal.mainloop() Login()