From 6b47959a45de1502e3fa480ffa9a285e17993e60 Mon Sep 17 00:00:00 2001 From: Thiago Sposito Date: Wed, 4 Feb 2026 22:23:21 -0300 Subject: [PATCH] feat: add proper README --- README.md | 137 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 96 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index 3d772d1..9f2c04b 100644 --- a/README.md +++ b/README.md @@ -1,66 +1,121 @@ -# Table extraction from scrolling video +# Extração de Tabelas de Vídeo com Scroll -Extract a table from a screen-recorded video: sample frames, OCR (Portuguese), align to column/row bounds from an SVG template, then merge and deduplicate into one CSV. +Sistema automatizado para extrair tabelas de vídeos de gravação de tela que contêm tabelas com scroll vertical. Utiliza OCR em português, alinhamento baseado em template SVG e mesclagem inteligente para gerar um CSV final deduplicado. -## Inputs +## Visão Geral -| File | Role | -|------|------| -| `video-data.webm` | Source video (scroll-down table). | -| `template.svg` | Annotation: rectangles under the image = column bounds; 28 rows. | +Este projeto processa vídeos de gravação de tela que contêm tabelas com scroll, extraindo os dados através de: -## Outputs +1. **Amostragem de frames**: Extrai frames do vídeo em intervalos regulares +2. **OCR**: Reconhece texto em português em cada frame +3. **Alinhamento**: Usa um template SVG para identificar colunas e linhas +4. **Correção heurística**: Aplica correções automáticas nos dados extraídos +5. **Mesclagem e deduplicação**: Combina todos os frames e remove duplicatas -| File / dir | Role | -|------------|------| -| `result.csv` | Final table: 6 columns (Concessionária, Código, Rodovia/UF, km inicial, km final, Extensão), one row per segment, deduplicated. | -| `frames/` | Working: one PNG and one CSV per sampled frame (e.g. 0, 10, 20, …). | -| `llm-fixed-frames/` | Optional: copy of frame CSVs after manual/LLM fixes; sew from here instead of `frames/` if used. | +## Requisitos -## Run (same chore again) +- Python 3 +- OpenCV (opencv4) +- NumPy +- Tesseract OCR (com suporte a português) +- FFmpeg +- Nix (para ambiente isolado, opcional) -**Fully automated (extract → fix → sew → result):** +## Estrutura do Projeto + +### Arquivos de Entrada + +| Arquivo | Descrição | +|---------|-----------| +| `video-data.webm` | Vídeo fonte contendo a tabela com scroll vertical | +| `template.svg` | Template de anotação: retângulos vermelhos definem as colunas (6 colunas), retângulos azuis definem as linhas (28 linhas) | + +### Arquivos de Saída + +| Arquivo/Diretório | Descrição | +|-------------------|-----------| +| `result.csv` | Tabela final com 6 colunas: Concessionária, Código, Rodovia/UF, km inicial, km final, Extensão. Uma linha por segmento, deduplicada. | +| `frames/` | Diretório de trabalho: contém um PNG e um CSV por frame amostrado (ex: 0, 10, 20, 30, ...) | +| `llm-fixed-frames/` | Diretório opcional: cópias dos CSVs dos frames após correções manuais ou via LLM. Use este diretório como entrada para `sew_csvs.py` se fizer correções manuais | + +## Uso Rápido + +### Execução Automatizada Completa + +Para executar todo o pipeline (extração → correção → mesclagem → resultado): ```bash nix-shell -p python3 python3Packages.opencv4 python3Packages.numpy python3Packages.pytesseract tesseract ffmpeg --run "./run.sh" ``` -Or with custom video / output dir: +Ou com vídeo e diretório de saída customizados: ```bash -./run.sh path/to/video.webm my_frames -# result.csv is still written at project root +./run.sh caminho/para/video.webm meu_diretorio_frames +# result.csv será escrito na raiz do projeto ``` -**If you do manual fixes:** copy `frames/*.csv` into `llm-fixed-frames/`, edit CSVs, then: +### Fluxo com Correções Manuais -```bash -python3 sew_csvs.py llm-fixed-frames result.csv -``` +Se você precisar corrigir manualmente os CSVs extraídos: -## Scripts (keep) +1. Copie os CSVs do diretório `frames/` para `llm-fixed-frames/`: + ```bash + cp frames/*.csv llm-fixed-frames/ + ``` -| Script | Role | -|--------|------| -| `extract_frames_and_tables.py` | Sample video every N frames → PNGs; OCR (por) + SVG column/row bounds → one CSV per frame. | -| `fix_all_csvs.py` | Heuristic fixes on frame CSVs (strip, E→-, pipe→space, extensão from km). | -| `sew_csvs.py` | Merge frame CSVs in order, remove boundary overlap, deduplicate full rows, write result. | -| `svg_columns.py` | Parse column/row rectangles from template.svg. | -| `assign_cells.py` | Map word boxes to (col, row); merge cell text (col1 no space, others space). | -| `clean_csv_heuristics.py` | Per-row cleanup and extensão correction (used by fix_all_csvs). | -| `row_eq.py` | Row equality for sewing. | +2. Edite os arquivos CSV em `llm-fixed-frames/` conforme necessário -## Not kept (removed) +3. Execute apenas a mesclagem usando o diretório corrigido: + ```bash + python3 sew_csvs.py llm-fixed-frames result.csv + ``` -- `extract_table_frames.py` – superseded by `extract_frames_and_tables.py`. -- `extract_every_n_frames.py` – logic folded into `extract_frames_and_tables.py`. -- `sewn.csv` – superseded by `result.csv` (sew now writes result.csv and dedupes). +## Scripts do Projeto -## Clean re-run +### Scripts Principais -To start from scratch: +| Script | Função | +|--------|--------| +| `extract_frames_and_tables.py` | Extrai frames do vídeo a cada N frames, salva como PNG, executa OCR em português, alinha texto às colunas/linhas do template SVG e gera um CSV por frame | +| `fix_all_csvs.py` | Aplica correções heurísticas nos CSVs dos frames: remove espaços, converte "E" em "-", substitui pipes por espaços, calcula extensão a partir dos km | +| `sew_csvs.py` | Mescla os CSVs dos frames em ordem, remove sobreposição nas bordas, deduplica linhas completas e escreve o resultado final | -- Delete or clear `frames/` and optionally `llm-fixed-frames/`. -- Run `./run.sh` (or the manual-fix flow above). +### Scripts Auxiliares -`result.csv` is overwritten each run. +| Script | Função | +|--------|--------| +| `svg_columns.py` | Parse dos retângulos de colunas e linhas do `template.svg` | +| `assign_cells.py` | Mapeia caixas de palavras para células (col, row); mescla texto das células (col1 sem espaço, outras com espaço) | +| `clean_csv_heuristics.py` | Limpeza por linha e correção de extensão (usado por `fix_all_csvs.py`) | +| `row_eq.py` | Função de igualdade de linhas para a mesclagem | + +## Fluxo de Processamento + +O pipeline completo segue estas etapas: + +1. **Extração de Frames**: `extract_frames_and_tables.py` amostra o vídeo a cada 10 frames (padrão) e salva como PNG +2. **OCR e Alinhamento**: Para cada frame, executa OCR em português e alinha o texto às colunas/linhas definidas no `template.svg` +3. **Correção Heurística**: `fix_all_csvs.py` aplica correções automáticas nos dados extraídos +4. **Mesclagem**: `sew_csvs.py` combina todos os CSVs, remove sobreposições e deduplica linhas completas +5. **Resultado Final**: Gera `result.csv` com todos os dados consolidados + +## Reiniciar do Zero + +Para executar uma nova extração do zero: + +1. Delete ou limpe os diretórios `frames/` e `llm-fixed-frames/` (se existirem) +2. Execute `./run.sh` (ou o fluxo de correção manual descrito acima) + +**Nota**: `result.csv` é sobrescrito a cada execução. + +## Estrutura das Colunas + +O CSV final contém 6 colunas: + +- **Concessionária**: Nome da concessionária +- **Código**: Código identificador +- **Rodovia/UF**: Rodovia e estado +- **km inicial**: Quilômetro inicial do segmento +- **km final**: Quilômetro final do segmento +- **Extensão**: Extensão calculada (km final - km inicial)