尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Escáner de documentos en el navegador: detección automática con OpenCV.js, ajuste manual de esquinas y corrección de perspectiva. Vanilla JS, sin backend.
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
Escáner de documentos que corre entero en el navegador: detecta el documento con la cámara, corrige la perspectiva y exporta un PNG limpio en blanco y negro, escala de grises o color — o un PDF con varias páginas de una tacada — sin subir nada a ningún servidor. Toda la visión por computador (detección de bordes, contornos y warpPerspective) la hace OpenCV.js cargado por CDN. Uno más de una serie de proyectos pequeños para portfolio, junto a BusYa (tiempos de paso EMT/CRTM) y Disaster Watch (alertas globales GDACS).查看完整 README ↗
Escáner de documentos que corre entero en el navegador: detecta el documento con la
cámara, corrige la perspectiva y exporta un PNG limpio en blanco y negro, escala de
grises o color — o un PDF con varias páginas de una tacada — sin subir nada a ningún
servidor. Toda la visión por computador (detección de bordes, contornos y
warpPerspective) la hace OpenCV.js cargado
por CDN.
Uno más de una serie de proyectos pequeños para portfolio, junto a BusYa (tiempos de paso EMT/CRTM) y Disaster Watch (alertas globales GDACS).
Demo en vivo: https://zscanner.vercel.app/
getUserMedia y, en cada frame, un bucle de detección
corre el documento a través de OpenCV.js: gris → GaussianBlur → Canny →
findContours → approxPolyDP, buscando el cuadrilátero convexo más grande. El
contorno detectado se dibuja en tiempo real sobre el preview.Canny se recalculan en cada frame a partir de la mediana de brillo de
la imagen (heurística estándar, sigma=0.33), en vez de usar un par de valores fijos —
así la detección se adapta sola a luz mala o poco contraste en vez de depender de un
ajuste manual único que solo funciona bien en una escena. Si ese cálculo no encuentra
ningún cuadrilátero, se reintenta una vez con umbrales más permisivos antes de rendirse
en ese frame.getPerspectiveTransform + warpPerspective usando las 4 esquinas encontradas.<input type="file">). Al no depender de getUserMedia ni del bucle de detección,
es una vía de escaneo completamente independiente de la cámara en vivo: sigue
funcionando igual aunque haya algún problema puntual con esta última. La imagen
elegida siempre pasa por el ajuste manual de esquinas (no hay detección automática
posible sobre una foto ya tomada).adaptiveThreshold, con el tamaño de bloque
escalado a la resolución real del recorte para no verse ruidoso a resoluciones de
captura más altas) — blanco y negro puro, máximo contraste, archivo más pequeño.sw.js) cachea el shell estático de la app
(HTML/CSS/JS/iconos) con estrategia stale-while-revalidate, para que cargue al instante
y la interfaz funcione sin conexión en visitas repetidas; si detecta una versión nueva
mientras la app está abierta, muestra un aviso con un botón para recargar en vez de
hacerlo solo (podría cortar una captura o un arrastre de esquinas en curso).El área mínima del contorno, el tamaño del blur, el epsilon de approxPolyDP, y los
frames requeridos para bloquear/soltar la detección, son overridables por query string,
para probar valores distintos sin tocar código. Pasar cannyLow/cannyHigh explícitos
desactiva el cálculo automático por mediana y fuerza esos valores fijos (o desactívalo a
mano con autoCanny=0):
index.html?minArea=0.1&cannyLow=40&cannyHigh=120&blur=7&epsilon=0.015&stableFrames=3&missGrace=8
Añadiendo ?debug=1 aparece además un panel con sliders para los mismos parámetros,
con el valor aplicándose en vivo al siguiente frame.
<canvas> en memoria (nunca en
disco ni en el servidor) — funciona bien para el uso típico de escanear un puñado de
hojas, pero muchas páginas de alta resolución seguidas pueden notarse en RAM en un
móvil modesto. No hay un límite explícito de páginas ni una barra de progreso durante
la generación del PDF.onnxruntime-web. No es un simple añadido:
sería un modelo extra que descargar (además de OpenCV.js, no en su lugar), y las
implementaciones que existen usan un bundler porque el backend WASM rápido de
onnxruntime-web necesita cabeceras Cross-Origin-Opener-Policy/
Cross-Origin-Embedder-Policy para SharedArrayBuffer (configurables en Vercel sin
build step, pero no es un CDN-y-listo como OpenCV.js). Si se aborda, mejor como
modo opt-in (p. ej. ?ml=1) que conviva con el pipeline clásico, no como reemplazo.js/*.js con import/export) que el navegador resuelve directamente, sin
bundler.manifest.webmanifest + sw.js.WhitePaperTransform de
OSS-DocumentScanner
— reimplementada aquí directamente contra OpenCV.js, no copiada de su código C++.zscanner/
├── css/
│ └── styles.css
├── js/
│ ├── dom.js # referencias a elementos del DOM
│ ├── state.js # estado mutable compartido entre módulos
│ ├── ui.js # transiciones entre las 3 pantallas (cámara/ajuste/resultado)
│ ├── camera.js # getUserMedia y mapeo de coordenadas vídeo → stage
│ ├── detection.js # pipeline de OpenCV.js + parámetros ajustables
│ ├── adjust.js # esquinas arrastrables sobre el frame congelado
│ ├── perspective.js # warpPerspective + modos de salida + descarga
│ ├── pages.js # sesión multipágina: miniaturas + exportar PDF (jsPDF)
│ ├── share.js # guardar/compartir un archivo (Web Share API o descarga clásica)
│ └── main.js # orquestación: carga de OpenCV.js, SW y listeners de botones
├── icons/ # iconos de la PWA (192/512/512-maskable/apple-touch-icon)
├── index.html
├── favicon.svg
├── manifest.webmanifest
├── sw.js # service worker: cachea el shell estático, nunca OpenCV.js
├── LICENSE
├── CHANGELOG.md
└── README.md
No requiere instalación de dependencias ni build step. Basta con servir los archivos estáticos, por ejemplo:
python3 -m http.server 8000
# o: npx serve .
Y abrir http://localhost:8000 en el navegador. La cámara requiere HTTPS o localhost
(la excepción que los navegadores hacen para getUserMedia en desarrollo).
Sin configuración de build: Vercel sirve index.html, css/ y js/ tal cual como
sitio estático.
Ver CHANGELOG.md.
Código bajo licencia MIT (ver LICENSE). OpenCV.js se carga desde su propio CDN oficial y se rige por su propia licencia (Apache 2.0).