diff --git a/document_history.php b/document_history.php new file mode 100644 index 0000000..5681ca4 --- /dev/null +++ b/document_history.php @@ -0,0 +1,85 @@ +connect_error) { + die("Connection failed: " . $mysqli->connect_error); +} + +// Buscar histórico de documentos processados +$query = "SELECT pd.*, u.username FROM processed_documents pd + LEFT JOIN users u ON pd.user_id = u.id + ORDER BY pd.created_at DESC"; +$result = $mysqli->query($query); +?> + +
+

Histórico de Documentos Processados

+ + + + + + + + + + + + + fetch_assoc()): ?> + + + + + + + + + +
Data/HoraUsuárioDocumento OriginalDocumento ProcessadoAções
+ + Ver Original + + + + Ver Processado + + + +
+
+ + diff --git a/document_processor.php b/document_processor.php new file mode 100644 index 0000000..ecc4ada --- /dev/null +++ b/document_processor.php @@ -0,0 +1,153 @@ +outputPath = $outputPath; + + // Carrega a imagem + $this->srcImage = cv\imread($imagePath); + if ($this->srcImage === null) { + throw new Exception('Failed to load image'); + } + + // Pipeline de processamento + $this->detectDocument() + ->correctPerspective() + ->enhanceImage() + ->saveResult(); + + return $this->outputPath; + } + + private function detectDocument() { + // Converte para escala de cinza + $gray = cv\cvtColor($this->srcImage, cv\COLOR_BGR2GRAY); + + // Obter dimensões da imagem + $size = $gray->size(); + $rows = $size[0]; + $cols = $size[1]; + + // Cria uma matriz vazia para o resultado do blur + $blur = cv\Mat::zeros($rows, $cols, $gray->type()); + + // Aplica blur para reduzir ruído + cv\GaussianBlur($gray, $blur, [5, 5], 0); + + // Cria uma matriz vazia para as bordas + $edges = cv\Mat::zeros($rows, $cols, $gray->type()); + + // Detecta bordas + cv\Canny($blur, $edges, 75, 200); + + // Encontra contornos + $contours = []; + cv\findContours($edges, $contours, cv\RETR_LIST, cv\CHAIN_APPROX_SIMPLE); + + // Ordena contornos por área + usort($contours, function($a, $b) { + return cv\contourArea($b) - cv\contourArea($a); + }); + + // Procura o contorno mais próximo de um documento + foreach ($contours as $contour) { + $peri = cv\arcLength($contour, true); + $approx = cv\approxPolyDP($contour, 0.02 * $peri, true); + + if (count($approx) == 4) { + $this->documentContour = $approx; + break; + } + } + + return $this; + } + + private function correctPerspective() { + if (!isset($this->documentContour)) { + return $this; + } + + // Ordena os pontos para perspectiva + $points = $this->orderPoints($this->documentContour); + + // Calcula dimensões do documento + $width = max( + sqrt(pow($points[1][0] - $points[0][0], 2) + pow($points[1][1] - $points[0][1], 2)), + sqrt(pow($points[3][0] - $points[2][0], 2) + pow($points[3][1] - $points[2][1], 2)) + ); + + $height = max( + sqrt(pow($points[2][0] - $points[1][0], 2) + pow($points[2][1] - $points[1][1], 2)), + sqrt(pow($points[3][0] - $points[0][0], 2) + pow($points[3][1] - $points[0][1], 2)) + ); + + // Define pontos de destino + $dst = cv\Mat::zeros([4, 2], CV_32F); + $dst[0] = [0, 0]; + $dst[1] = [$width - 1, 0]; + $dst[2] = [$width - 1, $height - 1]; + $dst[3] = [0, $height - 1]; + + // Aplica transformação de perspectiva + $matrix = cv\getPerspectiveTransform($points, $dst); + $this->processedImage = cv\warpPerspective($this->srcImage, $matrix, [$width, $height]); + + return $this; + } + + private function enhanceImage() { + if (!isset($this->processedImage)) { + $this->processedImage = $this->srcImage; + } + + // Converte para LAB para melhor processamento + $lab = cv\cvtColor($this->processedImage, cv\COLOR_BGR2LAB); + $l_channel = cv\split($lab)[0]; + + // Aplica CLAHE para melhorar contraste + $clahe = cv\createCLAHE(3.0, [8, 8]); + $cl = $clahe->apply($l_channel); + + // Reconstrói imagem + $limg = cv\merge([$cl, cv\split($lab)[1], cv\split($lab)[2]]); + $this->processedImage = cv\cvtColor($limg, cv\COLOR_LAB2BGR); + + return $this; + } + + private function saveResult() { + if (!isset($this->processedImage)) { + throw new Exception('No processed image to save'); + } + + cv\imwrite($this->outputPath, $this->processedImage); + return $this; + } + + private function orderPoints($pts) { + // Ordena pontos para transformação de perspectiva + $rect = array_fill(0, 4, [0, 0]); + $s = array_map(function($p) { return $p[0] + $p[1]; }, $pts); + $d = array_map(function($p) { return $p[0] - $p[1]; }, $pts); + + $rect[0] = $pts[array_search(min($s), $s)]; // top-left + $rect[2] = $pts[array_search(max($s), $s)]; // bottom-right + $rect[1] = $pts[array_search(min($d), $d)]; // top-right + $rect[3] = $pts[array_search(max($d), $d)]; // bottom-left + + return $rect; + } +} diff --git a/index.php b/index.php index 442e759..c089384 100644 --- a/index.php +++ b/index.php @@ -52,6 +52,10 @@ include 'top_menu.php'; include 'clientes/edit_note.php'; } elseif ($page == 'delete_note' && isset($_POST['id'])) { include 'clientes/delete_note.php'; + } elseif ($page == 'process_document') { + include 'process_document.php'; + } elseif ($page == 'document_history') { + include 'document_history.php'; } else { echo "

Bem-vindo ao Sistema de Ferramentas

"; } diff --git a/menu.php b/menu.php index afd199e..4cd19d0 100644 --- a/menu.php +++ b/menu.php @@ -12,7 +12,7 @@ if (!isset($_SESSION['user_id'])) {
  • Autenticador de Provas Digitais @@ -24,6 +24,13 @@ if (!isset($_SESSION['user_id'])) {
  • Listagem de Clientes
  • +
  • + Processamento de Documentos + +
  • diff --git a/process_document.php b/process_document.php new file mode 100644 index 0000000..0e93852 --- /dev/null +++ b/process_document.php @@ -0,0 +1,85 @@ +processDocument($uploadFile, $processedFile); + + // Salva o registro no banco de dados + $mysqli = new mysqli("10.15.0.42", "root", "34641747", "valida"); + $stmt = $mysqli->prepare("INSERT INTO processed_documents (user_id, original_path, processed_path, created_at) VALUES (?, ?, ?, NOW())"); + $stmt->bind_param("iss", $_SESSION['user_id'], $uploadFile, $processedFile); + $stmt->execute(); + + $message = "Documento processado com sucesso!"; + $success = true; + } else { + throw new Exception("Falha ao fazer upload do arquivo."); + } + } catch (Exception $e) { + $message = "Erro: " . $e->getMessage(); + $success = false; + } +} +?> + +
    +

    Processamento de Documentos

    + + +
    + +
    + + +
    +
    + + +
    + + +
    + + +
    +

    Resultado:

    +
    +
    +

    Original:

    + Original +
    +
    +

    Processado:

    + Processado +
    +
    +
    + +
    diff --git a/style.css b/style.css index 4eb5acf..2723ee2 100644 --- a/style.css +++ b/style.css @@ -209,3 +209,50 @@ textarea { #search-button:hover { background-color: #0056b3; } + +/* Estilos para processamento de documentos */ +.upload-form { + max-width: 600px; + margin: 20px auto; + padding: 20px; + background: #f5f5f5; + border-radius: 5px; +} + +.result-preview { + margin-top: 30px; +} + +.image-comparison { + display: flex; + justify-content: space-around; + margin-top: 20px; + flex-wrap: wrap; +} + +.image-comparison img { + max-width: 45%; + height: auto; + margin: 10px; + border: 1px solid #ddd; + box-shadow: 0 0 5px rgba(0,0,0,0.2); +} + +.alert { + padding: 15px; + margin-bottom: 20px; + border: 1px solid transparent; + border-radius: 4px; +} + +.alert-success { + color: #155724; + background-color: #d4edda; + border-color: #c3e6cb; +} + +.alert-error { + color: #721c24; + background-color: #f8d7da; + border-color: #f5c6cb; +}