npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@teral-americas/react-native-face-detector

v0.2.1

Published

Deteccion de caras y tatuajes on-device para React Native: devuelve coordenadas normalizadas y no toca la imagen.

Readme

@teral-americas/react-native-face-detector

Detección on-device de caras y tatuajes para React Native / Expo. Devuelve coordenadas y no toca la imagen: el censurado lo dibuja tu app, con lo que el usuario puede mover, borrar o añadir zonas antes de exportar.

Nada de la imagen sale del dispositivo: sin red, sin Google Play Services.

| | iOS | Android | | --- | --- | --- | | Caras | Vision | android.media.FaceDetector | | Tatuajes | Core ML | LiteRT (TFLite) |

Instalación

npm install @teral-americas/react-native-face-detector
npx pod-install

Es código nativo: hay que recompilar (npx expo run:ios / npx expo run:android). No funciona en Expo Go.

API

detectFaces(uri, options?): Promise<FaceDetectionResult>

import { detectFaces, isFaceDetectionAvailable } from '@teral-americas/react-native-face-detector';

const { imageWidth, imageHeight, faces } = await detectFaces(uri, {
  region: 'face',        // o 'eyes'
  maxDetectionSize: 1000,
  minConfidence: 0.4,
});
// faces: [{ x, y, width, height, confidence, region, angle }] — normalizado 0..1

region: 'eyes'

Devuelve solo la banda de los ojos: la convención de las publicaciones médicas, útil cuando la lesión está en la cara. No anonimiza — mandíbula, nariz, boca y orejas siguen identificando a la persona, y el reconocimiento facial funciona con los ojos tapados. Es una decisión clínica, no una medida de privacidad.

En iOS la banda sale de los landmarks de Vision, así que se inclina con la cara; angle trae esa inclinación en radianes. En Android va siempre horizontal porque su API no reporta la pose. El rectángulo devuelto está alineado a los ejes y envuelve la banda inclinada, de modo que ignorar angle no destapa nada. Ajusta su tamaño con eyeBandScale.

detectTattoos(uri, options?): Promise<TattooDetectionResult>

import { detectTattoos, isTattooDetectionAvailable } from '@teral-americas/react-native-face-detector';

const { tattoos } = await detectTattoos(uri, {
  minConfidence: 0.05,   // umbral de confianza
  iouThreshold: 0.45,    // solape a partir del cual dos cajas son la misma
});
// tattoos: [{ x, y, width, height, confidence }] — normalizado 0..1

A diferencia de las caras, esto no lo resuelve ninguna API del sistema: es un YOLOX-Nano (Apache 2.0) entrenado con cajas generadas por AWS Rekognition, así que hereda su criterio y también sus fallos.

  • Encuentra el 84% de las cajas al umbral por defecto (0.05).
  • Rekognition solo localiza el tatuaje en algo más de la mitad de las fotos donde lo reconoce, así que sobre tatuajes reales el techo queda bastante por debajo.
  • Va peor con tatuajes pequeños (recall 0.34) que con grandes (0.67).

La censura automática de tatuajes es una ayuda, no una garantía. La interfaz no debería prometer que los ha tapado todos.

El umbral por defecto es bajo a propósito: difuminar de más cuesta píxeles, dejarse un tatuaje cuesta la privacidad de un paciente.

isFaceDetectionAvailable · isTattooDetectionAvailable

false cuando el build no trae lo necesario — por ejemplo en Expo Go, o en un binario anterior a instalar la librería. Úsalos para esconder la opción de censurado automático en vez de dejar que falle al pulsarla.

Detalles que importan

  • Las coordenadas son normalizadas sobre la imagen ya orientada por su EXIF. Multiplicas por el tamaño al que la pintas y ya está, sin lógica de rotación.
  • Detectar en pequeño es igual de preciso y mucho más rápido: de ahí el maxDetectionSize de 1000 por defecto en caras.
  • Las confianzas no son comparables entre plataformas. Vision devuelve valores altos y homogéneos; android.media.FaceDetector reparte confianzas bajas incluso en caras claras. Calibra el umbral por plataforma.
  • El rectángulo va justo al objeto. Si vas a censurar, agrándalo un 10-15%: sin margen quedan a la vista el contorno del tatuaje o la frente y el mentón, que bastan para identificar.
  • Android detecta caras frontales y poco más. Perfiles y caras mal iluminadas se le escapan. El punto donde se sustituye por ML Kit es el cuerpo de detectFaces en el Kotlin; la API no cambia.

Tamaño del build

  • iOS: +3,6 MB (el modelo; Vision y Core ML son del sistema).
  • Android: +3,7 MB de modelo y 2-4 MB del runtime de LiteRT.

Modelo de tatuajes

El decodificador vive fuera del modelo: dentro generaba una operación que TFLite no sabe convertir, y con la rejilla cruda iOS y Android aplican la misma aritmética en vez de tener dos implementaciones que puedan divergir.

El .mlmodelc de iOS va compilado en el repo porque CocoaPods copia los recursos tal cual, sin pasarlos por el compilador de Core ML. Se regenera con:

xcrun coremlcompiler compile TattooDetector.mlpackage .

Licencia

MIT. El modelo de tatuajes se entrenó con YOLOX (Apache 2.0) sobre imágenes de Wikimedia Commons con licencia libre.