尚未偵測到更新。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).